Skip to content

Commit e888350

Browse files
authored
Merge branch 'dev' into refactor/remove-space
2 parents 9e70e34 + e292f38 commit e888350

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3987
-281
lines changed

docs/api-reference/openapi.json

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,68 @@
187187
} ]
188188
}
189189
},
190+
"/agent_skills/{id}/download_to_sandbox" : {
191+
"post" : {
192+
"description" : "Download all files from an agent skill to a sandbox environment. Files are placed at /skills/{skill_name}/.",
193+
"parameters" : [ {
194+
"description" : "Agent skill UUID",
195+
"in" : "path",
196+
"name" : "id",
197+
"required" : true,
198+
"schema" : {
199+
"type" : "string"
200+
}
201+
} ],
202+
"requestBody" : {
203+
"content" : {
204+
"application/json" : {
205+
"schema" : {
206+
"$ref" : "#/components/schemas/handler.DownloadSkillToSandboxReq"
207+
}
208+
}
209+
},
210+
"description" : "Download to sandbox request",
211+
"required" : true
212+
},
213+
"responses" : {
214+
"200" : {
215+
"content" : {
216+
"application/json" : {
217+
"schema" : {
218+
"$ref" : "#/components/schemas/_agent_skills__id__download_to_sandbox_post_200_response"
219+
}
220+
}
221+
},
222+
"description" : "OK"
223+
},
224+
"409" : {
225+
"content" : {
226+
"application/json" : {
227+
"schema" : {
228+
"$ref" : "#/components/schemas/serializer.Response"
229+
}
230+
}
231+
},
232+
"description" : "Skill directory already exists in sandbox"
233+
}
234+
},
235+
"security" : [ {
236+
"BearerAuth" : [ ]
237+
} ],
238+
"summary" : "Download skill to sandbox",
239+
"tags" : [ "agent_skills" ],
240+
"x-code-samples" : [ {
241+
"label" : "Python",
242+
"lang" : "python",
243+
"source" : "from acontext import AcontextClient\n\nclient = AcontextClient(api_key='sk_project_token')\n\n# Download skill to sandbox\nresult = client.skills.download_to_sandbox(\n skill_id='skill-uuid',\n sandbox_id='sandbox-uuid'\n)\nprint(f\"Success: {result.success}\")\nprint(f\"Skill installed at: {result.dir_path}\")\n"
244+
}, {
245+
"label" : "JavaScript",
246+
"lang" : "javascript",
247+
"source" : "import { AcontextClient } from '@acontext/acontext';\n\nconst client = new AcontextClient({ apiKey: 'sk_project_token' });\n\n// Download skill to sandbox\nconst result = await client.skills.downloadToSandbox('skill-uuid', {\n sandboxId: 'sandbox-uuid'\n});\nconsole.log(`Success: ${result.success}`);\nconsole.log(`Skill installed at: ${result.dir_path}`);\n"
248+
} ],
249+
"x-codegen-request-body-name" : "request"
250+
}
251+
},
190252
"/agent_skills/{id}/file" : {
191253
"get" : {
192254
"description" : "Get file content or download URL from agent skill. If the file is text-based (parseable), returns parsed content. Otherwise, returns a presigned download URL.",
@@ -1846,6 +1908,37 @@
18461908
},
18471909
"type" : "object"
18481910
},
1911+
"handler.DownloadSkillToSandboxReq" : {
1912+
"properties" : {
1913+
"sandbox_id" : {
1914+
"description" : "Target sandbox ID",
1915+
"type" : "string"
1916+
}
1917+
},
1918+
"required" : [ "sandbox_id" ],
1919+
"type" : "object"
1920+
},
1921+
"handler.DownloadSkillToSandboxResp" : {
1922+
"properties" : {
1923+
"description" : {
1924+
"description" : "Skill description",
1925+
"type" : "string"
1926+
},
1927+
"dir_path" : {
1928+
"description" : "Full path to the skill directory in sandbox",
1929+
"type" : "string"
1930+
},
1931+
"name" : {
1932+
"description" : "Skill name",
1933+
"type" : "string"
1934+
},
1935+
"success" : {
1936+
"description" : "Whether the download was successful",
1937+
"type" : "boolean"
1938+
}
1939+
},
1940+
"type" : "object"
1941+
},
18491942
"handler.DownloadToSandboxReq" : {
18501943
"properties" : {
18511944
"file_path" : {
@@ -2613,6 +2706,18 @@
26132706
"type" : "object"
26142707
} ]
26152708
},
2709+
"_agent_skills__id__download_to_sandbox_post_200_response" : {
2710+
"allOf" : [ {
2711+
"$ref" : "#/components/schemas/serializer.Response"
2712+
}, {
2713+
"properties" : {
2714+
"data" : {
2715+
"$ref" : "#/components/schemas/handler.DownloadSkillToSandboxResp"
2716+
}
2717+
},
2718+
"type" : "object"
2719+
} ]
2720+
},
26162721
"_agent_skills__id__file_get_200_response" : {
26172722
"allOf" : [ {
26182723
"$ref" : "#/components/schemas/serializer.Response"

docs/chore/async_python.mdx

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Every method is available in async client, just add `await` prefix to the method
2626

2727
## Async Agentic Tools
2828

29-
The [Filesystem Tools](/tool/disk_tools) and [Skill Tools](/tool/skill_tools) also support async operations. Use `async_format_context()` and `async_execute_tool()` methods with `AcontextAsyncClient`.
29+
The [Filesystem Tools](/tool/disk_tools), [Skill Tools](/tool/skill_tools), and [Sandbox Tools](/tool/bash_tools) also support async operations. Use `async_format_context()` and `async_execute_tool()` methods with `AcontextAsyncClient`.
3030

3131
### Async Disk Tools
3232

@@ -132,6 +132,76 @@ while True:
132132
)
133133
```
134134

135+
### Async Sandbox Tools
136+
137+
```python Python
138+
import json
139+
from acontext import AcontextAsyncClient
140+
from acontext.agent.sandbox import SANDBOX_TOOLS
141+
from openai import AsyncOpenAI
142+
143+
# Initialize async clients
144+
acontext_client = AcontextAsyncClient(
145+
api_key=os.getenv("ACONTEXT_API_KEY"),
146+
)
147+
openai_client = AsyncOpenAI()
148+
149+
# Create sandbox and disk
150+
sandbox = await acontext_client.sandboxes.create()
151+
disk = await acontext_client.disks.create()
152+
153+
# Create async sandbox context (optionally mount skills)
154+
ctx = await SANDBOX_TOOLS.async_format_context(
155+
acontext_client,
156+
sandbox_id=sandbox.sandbox_id,
157+
disk_id=disk.id,
158+
# mount_skills=["skill-uuid-1", "skill-uuid-2"]
159+
)
160+
161+
# Get tool schemas for OpenAI
162+
tools = SANDBOX_TOOLS.to_openai_tool_schema()
163+
164+
# Get context prompt to include in system message
165+
context_prompt = ctx.get_context_prompt()
166+
167+
# Async agentic loop
168+
messages = [
169+
{
170+
"role": "system",
171+
"content": f"You are a helpful assistant.\n\n{context_prompt}",
172+
},
173+
{"role": "user", "content": "Create a Python script and run it"}
174+
]
175+
176+
while True:
177+
response = await openai_client.chat.completions.create(
178+
model="gpt-4.1",
179+
messages=messages,
180+
tools=tools,
181+
)
182+
183+
message = response.choices[0].message
184+
messages.append(message)
185+
186+
if not message.tool_calls:
187+
print(f"🤖 Assistant: {message.content}")
188+
break
189+
190+
# Execute each tool call asynchronously
191+
for tool_call in message.tool_calls:
192+
print(f"⚙️ Called {tool_call.function.name}")
193+
result = await SANDBOX_TOOLS.async_execute_tool(
194+
ctx, tool_call.function.name, json.loads(tool_call.function.arguments)
195+
)
196+
print(f"🔍 Result: {result}")
197+
messages.append(
198+
{"role": "tool", "tool_call_id": tool_call.id, "content": result}
199+
)
200+
201+
# Clean up
202+
await acontext_client.sandboxes.kill(sandbox.sandbox_id)
203+
```
204+
135205
<Tip>
136206
The async versions are identical to the sync versions except:
137207
- Use `AcontextAsyncClient` instead of `AcontextClient`

docs/docs.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
"group": "Agent Tools",
4949
"icon": "wand-magic-sparkles",
5050
"pages": [
51-
"tool/disk_tools",
52-
"tool/skill_tools"
51+
"tool/bash_tools",
52+
"tool/disk_tools"
5353
]
5454
},
5555
{
@@ -89,7 +89,8 @@
8989
"pages": [
9090
"chore/per-user",
9191
"chore/async_python",
92-
"chore/badge"
92+
"chore/badge",
93+
"tool/skill_tools"
9394
]
9495
},
9596
{

docs/store/sandbox.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ description: "Execute code in isolated, ephemeral sandbox environments"
66
The Sandbox API provides secure, isolated environments for executing shell commands.
77
Each sandbox is a temporary container that runs independently, perfect for running untrusted code or testing scripts.
88

9-
{/* ## Setup Sandbox for your Agent
9+
## Setup Sandbox for your Agent
1010

11-
<Card title="Agentic Bash Tools" icon="terminal" href="/tool/bash_tools">
12-
Give your agent the ability to execute commands with pre-built tools.
11+
<Card title="Agentic Sandbox Tools" icon="terminal" href="/tool/bash_tools">
12+
Give your agent the ability to execute commands, edit files, and export results with pre-built tools.
1313
</Card>
1414

15-
If you'd like to know the details of Sandbox APIs, please read the following documentation. */}
15+
If you'd like to know the details of Sandbox APIs, please read the following documentation.
1616

1717
## What you'll build
1818

docs/store/skill.mdx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ The Skills API provides storage and management for [Agent Skills](https://agents
77

88
## Setup Skills for your Agent
99

10-
<Card title="Agentic Skill Tools" icon="wand-magic-sparkles" href="/tool/skill_tools">
11-
Enable your agent to access and utilize skills with pre-built tools.
10+
<CardGroup cols={2}>
11+
<Card title="Sandbox with Skills" icon="terminal" href="/tool/bash_tools#mounting-skills-in-sandbox">
12+
Mount skills in a sandbox to execute skill scripts and access skill files.
13+
</Card>
14+
15+
<Card title="Skill Content Tools" icon="wand-magic-sparkles" href="/tool/skill_tools">
16+
Enable your agent to read skill files with pre-built tools. No sandbox required.
1217
</Card>
18+
</CardGroup>
1319

1420
If you'd like to know the details of Skills APIs, please read the following documentation.
1521

0 commit comments

Comments
 (0)