From c341a99e3d33a384668128d78d7fc06ec706ff51 Mon Sep 17 00:00:00 2001 From: "hanzhi.421" Date: Tue, 16 Jun 2026 20:24:37 +0800 Subject: [PATCH 1/6] feat(sandbox): add mcp config and xdg-open to complete browser task (cherry picked from commit 8405544d0050b49c88b59757b41ade01357ba591) --- agentkit/toolkit/cli/sandbox/cli_create.py | 6 ++++++ tests/toolkit/cli/test_cli_create_tool.py | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/agentkit/toolkit/cli/sandbox/cli_create.py b/agentkit/toolkit/cli/sandbox/cli_create.py index 8266957..439c980 100644 --- a/agentkit/toolkit/cli/sandbox/cli_create.py +++ b/agentkit/toolkit/cli/sandbox/cli_create.py @@ -132,6 +132,9 @@ def _build_codex_config_toml(model_name: str) -> str: "check_for_update_on_startup = false", 'web_search = "disabled"', f"model_catalog_json = {_toml_quote(CODEX_MODEL_CATALOG_PATH)}", + 'developer_instructions = """', + "When the user asks for simple browser operation tasks, you can use xdg-open to complete them.", + '"""', "", "[model_providers.codex]", 'name = "codex"', @@ -145,6 +148,9 @@ def _build_codex_config_toml(model_name: str) -> str: '[projects."/home/gem"]', 'trust_level = "trusted"', "", + "[mcp_servers.browser-use]", + 'url = "http://localhost:8100/mcp"', + "", ] ) diff --git a/tests/toolkit/cli/test_cli_create_tool.py b/tests/toolkit/cli/test_cli_create_tool.py index bab9839..d2296fe 100644 --- a/tests/toolkit/cli/test_cli_create_tool.py +++ b/tests/toolkit/cli/test_cli_create_tool.py @@ -395,11 +395,21 @@ def test_build_create_tool_request_adds_code_env_config_envs(monkeypatch): assert "model_auto_compact_token_limit" not in config_toml assert "model_supports_reasoning_summaries" not in config_toml assert "model_reasoning_summary" not in config_toml + assert ( + 'model_catalog_json = "/home/gem/.codex/model-catalog.json"\n' + 'developer_instructions = """\n' + "When the user asks for simple browser operation tasks, " + "you can use xdg-open to complete them.\n" + '"""' + ) in config_toml assert "[tui]" in config_toml assert "show_tooltips = false" in config_toml assert '[projects."/home/gem"]' in config_toml assert 'trust_level = "trusted"' in config_toml assert "check_for_update_on_startup = false" in config_toml + assert config_toml.rstrip().endswith( + '[mcp_servers.browser-use]\nurl = "http://localhost:8100/mcp"' + ) catalog_json = envs["CODEX_MODEL_CATALOG_JSON"] assert "\n " in catalog_json From fd77b82b1af9772420e6684a6c6f65a31198349a Mon Sep 17 00:00:00 2001 From: "hanzhi.421" Date: Tue, 16 Jun 2026 21:34:34 +0800 Subject: [PATCH 2/6] fix: sync sandbox exec codex model config (cherry picked from commit e50fadb7213608cbd9ec0daae675df7afcf74408) --- agentkit/toolkit/cli/sandbox/cli_create.py | 131 ++------------- agentkit/toolkit/cli/sandbox/cli_exec.py | 1 + agentkit/toolkit/cli/sandbox/model_config.py | 150 ++++++++++++++++++ .../toolkit/cli/sandbox/session_create.py | 44 ++++- tests/toolkit/cli/test_cli_sandbox.py | 61 +++++++ 5 files changed, 264 insertions(+), 123 deletions(-) create mode 100644 agentkit/toolkit/cli/sandbox/model_config.py diff --git a/agentkit/toolkit/cli/sandbox/cli_create.py b/agentkit/toolkit/cli/sandbox/cli_create.py index 439c980..fd98168 100644 --- a/agentkit/toolkit/cli/sandbox/cli_create.py +++ b/agentkit/toolkit/cli/sandbox/cli_create.py @@ -16,7 +16,6 @@ from __future__ import annotations -import json import os import re import time @@ -26,10 +25,21 @@ from agentkit.sdk.tools.client import AgentkitToolsClient from agentkit.sdk.tools import types as tools_types -from agentkit.toolkit.cli.sandbox.session_create import ( +from agentkit.toolkit.cli.sandbox.model_config import ( + ANTHROPIC_BASE_URL_ENV_KEYS, + CODE_ENV_CODEX_HOME, + CODE_ENV_HOME, + CODEX_CONFIG_TOML_ENV, + CODEX_MODEL_CATALOG_JSON_ENV, + DEFAULT_ANTHROPIC_BASE_URL, + DEFAULT_MODEL_BASE_URL, + DEFAULT_MODEL_NAME, MODEL_API_KEY_ENV, MODEL_API_KEY_ENV_KEYS, + MODEL_BASE_URL_ENV_KEYS, MODEL_NAME_ENV_KEYS, + build_codex_config_toml as _shared_build_codex_config_toml, + build_codex_model_catalog_json as _shared_build_codex_model_catalog_json, ) from agentkit.toolkit.cli.sandbox.tool_resolve import save_tool_result from agentkit.toolkit.cli.sandbox.utils import error @@ -46,27 +56,6 @@ DEFAULT_CREATE_TOOL_TYPE = "CodeEnv" DEFAULT_TOS_BUCKET_PATH = "/sandbox-session/default/default" DEFAULT_TOS_LOCAL_PATH = "/home/gem" -CODE_ENV_HOME = "/home/gem" -CODE_ENV_CODEX_HOME = "/home/gem/.codex" -CODEX_MODEL_CATALOG_PATH = f"{CODE_ENV_CODEX_HOME}/model-catalog.json" -DEFAULT_MODEL_NAME = "deepseek-v4-flash-260425" -DEFAULT_MODEL_NAME_LIST = ( - DEFAULT_MODEL_NAME, - "deepseek-v4-pro-260425", - "doubao-seed-2-0-pro-260215", -) -DEFAULT_MODEL_CONTEXT_WINDOW = 1000000 -MODEL_CONTEXT_WINDOW_OVERRIDES = { - "doubao-seed-2-0-pro-260215": 256000, -} -DEFAULT_MODEL_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3" -DEFAULT_ANTHROPIC_BASE_URL = "https://ark.cn-beijing.volces.com/api/compatible" -MODEL_BASE_URL_ENV_KEYS = ( - "OPENCODE_BASE_URL", - "CODEX_BASE_URL", - "MODEL_BASE_URL", -) -ANTHROPIC_BASE_URL_ENV_KEYS = ("ANTHROPIC_BASE_URL",) DISABLED_SERVICE_ENV_KEYS = ( "DISABLE_JUPYTER", "DISABLE_CODE_SERVER", @@ -114,100 +103,12 @@ def _append_tool_envs( ) -def _toml_quote(value: str) -> str: - return json.dumps(value, ensure_ascii=False) - - def _build_codex_config_toml(model_name: str) -> str: - quoted_model = _toml_quote(model_name) - return "\n".join( - [ - 'model_provider = "codex"', - f"model = {quoted_model}", - f"review_model = {quoted_model}", - 'approval_policy = "never"', - 'sandbox_mode = "danger-full-access"', - 'model_reasoning_effort = "medium"', - 'personality = "pragmatic"', - "check_for_update_on_startup = false", - 'web_search = "disabled"', - f"model_catalog_json = {_toml_quote(CODEX_MODEL_CATALOG_PATH)}", - 'developer_instructions = """', - "When the user asks for simple browser operation tasks, you can use xdg-open to complete them.", - '"""', - "", - "[model_providers.codex]", - 'name = "codex"', - f"base_url = {_toml_quote(DEFAULT_MODEL_BASE_URL)}", - 'wire_api = "responses"', - 'env_key = "CODEX_API_KEY"', - "", - "[tui]", - "show_tooltips = false", - "", - '[projects."/home/gem"]', - 'trust_level = "trusted"', - "", - "[mcp_servers.browser-use]", - 'url = "http://localhost:8100/mcp"', - "", - ] - ) - - -def _build_model_catalog_item(model_name: str, max_context_window: int) -> dict: - return { - "slug": model_name, - "display_name": model_name, - "supported_reasoning_levels": [ - { - "effort": "low", - "description": "Fast responses with lighter reasoning", - }, - { - "effort": "medium", - "description": "Balances speed and reasoning depth", - }, - { - "effort": "high", - "description": "Greater reasoning depth", - }, - ], - "max_context_window": max_context_window, - "shell_type": "shell_command", - "visibility": "list", - "supported_in_api": True, - "priority": 100, - "base_instructions": "", - "supports_reasoning_summaries": True, - "support_verbosity": False, - "truncation_policy": {"mode": "tokens", "limit": 10000}, - "supports_parallel_tool_calls": False, - "experimental_supported_tools": [], - } - - -def _model_catalog_context_window(model_name: str) -> int: - return MODEL_CONTEXT_WINDOW_OVERRIDES.get( - model_name, - DEFAULT_MODEL_CONTEXT_WINDOW, - ) + return _shared_build_codex_config_toml(model_name) def _build_codex_model_catalog_json(model_name: str) -> str: - deduped_model_names = list( - dict.fromkeys((model_name, *DEFAULT_MODEL_NAME_LIST)) - ) - payload = { - "models": [ - _build_model_catalog_item( - name, - _model_catalog_context_window(name), - ) - for name in deduped_model_names - ] - } - return json.dumps(payload, ensure_ascii=False, indent=2) + return _shared_build_codex_model_catalog_json(model_name) def _append_code_env_tool_envs( @@ -229,11 +130,11 @@ def _append_code_env_tool_envs( Value=CODE_ENV_CODEX_HOME, ), tools_types.EnvsItemForCreateTool( - Key="CODEX_CONFIG_TOML", + Key=CODEX_CONFIG_TOML_ENV, Value=_build_codex_config_toml(model_name), ), tools_types.EnvsItemForCreateTool( - Key="CODEX_MODEL_CATALOG_JSON", + Key=CODEX_MODEL_CATALOG_JSON_ENV, Value=_build_codex_model_catalog_json(model_name), ), ] diff --git a/agentkit/toolkit/cli/sandbox/cli_exec.py b/agentkit/toolkit/cli/sandbox/cli_exec.py index 4109ebf..3c0c9b2 100644 --- a/agentkit/toolkit/cli/sandbox/cli_exec.py +++ b/agentkit/toolkit/cli/sandbox/cli_exec.py @@ -410,6 +410,7 @@ def exec_command( envs=build_model_envs( model_name=model_name, model_api_key=model_api_key, + include_codex_config=tool_type == SandboxToolType.CODE_ENV, ), ) except typer.Exit: diff --git a/agentkit/toolkit/cli/sandbox/model_config.py b/agentkit/toolkit/cli/sandbox/model_config.py new file mode 100644 index 0000000..17f7f0c --- /dev/null +++ b/agentkit/toolkit/cli/sandbox/model_config.py @@ -0,0 +1,150 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Model and runtime configuration helpers for sandbox CLI.""" + +from __future__ import annotations + +import json + +MODEL_NAME_ENV_KEYS = ("OPENCODE_MODEL", "CODEX_MODEL", "ANTHROPIC_MODEL") +MODEL_API_KEY_ENV_KEYS = ( + "OPENCODE_API_KEY", + "CODEX_API_KEY", + "ANTHROPIC_AUTH_TOKEN", +) +MODEL_BASE_URL_ENV_KEYS = ( + "OPENCODE_BASE_URL", + "CODEX_BASE_URL", + "MODEL_BASE_URL", +) +ANTHROPIC_BASE_URL_ENV_KEYS = ("ANTHROPIC_BASE_URL",) +MODEL_API_KEY_ENV = "MODEL_API_KEY" + +CODE_ENV_HOME = "/home/gem" +CODE_ENV_CODEX_HOME = "/home/gem/.codex" +CODEX_CONFIG_TOML_ENV = "CODEX_CONFIG_TOML" +CODEX_MODEL_CATALOG_JSON_ENV = "CODEX_MODEL_CATALOG_JSON" +CODEX_MODEL_CATALOG_PATH = f"{CODE_ENV_CODEX_HOME}/model-catalog.json" +DEFAULT_MODEL_NAME = "deepseek-v4-flash-260425" +DEFAULT_MODEL_NAME_LIST = ( + DEFAULT_MODEL_NAME, + "deepseek-v4-pro-260425", + "doubao-seed-2-0-pro-260215", +) +DEFAULT_MODEL_CONTEXT_WINDOW = 1000000 +MODEL_CONTEXT_WINDOW_OVERRIDES = { + "doubao-seed-2-0-pro-260215": 256000, +} +DEFAULT_MODEL_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3" +DEFAULT_ANTHROPIC_BASE_URL = "https://ark.cn-beijing.volces.com/api/compatible" + + +def _toml_quote(value: str) -> str: + return json.dumps(value, ensure_ascii=False) + + +def build_codex_config_toml(model_name: str) -> str: + quoted_model = _toml_quote(model_name) + return "\n".join( + [ + 'model_provider = "codex"', + f"model = {quoted_model}", + f"review_model = {quoted_model}", + 'approval_policy = "never"', + 'sandbox_mode = "danger-full-access"', + 'model_reasoning_effort = "medium"', + 'personality = "pragmatic"', + "check_for_update_on_startup = false", + 'web_search = "disabled"', + f"model_catalog_json = {_toml_quote(CODEX_MODEL_CATALOG_PATH)}", + 'developer_instructions = """', + ( + "When the user asks for simple browser operation tasks, " + "you can use xdg-open to complete them." + ), + '"""', + "", + "[model_providers.codex]", + 'name = "codex"', + f"base_url = {_toml_quote(DEFAULT_MODEL_BASE_URL)}", + 'wire_api = "responses"', + 'env_key = "CODEX_API_KEY"', + "", + "[tui]", + "show_tooltips = false", + "", + '[projects."/home/gem"]', + 'trust_level = "trusted"', + "", + "[mcp_servers.browser-use]", + 'url = "http://localhost:8100/mcp"', + "", + ] + ) + + +def _build_model_catalog_item(model_name: str, max_context_window: int) -> dict: + return { + "slug": model_name, + "display_name": model_name, + "supported_reasoning_levels": [ + { + "effort": "low", + "description": "Fast responses with lighter reasoning", + }, + { + "effort": "medium", + "description": "Balances speed and reasoning depth", + }, + { + "effort": "high", + "description": "Greater reasoning depth", + }, + ], + "max_context_window": max_context_window, + "shell_type": "shell_command", + "visibility": "list", + "supported_in_api": True, + "priority": 100, + "base_instructions": "", + "supports_reasoning_summaries": True, + "support_verbosity": False, + "truncation_policy": {"mode": "tokens", "limit": 10000}, + "supports_parallel_tool_calls": False, + "experimental_supported_tools": [], + } + + +def model_catalog_context_window(model_name: str) -> int: + return MODEL_CONTEXT_WINDOW_OVERRIDES.get( + model_name, + DEFAULT_MODEL_CONTEXT_WINDOW, + ) + + +def build_codex_model_catalog_json(model_name: str) -> str: + deduped_model_names = list( + dict.fromkeys((model_name, *DEFAULT_MODEL_NAME_LIST)) + ) + payload = { + "models": [ + _build_model_catalog_item( + name, + model_catalog_context_window(name), + ) + for name in deduped_model_names + ] + } + return json.dumps(payload, ensure_ascii=False, indent=2) diff --git a/agentkit/toolkit/cli/sandbox/session_create.py b/agentkit/toolkit/cli/sandbox/session_create.py index a987091..7540983 100644 --- a/agentkit/toolkit/cli/sandbox/session_create.py +++ b/agentkit/toolkit/cli/sandbox/session_create.py @@ -23,6 +23,15 @@ from agentkit.sdk.tools.client import AgentkitToolsClient from agentkit.sdk.tools import types as tools_types +from agentkit.toolkit.cli.sandbox.model_config import ( + CODEX_CONFIG_TOML_ENV, + CODEX_MODEL_CATALOG_JSON_ENV, + MODEL_API_KEY_ENV, + MODEL_API_KEY_ENV_KEYS, + MODEL_NAME_ENV_KEYS, + build_codex_config_toml, + build_codex_model_catalog_json, +) from agentkit.toolkit.cli.sandbox.session_sync import ( session_info_to_result, sync_remote_sessions, @@ -40,13 +49,6 @@ DEFAULT_SANDBOX_TTL = 28800 SANDBOX_TOOL_ID_ENV = "AGENTKIT_SANDBOX_TOOL_ID" SANDBOX_TTL_ENV = "AGENTKIT_SANDBOX_TTL" -MODEL_NAME_ENV_KEYS = ("OPENCODE_MODEL", "CODEX_MODEL", "ANTHROPIC_MODEL") -MODEL_API_KEY_ENV_KEYS = ( - "OPENCODE_API_KEY", - "CODEX_API_KEY", - "ANTHROPIC_AUTH_TOKEN", -) -MODEL_API_KEY_ENV = "MODEL_API_KEY" CREATE_SESSION_START_FAIL_CODE = "ErrCreateSessionFail" CREATE_SESSION_CONFIRM_ATTEMPTS = 6 CREATE_SESSION_CONFIRM_INTERVAL_SECONDS = 5 @@ -68,14 +70,40 @@ def _append_envs( ) +def _append_codex_config_envs( + envs: list[tools_types.EnvsItemForCreateSession], + model_name: Optional[str], +) -> None: + resolved_model_name = (model_name or "").strip() + if not resolved_model_name: + return + + envs.extend( + [ + tools_types.EnvsItemForCreateSession( + key=CODEX_CONFIG_TOML_ENV, + value=build_codex_config_toml(resolved_model_name), + ), + tools_types.EnvsItemForCreateSession( + key=CODEX_MODEL_CATALOG_JSON_ENV, + value=build_codex_model_catalog_json(resolved_model_name), + ), + ] + ) + + def build_model_envs( *, model_name: Optional[str] = None, model_api_key: Optional[str] = None, + include_codex_config: bool = False, ) -> list[tools_types.EnvsItemForCreateSession] | None: envs: list[tools_types.EnvsItemForCreateSession] = [] + resolved_model_name = (model_name or "").strip() resolved_model_api_key = model_api_key or os.getenv(MODEL_API_KEY_ENV) - _append_envs(envs, MODEL_NAME_ENV_KEYS, model_name) + _append_envs(envs, MODEL_NAME_ENV_KEYS, resolved_model_name) + if include_codex_config: + _append_codex_config_envs(envs, resolved_model_name) _append_envs(envs, MODEL_API_KEY_ENV_KEYS, resolved_model_api_key) return envs or None diff --git a/tests/toolkit/cli/test_cli_sandbox.py b/tests/toolkit/cli/test_cli_sandbox.py index bca4634..308d737 100644 --- a/tests/toolkit/cli/test_cli_sandbox.py +++ b/tests/toolkit/cli/test_cli_sandbox.py @@ -2581,6 +2581,67 @@ def fake_connect(_ws_url, initial_command=None, on_shell_id=None): ] +def test_cli_exec_syncs_codex_config_for_code_env_model_name( + monkeypatch, + tmp_path, +) -> None: + from agentkit.toolkit.cli.cli import app + import agentkit.toolkit.cli.sandbox.cli_exec as cli_exec + + monkeypatch.delenv("MODEL_API_KEY", raising=False) + store_path = _patch_store_path(monkeypatch, tmp_path) + stored_session = { + "session_id": "user-1", + "tool_id": "tool-1", + "instance_id": "session-1", + "endpoint": "https://sandbox.example.com/?token=abc", + } + store_path.write_text( + json.dumps({"user-1": stored_session}), + encoding="utf-8", + ) + captured_session = {} + _patch_exec_session( + monkeypatch, + cli_exec, + stored_session, + capture=captured_session, + ) + monkeypatch.setattr( + cli_exec, + "_connect_terminal", + lambda *_args, **_kwargs: None, + ) + + result = runner.invoke( + app, + [ + "sandbox", + "exec", + "--session-id", + "user-1", + "--model-name", + "claude-sonnet-4", + ], + ) + + assert result.exit_code == 0 + envs = {item.key: item.value for item in captured_session["envs"]} + assert list(envs) == [ + "OPENCODE_MODEL", + "CODEX_MODEL", + "ANTHROPIC_MODEL", + "CODEX_CONFIG_TOML", + "CODEX_MODEL_CATALOG_JSON", + ] + config_toml = envs["CODEX_CONFIG_TOML"] + assert 'model = "claude-sonnet-4"' in config_toml + assert 'review_model = "claude-sonnet-4"' in config_toml + assert 'model = "deepseek-v4-flash-260425"' not in config_toml + catalog = json.loads(envs["CODEX_MODEL_CATALOG_JSON"]) + assert catalog["models"][0]["slug"] == "claude-sonnet-4" + + def test_cli_exec_rejects_model_base_url_option() -> None: from agentkit.toolkit.cli.cli import app From c2a95752f50f11007da83f41d995fca6381e0a1d Mon Sep 17 00:00:00 2001 From: "hanzhi.421" Date: Wed, 17 Jun 2026 12:53:14 +0800 Subject: [PATCH 3/6] Update sandbox create defaults (cherry picked from commit d4fea766c018150fdf863ca913107b0cb2788577) --- agentkit/toolkit/cli/sandbox/README.md | 26 ++-- agentkit/toolkit/cli/sandbox/cli_create.py | 44 +++++- tests/toolkit/cli/test_cli_create_tool.py | 150 +++++++++++++++++++-- 3 files changed, 194 insertions(+), 26 deletions(-) diff --git a/agentkit/toolkit/cli/sandbox/README.md b/agentkit/toolkit/cli/sandbox/README.md index e937998..c105551 100644 --- a/agentkit/toolkit/cli/sandbox/README.md +++ b/agentkit/toolkit/cli/sandbox/README.md @@ -38,9 +38,10 @@ python3 -m pip show agentkit-sdk-python ### Create -Create an AgentKit Tool for sandbox sessions. This command prepares the backing -TOS bucket/path, builds a `CreateTool` request, waits until the tool reaches -`Ready`, and prints the created tool ID. +Create an AgentKit Tool for sandbox sessions. This command builds a `CreateTool` +request, waits until the tool reaches `Ready`, and prints the created tool ID. +When `--tos-bucket` is provided, it also prepares the backing TOS bucket/path and +mounts it into sandbox sessions. ```bash agentkit sandbox create \ @@ -55,14 +56,18 @@ Options: - `--tool-name`: optional. Tool name. If omitted, the CLI generates a name like `agentkit-codeenv-`. - `--tos-bucket`: optional. TOS bucket mounted at `/home/gem`. If omitted, the - CLI uses `TOSService.generate_bucket_name()`, which resolves the configured - default bucket template. + tool is created without TOS mount configuration. +- `--cpu`: optional. Sandbox vCPU count; allowed values are `2`, `4`, `8`, and + `16`. Defaults to `4`. Memory is derived as 2 GiB per vCPU. - `--model-name`: optional. Injected into the tool as `OPENCODE_MODEL`, `CODEX_MODEL`, and `ANTHROPIC_MODEL`. - `--model-api-key`: optional. Injected into the tool as `OPENCODE_API_KEY`, `CODEX_API_KEY`, and `ANTHROPIC_AUTH_TOKEN`. If omitted, the CLI uses `MODEL_API_KEY` when that environment variable is set. +The sandbox create request maps `--cpu` to `CpuMilli=` and +`MemoryMb=`, so the default shape is 4 vCPU / 8 GiB. + The tool always injects Volcengine Ark compatible endpoints into `OPENCODE_BASE_URL`, `CODEX_BASE_URL`, `MODEL_BASE_URL`, and `ANTHROPIC_BASE_URL`. Custom `--model-base-url` is intentionally not exposed. @@ -73,7 +78,7 @@ TOS credentials. The command supports the same credential sources as the shared Volcengine configuration, including environment variables and global `agentkit config --global` settings. -The generated tool TOS mount uses: +When `--tos-bucket` is set, the generated tool TOS mount uses: ```text BucketPath: /sandbox-session/default/default @@ -81,14 +86,17 @@ LocalMountPath: /home/gem Endpoint: http://tos-.ivolces.com ``` -When `sandbox exec` or `sandbox shell` later creates a session from this tool, -the session flow calls `GetTool`, reads this mount configuration, and mounts a -per-session path: +When `sandbox exec` or `sandbox shell` later creates a session from a tool with +TOS configuration, the session flow calls `GetTool`, reads this mount +configuration, and mounts a per-session path: ```text /sandbox-session/tool-/session-/ ``` +If the tool was created without `--tos-bucket`, `GetTool` has no TOS mount +configuration and session creation skips TOS mounting. + After the tool reaches `Ready`, `agentkit sandbox create` writes the tool information to `.agentkit/sandbox/tools.json`. Only one tool record is stored per `ToolType`; creating or resolving another tool of the same type replaces diff --git a/agentkit/toolkit/cli/sandbox/cli_create.py b/agentkit/toolkit/cli/sandbox/cli_create.py index fd98168..6543eb7 100644 --- a/agentkit/toolkit/cli/sandbox/cli_create.py +++ b/agentkit/toolkit/cli/sandbox/cli_create.py @@ -54,6 +54,9 @@ SANDBOX_REGION_ENV = "AGENTKIT_SANDBOX_REGION" SANDBOX_TOS_REGION_ENV = "AGENTKIT_SANDBOX_TOS_REGION" DEFAULT_CREATE_TOOL_TYPE = "CodeEnv" +DEFAULT_CPU = 4 +VALID_CPU_VALUES = (2, 4, 8, 16) +MEMORY_MB_PER_CPU = 2048 DEFAULT_TOS_BUCKET_PATH = "/sandbox-session/default/default" DEFAULT_TOS_LOCAL_PATH = "/home/gem" DISABLED_SERVICE_ENV_KEYS = ( @@ -83,9 +86,21 @@ def _generate_tool_name(tool_type: str) -> str: def _resolve_tos_bucket(tos_bucket: Optional[str]) -> str: resolved_bucket = (tos_bucket or "").strip() - if resolved_bucket: - return resolved_bucket - return TOSService.generate_bucket_name() + if not resolved_bucket: + error("--tos-bucket must not be empty") + return resolved_bucket + + +def _validate_cpu(value: int) -> int: + if value not in VALID_CPU_VALUES: + allowed = ", ".join(str(item) for item in VALID_CPU_VALUES) + raise typer.BadParameter(f"--cpu must be one of: {allowed}") + return value + + +def _cpu_to_resource_shape(cpu: int) -> tuple[int, int]: + resolved_cpu = _validate_cpu(cpu) + return resolved_cpu * 1000, resolved_cpu * MEMORY_MB_PER_CPU def _append_tool_envs( @@ -174,16 +189,20 @@ def _build_create_tool_request( name: Optional[str], tos_bucket: Optional[str], tos_region: str, + cpu: int = DEFAULT_CPU, model_name: Optional[str] = None, model_api_key: Optional[str] = None, ) -> tools_types.CreateToolRequest: resolved_tool_type = tool_type.strip() or DEFAULT_CREATE_TOOL_TYPE resolved_name = (name or "").strip() or _generate_tool_name(resolved_tool_type) tos_mount_config = _build_tos_mount_config(tos_bucket, tos_region) + cpu_milli, memory_mb = _cpu_to_resource_shape(cpu) return tools_types.CreateToolRequest( Name=resolved_name, ToolType=resolved_tool_type, + CpuMilli=cpu_milli, + MemoryMb=memory_mb, AuthorizerConfiguration=tools_types.AuthorizerForCreateTool( KeyAuth=tools_types.AuthorizerKeyAuthForCreateTool( ApiKeyName=generate_apikey_name(), @@ -206,7 +225,10 @@ def _build_create_tool_request( def _build_tos_mount_config( tos_bucket: Optional[str], region: str, -) -> tools_types.TosMountForCreateTool: +) -> tools_types.TosMountForCreateTool | None: + if not (tos_bucket or "").strip(): + return None + resolved_bucket = _resolve_tos_bucket(tos_bucket) service = TOSService( TOSServiceConfig( @@ -304,6 +326,7 @@ def create_tool( tool_type: str = DEFAULT_CREATE_TOOL_TYPE, tool_name: Optional[str] = None, tos_bucket: Optional[str] = None, + cpu: int = DEFAULT_CPU, model_name: Optional[str] = None, model_api_key: Optional[str] = None, ) -> dict[str, object]: @@ -314,6 +337,7 @@ def create_tool( name=tool_name, tos_bucket=tos_bucket, tos_region=tos_region, + cpu=cpu, model_name=model_name, model_api_key=model_api_key, ) @@ -347,7 +371,16 @@ def create_command( tos_bucket: Optional[str] = typer.Option( None, "--tos-bucket", - help="TOS bucket to mount at /home/gem.", + help=( + "TOS bucket to mount at /home/gem. " + "Omit to create the tool without a TOS mount." + ), + ), + cpu: int = typer.Option( + DEFAULT_CPU, + "--cpu", + help="Sandbox vCPU count. Allowed values: 2, 4, 8, 16.", + callback=_validate_cpu, ), model_name: Optional[str] = typer.Option( None, @@ -372,6 +405,7 @@ def create_command( tool_type=tool_type, tool_name=tool_name, tos_bucket=tos_bucket, + cpu=cpu, model_name=model_name, model_api_key=model_api_key, ) diff --git a/tests/toolkit/cli/test_cli_create_tool.py b/tests/toolkit/cli/test_cli_create_tool.py index d2296fe..438419d 100644 --- a/tests/toolkit/cli/test_cli_create_tool.py +++ b/tests/toolkit/cli/test_cli_create_tool.py @@ -154,7 +154,7 @@ def _reset_fake_tools_client(): _FakeTOSService.instances = [] -def test_create_command_uses_tos_service_and_default_region( +def test_create_command_skips_tos_mount_by_default( monkeypatch, tool_store_path, ): @@ -179,18 +179,12 @@ def test_create_command_uses_tos_service_and_default_region( assert client.secret_key == "" assert client.session_token == "" assert client.region == "cn-beijing" - assert len(_FakeTOSService.instances) == 1 - assert _FakeTOSService.instances[0].config.bucket == "agentkit-platform-123" - assert _FakeTOSService.instances[0].config.region == "cn-beijing" + assert _FakeTOSService.instances == [] assert _FakeToolsClient.last_request.name == "demo-tool" assert _FakeToolsClient.last_request.tool_type == "CodeEnv" - tos_config = _FakeToolsClient.last_request.tos_mount_config - assert tos_config is not None - assert tos_config.mount_points[0].bucket_name == "agentkit-platform-123" - assert ( - tos_config.mount_points[0].bucket_path - == "/sandbox-session/default/default" - ) + assert _FakeToolsClient.last_request.cpu_milli == 4000 + assert _FakeToolsClient.last_request.memory_mb == 8192 + assert _FakeToolsClient.last_request.tos_mount_config is None assert _FakeToolsClient.get_call_count == 1 assert json.loads(tool_store_path.read_text(encoding="utf-8")) == { "SkillEnv": { @@ -212,13 +206,108 @@ def test_create_command_uses_region_envs(monkeypatch): monkeypatch.setattr(cli_create, "AgentkitToolsClient", _FakeToolsClient) monkeypatch.setattr(cli_create, "TOSService", _FakeTOSService) - result = runner.invoke(app, ["sandbox", "create", "--tool-name", "demo-tool"]) + result = runner.invoke( + app, + [ + "sandbox", + "create", + "--tool-name", + "demo-tool", + "--tos-bucket", + "my-bucket", + ], + ) assert result.exit_code == 0 assert _FakeToolsClient.instances[0].region == "cn-shanghai" assert _FakeTOSService.instances[0].config.region == "cn-guangzhou" +def test_create_command_uses_tos_service_when_bucket_is_set(monkeypatch): + from agentkit.toolkit.cli.cli import app + from agentkit.toolkit.cli.sandbox import cli_create + + _reset_fake_tools_client() + monkeypatch.delenv("AGENTKIT_SANDBOX_TOS_REGION", raising=False) + monkeypatch.setattr(cli_create, "AgentkitToolsClient", _FakeToolsClient) + monkeypatch.setattr(cli_create, "TOSService", _FakeTOSService) + + result = runner.invoke( + app, + [ + "sandbox", + "create", + "--tool-name", + "demo-tool", + "--tos-bucket", + "my-bucket", + ], + ) + + assert result.exit_code == 0 + assert len(_FakeTOSService.instances) == 1 + assert _FakeTOSService.instances[0].config.bucket == "my-bucket" + assert _FakeTOSService.instances[0].config.region == "cn-beijing" + tos_config = _FakeToolsClient.last_request.tos_mount_config + assert tos_config is not None + assert tos_config.mount_points[0].bucket_name == "my-bucket" + assert ( + tos_config.mount_points[0].bucket_path + == "/sandbox-session/default/default" + ) + + +def test_create_command_uses_cpu_option_for_resource_shape(monkeypatch): + from agentkit.toolkit.cli.cli import app + from agentkit.toolkit.cli.sandbox import cli_create + + _reset_fake_tools_client() + monkeypatch.setattr(cli_create, "AgentkitToolsClient", _FakeToolsClient) + monkeypatch.setattr(cli_create, "TOSService", _FakeTOSService) + + result = runner.invoke( + app, + [ + "sandbox", + "create", + "--tool-name", + "demo-tool", + "--cpu", + "2", + ], + ) + + assert result.exit_code == 0 + assert _FakeToolsClient.last_request.cpu_milli == 2000 + assert _FakeToolsClient.last_request.memory_mb == 4096 + + +def test_create_command_rejects_invalid_cpu(monkeypatch): + from agentkit.toolkit.cli.cli import app + from agentkit.toolkit.cli.sandbox import cli_create + + _reset_fake_tools_client() + monkeypatch.setattr(cli_create, "AgentkitToolsClient", _FakeToolsClient) + monkeypatch.setattr(cli_create, "TOSService", _FakeTOSService) + + result = runner.invoke( + app, + [ + "sandbox", + "create", + "--tool-name", + "demo-tool", + "--cpu", + "3", + ], + ) + + assert result.exit_code != 0 + assert "--cpu must be one of: 2, 4, 8, 16" in result.output + assert _FakeToolsClient.instances == [] + assert _FakeTOSService.instances == [] + + def test_create_command_rejects_region_option(monkeypatch): from agentkit.toolkit.cli.cli import app from agentkit.toolkit.cli.sandbox import cli_create @@ -325,6 +414,43 @@ def test_build_create_tool_request_adds_tos_mount(monkeypatch): assert request.network_configuration is not None assert request.network_configuration.enable_public_network is True assert request.network_configuration.enable_private_network is False + assert request.cpu_milli == 4000 + assert request.memory_mb == 8192 + + +def test_build_create_tool_request_skips_tos_mount_without_bucket(monkeypatch): + from agentkit.toolkit.cli.sandbox import cli_create + + _reset_fake_tools_client() + monkeypatch.setattr(cli_create, "TOSService", _FakeTOSService) + + request = cli_create._build_create_tool_request( + tool_type="CodeEnv", + name="demo-tool", + tos_bucket=None, + tos_region="cn-beijing", + ) + + assert _FakeTOSService.instances == [] + assert request.tos_mount_config is None + + +def test_build_create_tool_request_derives_memory_from_cpu(monkeypatch): + from agentkit.toolkit.cli.sandbox import cli_create + + _reset_fake_tools_client() + monkeypatch.setattr(cli_create, "TOSService", _FakeTOSService) + + request = cli_create._build_create_tool_request( + tool_type="CodeEnv", + name="demo-tool", + tos_bucket=None, + tos_region="cn-beijing", + cpu=8, + ) + + assert request.cpu_milli == 8000 + assert request.memory_mb == 16384 def test_build_create_tool_request_adds_model_envs(monkeypatch): From 938cd4a282b93cdf395f595349b43a5c1591f511 Mon Sep 17 00:00:00 2001 From: "shijinyu.7" Date: Wed, 17 Jun 2026 13:31:40 +0800 Subject: [PATCH 4/6] feat: add sandbox session id short alias (cherry picked from commit 8c069b9c37b3f58cf1355f35a4685c21c23805c1) --- agentkit/toolkit/cli/sandbox/README.md | 10 +++++----- agentkit/toolkit/cli/sandbox/cli_exec.py | 1 + agentkit/toolkit/cli/sandbox/cli_file.py | 3 +++ agentkit/toolkit/cli/sandbox/cli_get.py | 1 + agentkit/toolkit/cli/sandbox/cli_shell.py | 1 + agentkit/toolkit/cli/sandbox/cli_web.py | 1 + tests/toolkit/cli/test_cli_sandbox.py | 3 ++- tests/toolkit/cli/test_cli_sandbox_file.py | 5 ++++- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/agentkit/toolkit/cli/sandbox/README.md b/agentkit/toolkit/cli/sandbox/README.md index c105551..bc6d33a 100644 --- a/agentkit/toolkit/cli/sandbox/README.md +++ b/agentkit/toolkit/cli/sandbox/README.md @@ -114,7 +114,7 @@ agentkit sandbox get Options: -- `--session-id` / `--sid`: optional. Sandbox session ID to look up. If omitted, the CLI +- `--session-id` / `--sid` / `-s`: optional. Sandbox session ID to look up. If omitted, the CLI returns all records from `.agentkit/sandbox/sessions.json` after syncing the current tool. - `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is @@ -150,7 +150,7 @@ only operate on existing sessions; they do not create a session when Common options: -- `--session-id` / `--sid`: required. Sandbox session ID to operate on. +- `--session-id` / `--sid` / `-s`: required. Sandbox session ID to operate on. - `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is set, the CLI resolves an existing tool by `--tool-type`. - `--tool-type`: optional. `CodeEnv` or `SkillEnv`; defaults to `CodeEnv`. @@ -278,7 +278,7 @@ agentkit sandbox shell \ Options: -- `--session-id` / `--sid`: optional. Sandbox session ID used as the local session key. +- `--session-id` / `--sid` / `-s`: optional. Sandbox session ID used as the local session key. If omitted, a UUID is generated and the command creates a sandbox session through the same idempotent session ensure flow as `sandbox exec`. - `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is @@ -325,7 +325,7 @@ agentkit sandbox web --session-id 123456789 --tool-id t-example Options: -- `--session-id` / `--sid`: required. Sandbox session ID to open in a browser. +- `--session-id` / `--sid` / `-s`: required. Sandbox session ID to open in a browser. - `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. The underscore alias `--tool_id` is also accepted. @@ -359,7 +359,7 @@ agentkit sandbox exec --session-id 123456789 --src-dir ./README.md ./requirement Options: -- `--session-id` / `--sid`: optional. Sandbox session ID used as the local +- `--session-id` / `--sid` / `-s`: optional. Sandbox session ID used as the local session key. If omitted, a UUID is generated and the command creates a sandbox session through the same idempotent session ensure flow. - `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is diff --git a/agentkit/toolkit/cli/sandbox/cli_exec.py b/agentkit/toolkit/cli/sandbox/cli_exec.py index 3c0c9b2..d077bca 100644 --- a/agentkit/toolkit/cli/sandbox/cli_exec.py +++ b/agentkit/toolkit/cli/sandbox/cli_exec.py @@ -333,6 +333,7 @@ def exec_command( None, "--session-id", "--sid", + "-s", help=( "Sandbox session ID. Defaults to a generated UUID and creates " "a sandbox session when needed." diff --git a/agentkit/toolkit/cli/sandbox/cli_file.py b/agentkit/toolkit/cli/sandbox/cli_file.py index 2af0cd2..84ad610 100644 --- a/agentkit/toolkit/cli/sandbox/cli_file.py +++ b/agentkit/toolkit/cli/sandbox/cli_file.py @@ -587,6 +587,7 @@ def file_upload_command( ..., "--session-id", "--sid", + "-s", help="Sandbox session ID to upload into.", ), workspace: Optional[str] = typer.Option( @@ -693,6 +694,7 @@ def file_download_command( ..., "--session-id", "--sid", + "-s", help="Sandbox session ID to download from.", ), workspace: Optional[str] = typer.Option( @@ -810,6 +812,7 @@ def file_list_command( ..., "--session-id", "--sid", + "-s", help="Sandbox session ID to list files from.", ), workspace: Optional[str] = typer.Option( diff --git a/agentkit/toolkit/cli/sandbox/cli_get.py b/agentkit/toolkit/cli/sandbox/cli_get.py index 158565c..ca890ae 100644 --- a/agentkit/toolkit/cli/sandbox/cli_get.py +++ b/agentkit/toolkit/cli/sandbox/cli_get.py @@ -49,6 +49,7 @@ def get_command( None, "--session-id", "--sid", + "-s", help=( "Sandbox session ID to look up. Omit to return all local " "sandbox sessions after syncing the current tool." diff --git a/agentkit/toolkit/cli/sandbox/cli_shell.py b/agentkit/toolkit/cli/sandbox/cli_shell.py index 62e64fb..f8b60ce 100644 --- a/agentkit/toolkit/cli/sandbox/cli_shell.py +++ b/agentkit/toolkit/cli/sandbox/cli_shell.py @@ -47,6 +47,7 @@ def shell_command( None, "--session-id", "--sid", + "-s", help=( "Sandbox session ID. Defaults to a generated UUID and creates " "a sandbox session when needed." diff --git a/agentkit/toolkit/cli/sandbox/cli_web.py b/agentkit/toolkit/cli/sandbox/cli_web.py index 10ad642..ebf1a4b 100644 --- a/agentkit/toolkit/cli/sandbox/cli_web.py +++ b/agentkit/toolkit/cli/sandbox/cli_web.py @@ -59,6 +59,7 @@ def web_command( ..., "--session-id", "--sid", + "-s", help="Sandbox session ID to open in a browser.", ), tool_id: Optional[str] = typer.Option( diff --git a/tests/toolkit/cli/test_cli_sandbox.py b/tests/toolkit/cli/test_cli_sandbox.py index 308d737..443f0e1 100644 --- a/tests/toolkit/cli/test_cli_sandbox.py +++ b/tests/toolkit/cli/test_cli_sandbox.py @@ -1024,7 +1024,7 @@ def test_sandbox_command_group_is_registered() -> None: ["sandbox", "exec", "--help"], ], ) -def test_sandbox_session_id_options_accept_sid_alias(args) -> None: +def test_sandbox_session_id_options_accept_aliases(args) -> None: from agentkit.toolkit.cli.cli import app result = runner.invoke(app, args) @@ -1032,6 +1032,7 @@ def test_sandbox_session_id_options_accept_sid_alias(args) -> None: assert result.exit_code == 0 assert "--session-id" in result.output assert "--sid" in result.output + assert "-s" in result.output def test_sandbox_commands_are_not_registered_at_top_level() -> None: diff --git a/tests/toolkit/cli/test_cli_sandbox_file.py b/tests/toolkit/cli/test_cli_sandbox_file.py index d6288e3..a32f387 100644 --- a/tests/toolkit/cli/test_cli_sandbox_file.py +++ b/tests/toolkit/cli/test_cli_sandbox_file.py @@ -114,6 +114,9 @@ def test_sandbox_file_command_group_is_registered() -> None: assert "--session-id" in result.output or "Commands" in result.output if args[2:3] in (["upload"], ["download"]): assert "--sid" in result.output + assert "-s" in result.output + if args[2:3] == ["list"]: + assert "-s" in result.output def test_cli_file_upload_directory_creates_destination_and_extracts_archive( @@ -1176,7 +1179,7 @@ def fake_post(url, **kwargs): "sandbox", "file", "list", - "--sid", + "-s", "user-1", "--workspace", "/home/gem", From e6c3e2176d458b1a52d621db7b88d0adfedb6164 Mon Sep 17 00:00:00 2001 From: "shijinyu.7" Date: Wed, 17 Jun 2026 14:08:17 +0800 Subject: [PATCH 5/6] fix: sync stale sandbox sessions before recreate (cherry picked from commit 8990c6f9c6836702afdd845e7e6b07a589d6d133) --- .../toolkit/cli/sandbox/session_create.py | 21 +++++ tests/toolkit/cli/test_cli_sandbox.py | 77 ++++++++++++++++++- 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/agentkit/toolkit/cli/sandbox/session_create.py b/agentkit/toolkit/cli/sandbox/session_create.py index 7540983..dfba650 100644 --- a/agentkit/toolkit/cli/sandbox/session_create.py +++ b/agentkit/toolkit/cli/sandbox/session_create.py @@ -381,6 +381,27 @@ def ensure_sandbox_session( save_session_result(result) return result + synced_tool_id = sync_remote_sessions( + session_id=resolved_session_id, + tool_id=resolved_tool_id, + tool_type=tool_type, + client=client, + env_var_name=SANDBOX_TOOL_ID_ENV, + ) + if synced_tool_id: + resolved_tool_id = synced_tool_id + existing = find_session_result(resolved_session_id) + if existing: + result = _get_existing_remote_session( + client, + existing, + resolved_session_id, + resolved_tool_id, + ) + if result: + save_session_result(result) + return result + result = _create_session( client, resolved_session_id, diff --git a/tests/toolkit/cli/test_cli_sandbox.py b/tests/toolkit/cli/test_cli_sandbox.py index 443f0e1..fc047ac 100644 --- a/tests/toolkit/cli/test_cli_sandbox.py +++ b/tests/toolkit/cli/test_cli_sandbox.py @@ -1188,9 +1188,10 @@ class NewResponse: tool_id="tool-new", ) - assert _FakeToolsClient.get_call_count == 1 - assert _FakeToolsClient.get_tool_call_count == 2 + assert _FakeToolsClient.get_call_count == 2 + assert _FakeToolsClient.get_tool_call_count == 3 assert _FakeToolsClient.create_call_count == 1 + assert _FakeToolsClient.list_sessions_call_count == 1 assert _FakeToolsClient.last_get_request.tool_id == "tool-new" assert _FakeToolsClient.last_get_request.session_id == "session-old" assert _FakeToolsClient.last_request.tool_id == "tool-new" @@ -1206,6 +1207,78 @@ class NewResponse: assert result == stored["same-user-session"] +def test_ensure_sandbox_session_syncs_existing_session_after_stale_instance( + monkeypatch, + tmp_path, +) -> None: + import agentkit.toolkit.cli.sandbox.session_create as session_create + + class ExistingResponse: + user_session_id = "same-user-session" + session_id = "session-remote" + endpoint = "https://remote.example.com" + + monkeypatch.setattr( + session_create, + "AgentkitToolsClient", + lambda: _FakeToolsClient(), + ) + store_path = _patch_store_path(monkeypatch, tmp_path) + store_path.write_text( + json.dumps( + { + "same-user-session": { + "session_id": "same-user-session", + "tool_id": "tool-stored", + "instance_id": "session-stale", + "endpoint": "https://stale.example.com", + } + } + ), + encoding="utf-8", + ) + _FakeToolsClient.get_error = Exception("Session not found") + _FakeToolsClient.list_sessions_responses = [ + _FakeListSessionsResponse( + [ + _FakeSessionInfo( + user_session_id="same-user-session", + session_id="session-remote", + endpoint="https://listed.example.com", + ) + ] + ) + ] + + def fake_get_session(_self, request): + _FakeToolsClient.last_get_request = request + _FakeToolsClient.get_call_count += 1 + if request.session_id == "session-stale": + raise Exception("Session not found") + return ExistingResponse() + + monkeypatch.setattr(_FakeToolsClient, "get_session", fake_get_session) + + result = session_create.ensure_sandbox_session( + session_id="same-user-session", + ) + + assert _FakeToolsClient.create_call_count == 0 + assert _FakeToolsClient.list_sessions_call_count == 1 + assert _FakeToolsClient.get_call_count == 2 + assert _FakeToolsClient.last_get_request.tool_id == "tool-stored" + assert _FakeToolsClient.last_get_request.session_id == "session-remote" + assert result == { + "session_id": "same-user-session", + "tool_id": "tool-stored", + "instance_id": "session-remote", + "endpoint": "https://remote.example.com", + } + assert json.loads(store_path.read_text(encoding="utf-8")) == { + "same-user-session": result + } + + def test_cli_get_returns_stored_session(monkeypatch, tmp_path) -> None: from agentkit.toolkit.cli.cli import app import agentkit.toolkit.cli.sandbox.cli_get as cli_get From 8d7ebe790c9cc326d6ebbd531285a9ae01dcdeb3 Mon Sep 17 00:00:00 2001 From: "shijinyu.7" Date: Wed, 17 Jun 2026 14:11:35 +0800 Subject: [PATCH 6/6] update(version): update version to 0.6.2 (cherry picked from commit 6d03b7cd0f053c8d2f3c67e1395c795a1523cdf6) --- agentkit/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/agentkit/version.py b/agentkit/version.py index 0581730..f90a98f 100644 --- a/agentkit/version.py +++ b/agentkit/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = "0.6.1" +VERSION = "0.6.2" diff --git a/pyproject.toml b/pyproject.toml index 0dcd1e3..dfe3a72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agentkit-sdk-python" -version = "0.6.1" +version = "0.6.2" description = "Python SDK for transforming any AI agent into a production-ready application. Framework-agnostic primitives for runtime, memory, authentication, and tools with volcengine-managed infrastructure." readme = "README.md" requires-python = ">=3.10"