@@ -61,33 +61,328 @@ providers "anthropic" {
6161}
6262```
6363
64- Python :
64+ Send a prompt :
6565
6666``` python
6767from a3s_code import Agent
6868
6969agent = Agent.create(" agent.acl" )
7070session = 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." })
7573print (result.text)
7674```
7775
78- Node.js:
79-
8076``` typescript
8177import { Agent } from ' @a3s-lab/code' ;
8278
8379const agent = await Agent .create (' agent.acl' );
8480const 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.' });
8983console .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
91386session .close ();
92387```
93388
0 commit comments