Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ sidebar_position: 1
* [release v1.0.1](v1.0.1.md)
* [release v1.0.2](v1.0.2.md)
* [release v1.0.3](v1.0.3.md)
* [release v1.0.4](v1.0.4.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# v1.0.4

## 发布日期
2026 年 2 月 4 日

## 概览
本次发布主要涉及Admin的bug修复。

---

## Admin

### Bug 修复

修复SandboxActor未汇报namespace指标的问题

---

## 已知问题

* 目前暂无


## 贡献者

感谢所有为本次发布做出贡献的贡献者!

## 下一步计划

* 增强文档与教程

* 进一步的性能优化与 Bug 修复
1 change: 1 addition & 0 deletions docs/versioned_docs/version-1.0.x/Release Notes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ sidebar_position: 1
* [release v1.0.1](v1.0.1.md)
* [release v1.0.2](v1.0.2.md)
* [release v1.0.3](v1.0.3.md)
* [release v1.0.4](v1.0.4.md)
27 changes: 27 additions & 0 deletions docs/versioned_docs/version-1.0.x/Release Notes/v1.0.4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# v1.0.2

## Release Date
February 4, 2026

## Overview
This release primarily focuses on Admin bug fix.

---

## Admin

### Bug Fixes

Fix the issue that the namespace metric is not reported by SandboxActor.

---

## Known Issues
- None at this time

## Contributors
Thanks to all the contributors who made this release possible!

## Next Steps
- Enhance documentation and tutorials
- Further performance optimizations and bug fixes
1 change: 1 addition & 0 deletions rock/actions/sandbox/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class SandboxStatusResponse(BaseModel):
swe_rex_version: str | None = None
user_id: str | None = None
experiment_id: str | None = None
namespace: str | None = None
cpus: float | None = None
memory: str | None = None

Expand Down
21 changes: 12 additions & 9 deletions rock/admin/metrics/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,24 @@ async def _get_user_info(redis_provider: RedisProvider, sandbox_id: str):
if user_info is not None and len(user_info) > 0:
user_id = user_info[0].get("user_id")
experiment_id = user_info[0].get("experiment_id")
namespace = user_info[0].get("namespace")
return (
user_id if user_id is not None else "default",
experiment_id if experiment_id is not None else "default",
namespace if namespace is not None else "default",
)
return "default", "default"
return "default", "default", "default"


def _build_attributes(op_name: str, sandbox_id: str, f, user_id: str, experiment_id: str):
def _build_attributes(op_name: str, sandbox_id: str, f, user_id: str, experiment_id: str, namespace: str):
"""Build attributes for metrics"""
return {
"operation": op_name,
"sandbox_id": sandbox_id,
"method": f.__name__,
"user_id": user_id,
"experiment_id": experiment_id,
"namespace": namespace,
}


Expand All @@ -77,20 +80,20 @@ def _record_metrics(metrics_monitor: MetricsMonitor, result, attributes: dict, s
"""Record metrics after function execution"""
# Update sandbox_id from result if available
attributes = _update_sandbox_id_from_result(result, attributes)

# Record success or failure
if isinstance(result, Exception):
error_attrs = {**attributes, "error_type": type(result).__name__}
metrics_monitor.record_counter_by_name(f"{metric_prefix}.failure", 1, error_attrs)
raise result
else:
metrics_monitor.record_counter_by_name(f"{metric_prefix}.success", 1, attributes)

# Record response time and total requests
rt_ms = (time.perf_counter() - start_time) * 1000
metrics_monitor.record_gauge_by_name(f"{metric_prefix}.rt", rt_ms, attributes)
metrics_monitor.record_counter_by_name(f"{metric_prefix}.total", 1, attributes)

return result


Expand Down Expand Up @@ -125,10 +128,10 @@ async def wrapper(self, *args, **kwargs):
)

redis_provider: RedisProvider = getattr(self, "_redis_provider", None)
user_id, experiment_id = await _get_user_info(redis_provider, sandbox_id)
user_id, experiment_id, namespace = await _get_user_info(redis_provider, sandbox_id)

# Build attributes
attributes = _build_attributes(op_name, sandbox_id, f, user_id, experiment_id)
attributes = _build_attributes(op_name, sandbox_id, f, user_id, experiment_id, namespace)

start_time = time.perf_counter()

Expand Down Expand Up @@ -159,10 +162,10 @@ def wrapper(self, *args, **kwargs):

redis_provider: RedisProvider = getattr(self, "_redis_provider", None)
# For sync functions, we need to run the async function in a blocking way
user_id, experiment_id = asyncio.run(_get_user_info(redis_provider, sandbox_id))
user_id, experiment_id, namespace = asyncio.run(_get_user_info(redis_provider, sandbox_id))

# Build attributes
attributes = _build_attributes(op_name, sandbox_id, f, user_id, experiment_id)
attributes = _build_attributes(op_name, sandbox_id, f, user_id, experiment_id, namespace)

start_time = time.perf_counter()

Expand Down
2 changes: 2 additions & 0 deletions rock/sandbox/base_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class BaseActor:
_env: str = "dev"
_user_id: str = "default"
_experiment_id: str = "default"
_namespace = "default"

def __init__(
self,
Expand Down Expand Up @@ -150,6 +151,7 @@ async def _collect_sandbox_metrics(self, sandbox_id: str):
attributes = {"sandbox_id": sandbox_id, "env": self._env, "role": self._role, "host": self.host}
attributes["user_id"] = self._user_id
attributes["experiment_id"] = self._experiment_id
attributes["namespace"] = self._namespace
self._gauges["cpu"].set(metrics["cpu"], attributes=attributes)
self._gauges["mem"].set(metrics["mem"], attributes=attributes)
self._gauges["disk"].set(metrics["disk"], attributes=attributes)
Expand Down
2 changes: 2 additions & 0 deletions rock/sdk/sandbox/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,8 @@ def _add_user_defined_tag_into_headers(self, headers: dict):
headers["X-User-Id"] = self.config.user_id
if self.config.experiment_id:
headers["X-Experiment-Id"] = self.config.experiment_id
if self.config.namespace:
headers["X-Namespace"] = self.config.namespace

def _is_token_expired(self) -> bool:
try:
Expand Down
1 change: 1 addition & 0 deletions rock/sdk/sandbox/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SandboxConfig(BaseConfig):
user_id: str | None = None
experiment_id: str | None = None
cluster: str = "zb"
namespace: str | None = None


class SandboxGroupConfig(SandboxConfig):
Expand Down
Loading
Loading