Skip to content

Commit aea336a

Browse files
committed
docs: enhance README with comprehensive API examples
Add "Main APIs At A Glance" section showcasing 13 core API groups with both Python and TypeScript examples side-by-side. Covers session config, send/stream, direct tools, delegation, programmatic calling, structured output, runs/replay, verification, HITL, MCP, memory, registries, and persistence. Makes the full SDK surface discoverable upfront. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 71ec109 commit aea336a

1 file changed

Lines changed: 304 additions & 9 deletions

File tree

README.md

Lines changed: 304 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,328 @@ providers "anthropic" {
6161
}
6262
```
6363

64-
Python:
64+
Send a prompt:
6565

6666
```python
6767
from a3s_code import Agent
6868

6969
agent = Agent.create("agent.acl")
7070
session = agent.session("/my-project")
7171

72-
result = session.send({
73-
"prompt": "Find where authentication errors are handled and summarize the flow",
74-
})
72+
result = session.send({"prompt": "Summarize how auth errors are handled."})
7573
print(result.text)
7674
```
7775

78-
Node.js:
79-
8076
```typescript
8177
import { Agent } from '@a3s-lab/code';
8278

8379
const agent = await Agent.create('agent.acl');
8480
const session = agent.session('/my-project');
8581

86-
const result = await session.send({
87-
prompt: 'Find where authentication errors are handled and summarize the flow',
88-
});
82+
const result = await session.send({ prompt: 'Summarize how auth errors are handled.' });
8983
console.log(result.text);
84+
session.close();
85+
```
86+
87+
## Main APIs At A Glance
88+
89+
The same surface area is available from Python and Node. Both are shown below — Node uses `camelCase`, Python uses `snake_case`, and the call shapes match.
90+
91+
```python
92+
from a3s_code import (
93+
Agent,
94+
SessionOptions,
95+
PermissionPolicy,
96+
ConfirmationPolicy,
97+
WorkerAgentSpec,
98+
FileMemoryStore,
99+
FileSessionStore,
100+
HttpTransport,
101+
)
102+
103+
# 1. Configure a session — typed extension options, not raw flags.
104+
opts = SessionOptions()
105+
opts.skill_dirs = ["./skills"]
106+
opts.planning_mode = "auto" # "auto" | "enabled" | "disabled"
107+
opts.permission_policy = PermissionPolicy(
108+
allow=["read(*)", "grep(*)", "glob(*)"],
109+
ask=["bash(*)", "write(*)"],
110+
deny=["bash(rm -rf *)"],
111+
default_decision="ask",
112+
)
113+
opts.confirmation_policy = ConfirmationPolicy(
114+
enabled=True, default_timeout_ms=30_000, timeout_action="reject",
115+
)
116+
opts.memory_store = FileMemoryStore("./memory")
117+
opts.session_store = FileSessionStore("./sessions")
118+
opts.session_id = "my-session"
119+
opts.auto_save = True
120+
opts.ahp_transport = HttpTransport("http://localhost:8080/ahp")
121+
122+
agent = Agent.create("agent.acl")
123+
session = agent.session("/my-project", opts)
124+
125+
# 2. Send / stream — string or object-shaped requests.
126+
result = session.send({"prompt": "Refactor the auth module"})
127+
print(result.text, result.verification_status)
128+
129+
for event in session.stream({"prompt": "Continue the refactor"}):
130+
if event.event_type == "text_delta":
131+
print(event.text, end="", flush=True)
132+
133+
# 3. Direct tools (bypass the LLM).
134+
session.read_file("src/main.py")
135+
session.bash("pytest -q")
136+
session.glob("**/*.py")
137+
session.grep("PermissionPolicy")
138+
session.git({"command": "status"})
139+
session.web_search({"query": "rust async cancellation"})
140+
141+
# 4. Delegation — isolate child context.
142+
session.task({
143+
"agent": "explore",
144+
"description": "Find auth entry points",
145+
"prompt": "Inspect the repo and return a list of auth files with evidence.",
146+
})
147+
session.tasks([
148+
{"agent": "explore", "description": "Find tests", "prompt": "Locate auth tests."},
149+
{"agent": "verification", "description": "Check risk", "prompt": "Review auth edge cases."},
150+
])
151+
152+
# 5. Programmatic tool calling — bounded JS in embedded QuickJS.
153+
session.program({
154+
"source": """
155+
export default async function run(ctx, inputs) {
156+
const hits = await ctx.grep(inputs.query, { glob: '*.py' });
157+
const files = await ctx.glob('src/**/*.py');
158+
return { hits, files: files.slice(0, 10) };
159+
}
160+
""",
161+
"inputs": {"query": "PermissionPolicy"},
162+
"allowed_tools": ["grep", "glob"],
163+
"limits": {"timeoutMs": 30_000, "maxToolCalls": 20, "maxOutputBytes": 65_536},
164+
})
165+
166+
# 6. Structured output — schema-validated JSON from any provider.
167+
session.tool("generate_object", {
168+
"schema": {
169+
"type": "object",
170+
"required": ["sentiment", "confidence"],
171+
"properties": {
172+
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
173+
"confidence": {"type": "number", "minimum": 0, "maximum": 1},
174+
},
175+
},
176+
"prompt": "Classify: 'This product is amazing!'",
177+
"schema_name": "sentiment",
178+
})
179+
180+
# 7. Runs and replay — typed runtime state, not text scraping.
181+
runs = session.runs()
182+
if runs:
183+
last = runs[-1]
184+
session.run_snapshot(last["id"])
185+
session.run_events(last["id"])
186+
session.active_tools()
187+
session.cancel_run(last["id"]) # only cancels if still active
188+
189+
# 8. Verification — completion requires a checked result.
190+
session.verify_commands("auth refactor", [
191+
{"label": "tests", "command": "pytest -q"},
192+
{"label": "lint", "command": "ruff check ."},
193+
])
194+
session.verification_summary_text()
195+
196+
# 9. HITL confirmations — single safety gate.
197+
for pending in session.pending_confirmations():
198+
session.confirm_tool_use(pending["tool_id"], approved=True, reason="Reviewed")
199+
200+
# 10. MCP — attach servers to a live session, tools selected per turn.
201+
session.add_mcp({
202+
"name": "github",
203+
"transport": {
204+
"type": "stdio",
205+
"command": "npx",
206+
"args": ["-y", "@modelcontextprotocol/server-github"],
207+
},
208+
"timeout_ms": 30_000,
209+
})
210+
session.mcps()
211+
session.remove_mcp("github")
212+
213+
# 11. Memory — optional evidence, not auto-stuffing.
214+
session.remember_success("refactor auth", ["edit", "bash"], "all tests passing")
215+
session.recall_similar("auth refactor", limit=5)
216+
session.memory_stats()
217+
218+
# 12. Tools, skills, slash commands, hooks, workers.
219+
session.tool_names()
220+
session.tool_definitions()
221+
session.list_commands()
222+
session.register_command("ping", "Health check", lambda args, ctx: "pong")
223+
session.register_hook("audit", "pre_tool_use", handler_fn)
224+
session.register_worker_agent(
225+
WorkerAgentSpec.verifier("verify-cow", "Run focused checks"),
226+
)
227+
228+
# 13. Persistence and lifecycle.
229+
session.save()
230+
resumed = agent.resume_session("my-session", opts)
231+
session.cancel() # cancels in-flight send/stream
232+
session.close()
233+
```
234+
235+
```typescript
236+
import {
237+
Agent,
238+
SessionOptions,
239+
PermissionPolicy,
240+
ConfirmationPolicy,
241+
WorkerAgentSpec,
242+
FileMemoryStore,
243+
FileSessionStore,
244+
HttpTransport,
245+
} from '@a3s-lab/code';
246+
247+
// 1. Configure a session — typed extension options, not raw flags.
248+
const opts: SessionOptions = {
249+
skillDirs: ['./skills'],
250+
planningMode: 'auto', // "auto" | "enabled" | "disabled"
251+
permissionPolicy: {
252+
allow: ['read(*)', 'grep(*)', 'glob(*)'],
253+
ask: ['bash(*)', 'write(*)'],
254+
deny: ['bash(rm -rf *)'],
255+
defaultDecision: 'ask',
256+
},
257+
confirmationPolicy: {
258+
enabled: true,
259+
defaultTimeoutMs: 30_000,
260+
timeoutAction: 'reject',
261+
},
262+
memoryStore: new FileMemoryStore('./memory'),
263+
sessionStore: new FileSessionStore('./sessions'),
264+
sessionId: 'my-session',
265+
autoSave: true,
266+
ahpTransport: new HttpTransport('http://localhost:8080/ahp'),
267+
};
268+
269+
const agent = await Agent.create('agent.acl');
270+
const session = agent.session('/my-project', opts);
271+
272+
// 2. Send / stream — string or object-shaped requests.
273+
const result = await session.send({ prompt: 'Refactor the auth module' });
274+
console.log(result.text, result.verificationStatus);
275+
276+
const stream = await session.stream({ prompt: 'Continue the refactor' });
277+
for await (const event of stream) {
278+
if (event.eventType === 'text_delta') process.stdout.write(event.text ?? '');
279+
}
280+
281+
// 3. Direct tools (bypass the LLM).
282+
await session.readFile('src/main.ts');
283+
await session.bash('npm test');
284+
await session.glob('**/*.ts');
285+
await session.grep('PermissionPolicy');
286+
await session.git({ command: 'status' });
287+
await session.webSearch({ query: 'rust async cancellation' });
288+
289+
// 4. Delegation — isolate child context.
290+
await session.task({
291+
agent: 'explore',
292+
description: 'Find auth entry points',
293+
prompt: 'Inspect the repo and return a list of auth files with evidence.',
294+
});
295+
await session.tasks([
296+
{ agent: 'explore', description: 'Find tests', prompt: 'Locate auth tests.' },
297+
{ agent: 'verification', description: 'Check risk', prompt: 'Review auth edge cases.' },
298+
]);
299+
300+
// 5. Programmatic tool calling — bounded JS in embedded QuickJS.
301+
await session.program({
302+
source: `
303+
export default async function run(ctx, inputs) {
304+
const hits = await ctx.grep(inputs.query, { glob: '*.ts' });
305+
const files = await ctx.glob('src/**/*.ts');
306+
return { hits, files: files.slice(0, 10) };
307+
}
308+
`,
309+
inputs: { query: 'PermissionPolicy' },
310+
allowedTools: ['grep', 'glob'],
311+
limits: { timeoutMs: 30_000, maxToolCalls: 20, maxOutputBytes: 65_536 },
312+
});
313+
314+
// 6. Structured output — schema-validated JSON from any provider.
315+
await session.tool('generate_object', {
316+
schema: {
317+
type: 'object',
318+
required: ['sentiment', 'confidence'],
319+
properties: {
320+
sentiment: { type: 'string', enum: ['positive', 'negative', 'neutral'] },
321+
confidence: { type: 'number', minimum: 0, maximum: 1 },
322+
},
323+
},
324+
prompt: "Classify: 'This product is amazing!'",
325+
schema_name: 'sentiment',
326+
});
327+
328+
// 7. Runs and replay — typed runtime state, not text scraping.
329+
const runs = await session.runs();
330+
const last = runs?.at(-1);
331+
if (last) {
332+
await session.runSnapshot(last.id);
333+
await session.runEvents(last.id);
334+
await session.activeTools();
335+
await session.cancelRun(last.id); // only cancels if still active
336+
}
337+
338+
// 8. Verification — completion requires a checked result.
339+
await session.verifyCommands('auth refactor', [
340+
{ label: 'tests', command: 'npm test' },
341+
{ label: 'lint', command: 'npm run lint' },
342+
]);
343+
session.verificationSummaryText();
344+
345+
// 9. HITL confirmations — single safety gate.
346+
for (const pending of await session.pendingConfirmations()) {
347+
await session.confirmToolUse(pending.toolId, true, 'Reviewed');
348+
}
349+
350+
// 10. MCP — attach servers to a live session, tools selected per turn.
351+
await session.addMcp({
352+
name: 'github',
353+
transport: {
354+
type: 'stdio',
355+
command: 'npx',
356+
args: ['-y', '@modelcontextprotocol/server-github'],
357+
},
358+
timeoutMs: 30_000,
359+
});
360+
await session.mcps();
361+
await session.removeMcp('github');
362+
363+
// 11. Memory — optional evidence, not auto-stuffing.
364+
await session.rememberSuccess('refactor auth', ['edit', 'bash'], 'all tests passing');
365+
await session.recallSimilar('auth refactor', 5);
366+
await session.memoryStats();
367+
368+
// 12. Tools, skills, slash commands, hooks, workers.
369+
session.toolNames();
370+
session.toolDefinitions();
371+
session.listCommands();
372+
session.registerCommand('ping', 'Health check', (_args, _ctx) => 'pong');
373+
session.registerHook('audit', 'pre_tool_use', { tool: 'bash' }, undefined, (event) => {
374+
return { action: 'continue' };
375+
});
376+
session.registerWorkerAgent({
377+
name: 'verify-cow',
378+
description: 'Run focused checks',
379+
kind: 'verifier',
380+
});
90381

382+
// 13. Persistence and lifecycle.
383+
await session.save();
384+
const resumed = agent.resumeSession('my-session', opts);
385+
session.cancel(); // cancels in-flight send/stream
91386
session.close();
92387
```
93388

0 commit comments

Comments
 (0)