Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions agentrun/integration/utils/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -1562,8 +1562,8 @@ def _build_openapi_schema(
if isinstance(schema, dict):
properties[name] = {
**schema,
"description": (
param.get("description") or schema.get("description", "")
"description": param.get("description") or schema.get(
"description", ""
),
}
if param.get("required"):
Expand Down
6 changes: 5 additions & 1 deletion agentrun/sandbox/__sandbox_async_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
Union,
)

from pydantic import Field

from agentrun.sandbox.model import TemplateType
from agentrun.utils.config import Config
from agentrun.utils.model import BaseModel
Expand Down Expand Up @@ -56,7 +58,9 @@ class Sandbox(BaseModel):
"""沙箱全局唯一资源名称 / Sandbox ARN"""
sandbox_id: Optional[str] = None
"""沙箱 ID / Sandbox ID"""
sandbox_idle_ttlin_seconds: Optional[int] = None
sandbox_idle_ttlin_seconds: Optional[int] = Field(
None, alias="sandboxIdleTTLInSeconds"
)
"""沙箱空闲 TTL(秒) / Sandbox Idle TTL (seconds)"""
sandbox_idle_timeout_seconds: Optional[int] = None
"""沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)"""
Expand Down
6 changes: 5 additions & 1 deletion agentrun/sandbox/__template_async_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from typing import Dict, List, Optional

from pydantic import Field

from agentrun.sandbox.model import (
PageableInput,
TemplateContainerConfiguration,
Expand Down Expand Up @@ -52,7 +54,9 @@ class Template(BaseModel):
"""执行角色 ARN / Execution Role ARN"""
sandbox_idle_timeout_in_seconds: Optional[int] = None
"""沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)"""
sandbox_ttlin_seconds: Optional[int] = None
sandbox_ttlin_seconds: Optional[int] = Field(
None, alias="sandboxTTLInSeconds"
)
"""沙箱存活时间(秒) / Sandbox TTL (seconds)"""
share_concurrency_limit_per_sandbox: Optional[int] = None
"""每个沙箱的最大并发会话数 / Max Concurrency Limit Per Sandbox"""
Expand Down
6 changes: 4 additions & 2 deletions agentrun/sandbox/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import Any, Dict, List, Optional, TYPE_CHECKING
import uuid

from pydantic import model_validator
from pydantic import Field, model_validator

from agentrun.utils.model import BaseModel

Expand Down Expand Up @@ -264,7 +264,9 @@ class TemplateInput(BaseModel):
"""执行角色 ARN / Execution Role ARN"""
sandbox_idle_timeout_in_seconds: Optional[int] = 1800
"""沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)"""
sandbox_ttlin_seconds: Optional[int] = 21600
sandbox_ttlin_seconds: Optional[int] = Field(
21600, alias="sandboxTTLInSeconds"
)
"""沙箱存活时间(秒) / Sandbox TTL (seconds)"""
share_concurrency_limit_per_sandbox: Optional[int] = 200
"""每个沙箱的最大并发会话数 / Max Concurrency Limit Per Sandbox"""
Expand Down
6 changes: 5 additions & 1 deletion agentrun/sandbox/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
Union,
)

from pydantic import Field

from agentrun.sandbox.model import TemplateType
from agentrun.utils.config import Config
from agentrun.utils.model import BaseModel
Expand Down Expand Up @@ -66,7 +68,9 @@ class Sandbox(BaseModel):
"""沙箱全局唯一资源名称 / Sandbox ARN"""
sandbox_id: Optional[str] = None
"""沙箱 ID / Sandbox ID"""
sandbox_idle_ttlin_seconds: Optional[int] = None
sandbox_idle_ttlin_seconds: Optional[int] = Field(
None, alias="sandboxIdleTTLInSeconds"
)
"""沙箱空闲 TTL(秒) / Sandbox Idle TTL (seconds)"""
sandbox_idle_timeout_seconds: Optional[int] = None
"""沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)"""
Expand Down
6 changes: 5 additions & 1 deletion agentrun/sandbox/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

from typing import Dict, List, Optional

from pydantic import Field

from agentrun.sandbox.model import (
PageableInput,
TemplateContainerConfiguration,
Expand Down Expand Up @@ -62,7 +64,9 @@ class Template(BaseModel):
"""执行角色 ARN / Execution Role ARN"""
sandbox_idle_timeout_in_seconds: Optional[int] = None
"""沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)"""
sandbox_ttlin_seconds: Optional[int] = None
sandbox_ttlin_seconds: Optional[int] = Field(
None, alias="sandboxTTLInSeconds"
)
"""沙箱存活时间(秒) / Sandbox TTL (seconds)"""
share_concurrency_limit_per_sandbox: Optional[int] = None
"""每个沙箱的最大并发会话数 / Max Concurrency Limit Per Sandbox"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,9 +664,7 @@ async def invoke_agent(request: AgentRequest):
json={
"messages": [{
"role": "user",
"content": (
"查询当前的时间,并获取天气信息,同时输出我的密钥信息"
),
"content": "查询当前的时间,并获取天气信息,同时输出我的密钥信息",
}],
"stream": True,
},
Expand Down Expand Up @@ -729,9 +727,7 @@ async def invoke_agent(request: AgentRequest):
json={
"messages": [{
"role": "user",
"content": (
"查询当前的时间,并获取天气信息,同时输出我的密钥信息"
),
"content": "查询当前的时间,并获取天气信息,同时输出我的密钥信息",
}],
"stream": True,
},
Expand Down
20 changes: 5 additions & 15 deletions tests/unittests/toolset/api/test_openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,7 @@ def test_post_with_ref_schema(self):
"content": {
"application/json": {
"schema": {
"$ref": (
"#/components/schemas/CreateOrderRequest"
)
"$ref": "#/components/schemas/CreateOrderRequest"
}
}
},
Expand Down Expand Up @@ -758,9 +756,7 @@ def test_invalid_ref_gracefully_handled(self):
"content": {
"application/json": {
"schema": {
"$ref": (
"#/components/schemas/NonExistent"
)
"$ref": "#/components/schemas/NonExistent"
}
}
}
Expand Down Expand Up @@ -793,9 +789,7 @@ def test_external_ref_not_resolved(self):
"content": {
"application/json": {
"schema": {
"$ref": (
"https://example.com/schemas/external.json"
)
"$ref": "https://example.com/schemas/external.json"
}
}
}
Expand Down Expand Up @@ -915,9 +909,7 @@ def _get_coffee_shop_schema():
"content": {
"application/json": {
"schema": {
"$ref": (
"#/components/schemas/CreateOrderRequest"
)
"$ref": "#/components/schemas/CreateOrderRequest"
}
}
},
Expand Down Expand Up @@ -953,9 +945,7 @@ def _get_coffee_shop_schema():
"content": {
"application/json": {
"schema": {
"$ref": (
"#/components/schemas/UpdateOrderStatusRequest"
)
"$ref": "#/components/schemas/UpdateOrderStatusRequest"
}
}
},
Expand Down
78 changes: 78 additions & 0 deletions tests/unittests/utils/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,81 @@ def test_is_final_instance_method(self):
"""测试实例方法 is_final"""
assert Status.READY.is_final() is True
assert Status.CREATING.is_final() is False


class TestTTLAliasFixIssue53:
"""测试 TTL 字段的显式 alias 修复 (Issue #53)

验证含有连续大写缩写词 (TTL) 的字段能正确从 API 返回的 camelCase key 解析。
"""

def test_template_sandbox_ttlin_seconds_from_api_data(self):
"""Template.sandbox_ttlin_seconds 应能通过 sandboxTTLInSeconds 正确解析"""
from agentrun.sandbox.template import Template

api_data = {
"templateName": "code-interpreter-01",
"sandboxIdleTimeoutInSeconds": 900,
"sandboxTTLInSeconds": 3600,
}
t = Template.model_validate(api_data, by_alias=True)
assert t.sandbox_idle_timeout_in_seconds == 900
assert t.sandbox_ttlin_seconds == 3600
assert t.model_extra.get("sandboxTTLInSeconds") is None

def test_template_sandbox_ttlin_seconds_by_field_name(self):
"""Template.sandbox_ttlin_seconds 也应支持通过字段名直接赋值"""
from agentrun.sandbox.template import Template

t = Template(sandbox_ttlin_seconds=1800)
assert t.sandbox_ttlin_seconds == 1800

def test_template_sandbox_ttlin_seconds_serialization(self):
"""Template 序列化时应使用正确的 alias sandboxTTLInSeconds"""
from agentrun.sandbox.template import Template

t = Template(sandbox_ttlin_seconds=7200)
data = t.model_dump(by_alias=True)
assert data["sandboxTTLInSeconds"] == 7200

def test_template_input_sandbox_ttlin_seconds_serialization(self):
"""TemplateInput.sandbox_ttlin_seconds 序列化应使用 sandboxTTLInSeconds"""
from agentrun.sandbox.model import TemplateInput, TemplateType

inp = TemplateInput(
template_type=TemplateType.CODE_INTERPRETER,
sandbox_ttlin_seconds=600,
)
data = inp.model_dump(by_alias=True)
assert data["sandboxTTLInSeconds"] == 600

def test_sandbox_idle_ttlin_seconds_from_api_data(self):
"""Sandbox.sandbox_idle_ttlin_seconds 应能通过 sandboxIdleTTLInSeconds 正确解析"""
from agentrun.sandbox.sandbox import Sandbox

api_data = {
"sandboxId": "sb-123",
"sandboxIdleTTLInSeconds": 300,
"sandboxIdleTimeoutSeconds": 600,
}
s = Sandbox.model_validate(api_data, by_alias=True)
assert s.sandbox_idle_ttlin_seconds == 300
assert s.sandbox_idle_timeout_seconds == 600
assert s.model_extra.get("sandboxIdleTTLInSeconds") is None

def test_template_from_inner_object_with_ttl(self):
"""Template.from_inner_object 应正确解析 sandboxTTLInSeconds"""
from agentrun.sandbox.template import Template

class MockDaraModel:

def to_map(self):
return {
"templateName": "test-template",
"sandboxIdleTimeoutInSeconds": 900,
"sandboxTTLInSeconds": 3600,
}

t = Template.from_inner_object(MockDaraModel())
assert t.sandbox_ttlin_seconds == 3600
assert t.sandbox_idle_timeout_in_seconds == 900
Loading