Skip to content

Commit f09df89

Browse files
authored
chore: sync internal 0.6.2 to GitHub (#74)
2 parents ac5de56 + 8d7ebe7 commit f09df89

14 files changed

Lines changed: 584 additions & 154 deletions

agentkit/toolkit/cli/sandbox/README.md

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ python3 -m pip show agentkit-sdk-python
3838

3939
### Create
4040

41-
Create an AgentKit Tool for sandbox sessions. This command prepares the backing
42-
TOS bucket/path, builds a `CreateTool` request, waits until the tool reaches
43-
`Ready`, and prints the created tool ID.
41+
Create an AgentKit Tool for sandbox sessions. This command builds a `CreateTool`
42+
request, waits until the tool reaches `Ready`, and prints the created tool ID.
43+
When `--tos-bucket` is provided, it also prepares the backing TOS bucket/path and
44+
mounts it into sandbox sessions.
4445

4546
```bash
4647
agentkit sandbox create \
@@ -55,14 +56,18 @@ Options:
5556
- `--tool-name`: optional. Tool name. If omitted, the CLI generates a name like
5657
`agentkit-codeenv-<random>`.
5758
- `--tos-bucket`: optional. TOS bucket mounted at `/home/gem`. If omitted, the
58-
CLI uses `TOSService.generate_bucket_name()`, which resolves the configured
59-
default bucket template.
59+
tool is created without TOS mount configuration.
60+
- `--cpu`: optional. Sandbox vCPU count; allowed values are `2`, `4`, `8`, and
61+
`16`. Defaults to `4`. Memory is derived as 2 GiB per vCPU.
6062
- `--model-name`: optional. Injected into the tool as `OPENCODE_MODEL`,
6163
`CODEX_MODEL`, and `ANTHROPIC_MODEL`.
6264
- `--model-api-key`: optional. Injected into the tool as `OPENCODE_API_KEY`,
6365
`CODEX_API_KEY`, and `ANTHROPIC_AUTH_TOKEN`. If omitted, the CLI uses
6466
`MODEL_API_KEY` when that environment variable is set.
6567

68+
The sandbox create request maps `--cpu` to `CpuMilli=<cpu * 1000>` and
69+
`MemoryMb=<cpu * 2048>`, so the default shape is 4 vCPU / 8 GiB.
70+
6671
The tool always injects Volcengine Ark compatible endpoints into
6772
`OPENCODE_BASE_URL`, `CODEX_BASE_URL`, `MODEL_BASE_URL`, and
6873
`ANTHROPIC_BASE_URL`. Custom `--model-base-url` is intentionally not exposed.
@@ -73,22 +78,25 @@ TOS credentials. The command supports the same credential sources as the shared
7378
Volcengine configuration, including environment variables and global
7479
`agentkit config --global` settings.
7580

76-
The generated tool TOS mount uses:
81+
When `--tos-bucket` is set, the generated tool TOS mount uses:
7782

7883
```text
7984
BucketPath: /sandbox-session/default/default
8085
LocalMountPath: /home/gem
8186
Endpoint: http://tos-<region>.ivolces.com
8287
```
8388

84-
When `sandbox exec` or `sandbox shell` later creates a session from this tool,
85-
the session flow calls `GetTool`, reads this mount configuration, and mounts a
86-
per-session path:
89+
When `sandbox exec` or `sandbox shell` later creates a session from a tool with
90+
TOS configuration, the session flow calls `GetTool`, reads this mount
91+
configuration, and mounts a per-session path:
8792

8893
```text
8994
/sandbox-session/tool-<tool-id>/session-<session-id>/
9095
```
9196

97+
If the tool was created without `--tos-bucket`, `GetTool` has no TOS mount
98+
configuration and session creation skips TOS mounting.
99+
92100
After the tool reaches `Ready`, `agentkit sandbox create` writes the tool
93101
information to `.agentkit/sandbox/tools.json`. Only one tool record is stored
94102
per `ToolType`; creating or resolving another tool of the same type replaces
@@ -106,7 +114,7 @@ agentkit sandbox get
106114

107115
Options:
108116

109-
- `--session-id` / `--sid`: optional. Sandbox session ID to look up. If omitted, the CLI
117+
- `--session-id` / `--sid` / `-s`: optional. Sandbox session ID to look up. If omitted, the CLI
110118
returns all records from `.agentkit/sandbox/sessions.json` after syncing the
111119
current tool.
112120
- `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is
@@ -142,7 +150,7 @@ only operate on existing sessions; they do not create a session when
142150

143151
Common options:
144152

145-
- `--session-id` / `--sid`: required. Sandbox session ID to operate on.
153+
- `--session-id` / `--sid` / `-s`: required. Sandbox session ID to operate on.
146154
- `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is
147155
set, the CLI resolves an existing tool by `--tool-type`.
148156
- `--tool-type`: optional. `CodeEnv` or `SkillEnv`; defaults to `CodeEnv`.
@@ -270,7 +278,7 @@ agentkit sandbox shell \
270278

271279
Options:
272280

273-
- `--session-id` / `--sid`: optional. Sandbox session ID used as the local session key.
281+
- `--session-id` / `--sid` / `-s`: optional. Sandbox session ID used as the local session key.
274282
If omitted, a UUID is generated and the command creates a sandbox session
275283
through the same idempotent session ensure flow as `sandbox exec`.
276284
- `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is
@@ -317,7 +325,7 @@ agentkit sandbox web --session-id 123456789 --tool-id t-example
317325

318326
Options:
319327

320-
- `--session-id` / `--sid`: required. Sandbox session ID to open in a browser.
328+
- `--session-id` / `--sid` / `-s`: required. Sandbox session ID to open in a browser.
321329
- `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. The
322330
underscore alias `--tool_id` is also accepted.
323331

@@ -351,7 +359,7 @@ agentkit sandbox exec --session-id 123456789 --src-dir ./README.md ./requirement
351359

352360
Options:
353361

354-
- `--session-id` / `--sid`: optional. Sandbox session ID used as the local
362+
- `--session-id` / `--sid` / `-s`: optional. Sandbox session ID used as the local
355363
session key. If omitted, a UUID is generated and the command creates a
356364
sandbox session through the same idempotent session ensure flow.
357365
- `--tool-id`: optional. Defaults to `AGENTKIT_SANDBOX_TOOL_ID`. If neither is

agentkit/toolkit/cli/sandbox/cli_create.py

Lines changed: 55 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
from __future__ import annotations
1818

19-
import json
2019
import os
2120
import re
2221
import time
@@ -26,10 +25,21 @@
2625

2726
from agentkit.sdk.tools.client import AgentkitToolsClient
2827
from agentkit.sdk.tools import types as tools_types
29-
from agentkit.toolkit.cli.sandbox.session_create import (
28+
from agentkit.toolkit.cli.sandbox.model_config import (
29+
ANTHROPIC_BASE_URL_ENV_KEYS,
30+
CODE_ENV_CODEX_HOME,
31+
CODE_ENV_HOME,
32+
CODEX_CONFIG_TOML_ENV,
33+
CODEX_MODEL_CATALOG_JSON_ENV,
34+
DEFAULT_ANTHROPIC_BASE_URL,
35+
DEFAULT_MODEL_BASE_URL,
36+
DEFAULT_MODEL_NAME,
3037
MODEL_API_KEY_ENV,
3138
MODEL_API_KEY_ENV_KEYS,
39+
MODEL_BASE_URL_ENV_KEYS,
3240
MODEL_NAME_ENV_KEYS,
41+
build_codex_config_toml as _shared_build_codex_config_toml,
42+
build_codex_model_catalog_json as _shared_build_codex_model_catalog_json,
3343
)
3444
from agentkit.toolkit.cli.sandbox.tool_resolve import save_tool_result
3545
from agentkit.toolkit.cli.sandbox.utils import error
@@ -44,29 +54,11 @@
4454
SANDBOX_REGION_ENV = "AGENTKIT_SANDBOX_REGION"
4555
SANDBOX_TOS_REGION_ENV = "AGENTKIT_SANDBOX_TOS_REGION"
4656
DEFAULT_CREATE_TOOL_TYPE = "CodeEnv"
57+
DEFAULT_CPU = 4
58+
VALID_CPU_VALUES = (2, 4, 8, 16)
59+
MEMORY_MB_PER_CPU = 2048
4760
DEFAULT_TOS_BUCKET_PATH = "/sandbox-session/default/default"
4861
DEFAULT_TOS_LOCAL_PATH = "/home/gem"
49-
CODE_ENV_HOME = "/home/gem"
50-
CODE_ENV_CODEX_HOME = "/home/gem/.codex"
51-
CODEX_MODEL_CATALOG_PATH = f"{CODE_ENV_CODEX_HOME}/model-catalog.json"
52-
DEFAULT_MODEL_NAME = "deepseek-v4-flash-260425"
53-
DEFAULT_MODEL_NAME_LIST = (
54-
DEFAULT_MODEL_NAME,
55-
"deepseek-v4-pro-260425",
56-
"doubao-seed-2-0-pro-260215",
57-
)
58-
DEFAULT_MODEL_CONTEXT_WINDOW = 1000000
59-
MODEL_CONTEXT_WINDOW_OVERRIDES = {
60-
"doubao-seed-2-0-pro-260215": 256000,
61-
}
62-
DEFAULT_MODEL_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"
63-
DEFAULT_ANTHROPIC_BASE_URL = "https://ark.cn-beijing.volces.com/api/compatible"
64-
MODEL_BASE_URL_ENV_KEYS = (
65-
"OPENCODE_BASE_URL",
66-
"CODEX_BASE_URL",
67-
"MODEL_BASE_URL",
68-
)
69-
ANTHROPIC_BASE_URL_ENV_KEYS = ("ANTHROPIC_BASE_URL",)
7062
DISABLED_SERVICE_ENV_KEYS = (
7163
"DISABLE_JUPYTER",
7264
"DISABLE_CODE_SERVER",
@@ -94,9 +86,21 @@ def _generate_tool_name(tool_type: str) -> str:
9486

9587
def _resolve_tos_bucket(tos_bucket: Optional[str]) -> str:
9688
resolved_bucket = (tos_bucket or "").strip()
97-
if resolved_bucket:
98-
return resolved_bucket
99-
return TOSService.generate_bucket_name()
89+
if not resolved_bucket:
90+
error("--tos-bucket must not be empty")
91+
return resolved_bucket
92+
93+
94+
def _validate_cpu(value: int) -> int:
95+
if value not in VALID_CPU_VALUES:
96+
allowed = ", ".join(str(item) for item in VALID_CPU_VALUES)
97+
raise typer.BadParameter(f"--cpu must be one of: {allowed}")
98+
return value
99+
100+
101+
def _cpu_to_resource_shape(cpu: int) -> tuple[int, int]:
102+
resolved_cpu = _validate_cpu(cpu)
103+
return resolved_cpu * 1000, resolved_cpu * MEMORY_MB_PER_CPU
100104

101105

102106
def _append_tool_envs(
@@ -114,94 +118,12 @@ def _append_tool_envs(
114118
)
115119

116120

117-
def _toml_quote(value: str) -> str:
118-
return json.dumps(value, ensure_ascii=False)
119-
120-
121121
def _build_codex_config_toml(model_name: str) -> str:
122-
quoted_model = _toml_quote(model_name)
123-
return "\n".join(
124-
[
125-
'model_provider = "codex"',
126-
f"model = {quoted_model}",
127-
f"review_model = {quoted_model}",
128-
'approval_policy = "never"',
129-
'sandbox_mode = "danger-full-access"',
130-
'model_reasoning_effort = "medium"',
131-
'personality = "pragmatic"',
132-
"check_for_update_on_startup = false",
133-
'web_search = "disabled"',
134-
f"model_catalog_json = {_toml_quote(CODEX_MODEL_CATALOG_PATH)}",
135-
"",
136-
"[model_providers.codex]",
137-
'name = "codex"',
138-
f"base_url = {_toml_quote(DEFAULT_MODEL_BASE_URL)}",
139-
'wire_api = "responses"',
140-
'env_key = "CODEX_API_KEY"',
141-
"",
142-
"[tui]",
143-
"show_tooltips = false",
144-
"",
145-
'[projects."/home/gem"]',
146-
'trust_level = "trusted"',
147-
"",
148-
]
149-
)
150-
151-
152-
def _build_model_catalog_item(model_name: str, max_context_window: int) -> dict:
153-
return {
154-
"slug": model_name,
155-
"display_name": model_name,
156-
"supported_reasoning_levels": [
157-
{
158-
"effort": "low",
159-
"description": "Fast responses with lighter reasoning",
160-
},
161-
{
162-
"effort": "medium",
163-
"description": "Balances speed and reasoning depth",
164-
},
165-
{
166-
"effort": "high",
167-
"description": "Greater reasoning depth",
168-
},
169-
],
170-
"max_context_window": max_context_window,
171-
"shell_type": "shell_command",
172-
"visibility": "list",
173-
"supported_in_api": True,
174-
"priority": 100,
175-
"base_instructions": "",
176-
"supports_reasoning_summaries": True,
177-
"support_verbosity": False,
178-
"truncation_policy": {"mode": "tokens", "limit": 10000},
179-
"supports_parallel_tool_calls": False,
180-
"experimental_supported_tools": [],
181-
}
182-
183-
184-
def _model_catalog_context_window(model_name: str) -> int:
185-
return MODEL_CONTEXT_WINDOW_OVERRIDES.get(
186-
model_name,
187-
DEFAULT_MODEL_CONTEXT_WINDOW,
188-
)
122+
return _shared_build_codex_config_toml(model_name)
189123

190124

191125
def _build_codex_model_catalog_json(model_name: str) -> str:
192-
deduped_model_names = list(
193-
dict.fromkeys((model_name, *DEFAULT_MODEL_NAME_LIST))
194-
)
195-
payload = {
196-
"models": [
197-
_build_model_catalog_item(
198-
name,
199-
_model_catalog_context_window(name),
200-
)
201-
for name in deduped_model_names
202-
]
203-
}
204-
return json.dumps(payload, ensure_ascii=False, indent=2)
126+
return _shared_build_codex_model_catalog_json(model_name)
205127

206128

207129
def _append_code_env_tool_envs(
@@ -223,11 +145,11 @@ def _append_code_env_tool_envs(
223145
Value=CODE_ENV_CODEX_HOME,
224146
),
225147
tools_types.EnvsItemForCreateTool(
226-
Key="CODEX_CONFIG_TOML",
148+
Key=CODEX_CONFIG_TOML_ENV,
227149
Value=_build_codex_config_toml(model_name),
228150
),
229151
tools_types.EnvsItemForCreateTool(
230-
Key="CODEX_MODEL_CATALOG_JSON",
152+
Key=CODEX_MODEL_CATALOG_JSON_ENV,
231153
Value=_build_codex_model_catalog_json(model_name),
232154
),
233155
]
@@ -267,16 +189,20 @@ def _build_create_tool_request(
267189
name: Optional[str],
268190
tos_bucket: Optional[str],
269191
tos_region: str,
192+
cpu: int = DEFAULT_CPU,
270193
model_name: Optional[str] = None,
271194
model_api_key: Optional[str] = None,
272195
) -> tools_types.CreateToolRequest:
273196
resolved_tool_type = tool_type.strip() or DEFAULT_CREATE_TOOL_TYPE
274197
resolved_name = (name or "").strip() or _generate_tool_name(resolved_tool_type)
275198
tos_mount_config = _build_tos_mount_config(tos_bucket, tos_region)
199+
cpu_milli, memory_mb = _cpu_to_resource_shape(cpu)
276200

277201
return tools_types.CreateToolRequest(
278202
Name=resolved_name,
279203
ToolType=resolved_tool_type,
204+
CpuMilli=cpu_milli,
205+
MemoryMb=memory_mb,
280206
AuthorizerConfiguration=tools_types.AuthorizerForCreateTool(
281207
KeyAuth=tools_types.AuthorizerKeyAuthForCreateTool(
282208
ApiKeyName=generate_apikey_name(),
@@ -299,7 +225,10 @@ def _build_create_tool_request(
299225
def _build_tos_mount_config(
300226
tos_bucket: Optional[str],
301227
region: str,
302-
) -> tools_types.TosMountForCreateTool:
228+
) -> tools_types.TosMountForCreateTool | None:
229+
if not (tos_bucket or "").strip():
230+
return None
231+
303232
resolved_bucket = _resolve_tos_bucket(tos_bucket)
304233
service = TOSService(
305234
TOSServiceConfig(
@@ -397,6 +326,7 @@ def create_tool(
397326
tool_type: str = DEFAULT_CREATE_TOOL_TYPE,
398327
tool_name: Optional[str] = None,
399328
tos_bucket: Optional[str] = None,
329+
cpu: int = DEFAULT_CPU,
400330
model_name: Optional[str] = None,
401331
model_api_key: Optional[str] = None,
402332
) -> dict[str, object]:
@@ -407,6 +337,7 @@ def create_tool(
407337
name=tool_name,
408338
tos_bucket=tos_bucket,
409339
tos_region=tos_region,
340+
cpu=cpu,
410341
model_name=model_name,
411342
model_api_key=model_api_key,
412343
)
@@ -440,7 +371,16 @@ def create_command(
440371
tos_bucket: Optional[str] = typer.Option(
441372
None,
442373
"--tos-bucket",
443-
help="TOS bucket to mount at /home/gem.",
374+
help=(
375+
"TOS bucket to mount at /home/gem. "
376+
"Omit to create the tool without a TOS mount."
377+
),
378+
),
379+
cpu: int = typer.Option(
380+
DEFAULT_CPU,
381+
"--cpu",
382+
help="Sandbox vCPU count. Allowed values: 2, 4, 8, 16.",
383+
callback=_validate_cpu,
444384
),
445385
model_name: Optional[str] = typer.Option(
446386
None,
@@ -465,6 +405,7 @@ def create_command(
465405
tool_type=tool_type,
466406
tool_name=tool_name,
467407
tos_bucket=tos_bucket,
408+
cpu=cpu,
468409
model_name=model_name,
469410
model_api_key=model_api_key,
470411
)

0 commit comments

Comments
 (0)