@a3s-lab/code 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +61 -40
  2. package/index.d.ts +49 -158
  3. package/index.js +1 -5
  4. package/package.json +8 -11
package/README.md CHANGED
@@ -24,62 +24,83 @@ async function main() {
24
24
  main().catch(console.error)
25
25
  ```
26
26
 
27
- ## Tool Metadata Helpers
27
+ ## Programmatic Tool Calling
28
28
 
29
- `session.tool(...)` returns a `ToolResult` enriched with parsed metadata helpers.
30
-
31
- ### Agentic Parse LLM Blocks
32
-
33
- When `agentic_parse` runs with a query, the SDK exposes the exact structured
34
- document blocks selected for the LLM input.
29
+ `session.program(...)` runs a bounded JavaScript script in the embedded QuickJS
30
+ runtime. It is the SDK-friendly wrapper around the core `program` tool.
35
31
 
36
32
  ```js
37
- const tool = await session.tool('agentic_parse', {
38
- path: 'docs/scanned.pdf',
39
- query: 'overview',
33
+ const result = await session.program({
34
+ source: `
35
+ export default async function run(ctx, inputs) {
36
+ const hits = await ctx.grep(inputs.query, { glob: '*.ts' })
37
+ const files = await ctx.glob('src/**/*.ts')
38
+ return { hits, files: files.slice(0, 10) }
39
+ }
40
+ `,
41
+ inputs: { query: 'PermissionPolicy' },
42
+ allowedTools: ['grep', 'glob'],
43
+ limits: { timeoutMs: 30000, maxToolCalls: 20, maxOutputBytes: 65536 },
40
44
  })
41
45
 
42
- for (const block of tool.agenticParseLlmBlocks ?? []) {
43
- console.log(block.index, block.kind, block.label, block.location?.display)
44
- }
46
+ console.log(result.output)
45
47
  ```
46
48
 
47
- ### Agentic Search Match Locators
49
+ Omit `allowedTools` to allow every registered session tool except `program`.
50
+ Scripts can also be loaded from workspace-relative `.js` or `.mjs` files with
51
+ `{ path: 'scripts/ptc/search.js' }`.
48
52
 
49
- `agentic_search` results expose typed match metadata, including page / section
50
- locators derived from `CompositeDocumentParser` blocks.
53
+ ## Planning Events
51
54
 
52
- ```js
53
- const search = await session.tool('agentic_search', {
54
- query: 'overview',
55
- mode: 'fast',
56
- })
55
+ Planning is automatic by default. Prefer the explicit tri-state
56
+ `planningMode` contract for SDK callers:
57
57
 
58
- for (const result of search.agenticSearchResults ?? []) {
59
- for (const match of result.matches ?? []) {
60
- console.log(match.lineNumber, match.locator, match.content)
61
- }
62
- }
58
+ ```js
59
+ agent.session('/my-project', { planningMode: 'auto' }) // default
60
+ agent.session('/my-project', { planningMode: 'enabled' }) // force planning
61
+ agent.session('/my-project', { planningMode: 'disabled' }) // explicitly off
63
62
  ```
64
63
 
65
- Deep search also exposes `sampledLines` with `locator`, `distance`, and `weight`.
64
+ The legacy boolean shortcut still works: `{ planning: true }` forces planning
65
+ and `{ planning: false }` disables it.
66
+
67
+ When streaming, `task_updated` is the authoritative task-list snapshot for UI
68
+ rendering. `planning_end` contains the initial plan, while `step_start` and
69
+ `step_end` are fine-grained progress events.
70
+
71
+ ## Delegation And Tool Introspection
72
+
73
+ The SDK exposes the core `task` / `parallel_task` tools as direct helpers:
66
74
 
67
75
  ```js
68
- const deep = await session.tool('agentic_search', {
69
- query: 'overview',
70
- mode: 'deep',
76
+ await session.delegateTask({
77
+ agent: 'explore',
78
+ description: 'Find auth entry points',
79
+ prompt: 'Inspect the repository and summarize the auth-related files.',
71
80
  })
72
81
 
73
- for (const result of deep.agenticSearchResults ?? []) {
74
- for (const sampled of result.sampledLines ?? []) {
75
- console.log(sampled.lineNumber, sampled.locator, sampled.distance, sampled.weight)
76
- }
77
- }
82
+ await session.parallelTask([
83
+ { agent: 'explore', description: 'Find tests', prompt: 'Locate auth tests.' },
84
+ { agent: 'verification', description: 'Check risk', prompt: 'Review auth edge cases.' },
85
+ ])
78
86
  ```
79
87
 
80
- ## Examples
88
+ Use `session.toolNames()` for names and `session.toolDefinitions()` when a UI
89
+ needs the full model-visible schemas.
90
+
91
+ ## Run Replay
92
+
93
+ Each `send(...)` or `stream(...)` call records a run snapshot and replayable
94
+ runtime events:
95
+
96
+ ```js
97
+ await session.send('Fix the failing test')
98
+
99
+ const [run] = await session.runs()
100
+ console.log(run.id, run.status)
101
+ console.log(await session.runEvents(run.id))
102
+ ```
81
103
 
82
- - `examples/test-agentic-parse-llm-blocks.js`
83
- - `examples/test-agentic-search-locators.js`
84
- - `examples/test-agentic-search-sampled-lines.js`
85
- - `examples/test-agentic-search-sdk.js`
104
+ Use `session.currentRun()` while a stream is active to inspect the current run.
105
+ Use `session.cancelRun(run.id)` to cancel only that run; stale IDs will not
106
+ cancel a newer operation.
package/index.d.ts CHANGED
@@ -108,6 +108,28 @@ export interface ToolResult {
108
108
  /** Convenience JSON view of `metadata.document_runtime` when present. */
109
109
  documentRuntimeJson?: string
110
110
  }
111
+ /** Execution limits for `Session.program`. */
112
+ export interface ProgramScriptLimits {
113
+ timeoutMs?: number
114
+ maxToolCalls?: number
115
+ maxOutputBytes?: number
116
+ }
117
+ /** Options for `Session.program`. */
118
+ export interface ProgramScriptOptions {
119
+ source?: string
120
+ path?: string
121
+ inputs?: any
122
+ allowedTools?: Array<string>
123
+ limits?: ProgramScriptLimits
124
+ }
125
+ /** Options for `Session.delegateTask`. */
126
+ export interface DelegateTaskOptions {
127
+ agent: string
128
+ description: string
129
+ prompt: string
130
+ background?: boolean
131
+ maxSteps?: number
132
+ }
111
133
  /** Parameters for the web_search tool. */
112
134
  export interface JsWebSearchParams {
113
135
  /** The search query. */
@@ -153,20 +175,6 @@ export interface JsSessionStore {
153
175
  export interface JsSecurityProvider {
154
176
  kind: string
155
177
  }
156
- /**
157
- * A plugin descriptor passed in `SessionOptions.plugins`.
158
- *
159
- * Use `new SkillPlugin(...)` to create plugin instances — do not construct
160
- * this object directly.
161
- */
162
- export interface JsPlugin {
163
- /** Plugin kind: currently only `"skill_plugin"`. */
164
- kind: string
165
- /** Plugin name (used by SkillPlugin). */
166
- pluginName?: string
167
- /** Skill YAML/markdown content strings (used by SkillPlugin). */
168
- skills?: Array<string>
169
- }
170
178
  /**
171
179
  * Union type for AHP transport configuration.
172
180
  * Accepts any of: StdioTransport, HttpTransport, WebSocketTransport, UnixSocketTransport.
@@ -194,7 +202,7 @@ export interface PermissionPolicy {
194
202
  export interface SessionOptions {
195
203
  /** Override the default model. Format: "provider/model" (e.g., "openai/gpt-4o"). */
196
204
  model?: string
197
- /** Enable built-in skills (7 skills: code-search, code-review, explain-code, find-bugs, builtin-tools, delegate-task, find-skills). */
205
+ /** Enable built-in skills (4 skills: code-search, code-review, explain-code, find-bugs). */
198
206
  builtinSkills?: boolean
199
207
  /** Extra directories to scan for skill files (.md with YAML frontmatter). */
200
208
  skillDirs?: Array<string>
@@ -208,7 +216,14 @@ export interface SessionOptions {
208
216
  queueConfig?: SessionQueueConfig
209
217
  /** Explicit permission policy for tool execution. */
210
218
  permissionPolicy?: PermissionPolicy
211
- /** Enable planning mode (default: false). */
219
+ /**
220
+ * Explicit planning mode: "auto", "enabled", or "disabled".
221
+ *
222
+ * Prefer this over `planning` when the caller needs an unambiguous SDK contract.
223
+ * If both are set, `planningMode` wins.
224
+ */
225
+ planningMode?: string
226
+ /** Legacy planning shortcut. Omit for auto planning, true to force planning, false to disable. */
212
227
  planning?: boolean
213
228
  /** Enable goal tracking (default: false). */
214
229
  goalTracking?: boolean
@@ -255,12 +270,6 @@ export interface SessionOptions {
255
270
  * ```
256
271
  */
257
272
  securityProvider?: JsSecurityProvider
258
- /**
259
- * Plugins to mount onto this session.
260
- *
261
- * Pass instances such as `new SkillPlugin(...)` to inject custom skills.
262
- */
263
- plugins?: Array<JsPlugin>
264
273
  /**
265
274
  * Custom role/identity prepended before the core agentic prompt.
266
275
  * Example: "You are a senior Python developer specializing in FastAPI."
@@ -525,55 +534,6 @@ export interface SearchConfig {
525
534
  engines: Record<string, SearchEngineConfig>
526
535
  headless?: HeadlessConfig
527
536
  }
528
- /** SubAgent configuration for the advanced orchestrator control plane. */
529
- export interface SubAgentConfig {
530
- /** Agent type (general, explore, plan, etc.) */
531
- agentType: string
532
- /** Task description */
533
- description: string
534
- /** Execution prompt */
535
- prompt: string
536
- /** Maximum execution steps */
537
- maxSteps?: number
538
- /** Execution timeout (milliseconds) */
539
- timeoutMs?: number
540
- /** Parent SubAgent ID (for nesting) */
541
- parentId?: string
542
- /** Workspace directory for the SubAgent (defaults to ".") */
543
- workspace?: string
544
- /** Extra directories to scan for agent definition files */
545
- agentDirs?: Array<string>
546
- /** Extra directories to scan for skill definition files */
547
- skillDirs?: Array<string>
548
- }
549
- /** SubAgent activity type */
550
- export interface SubAgentActivity {
551
- /** Activity type: idle, calling_tool, requesting_llm, waiting_for_control */
552
- activityType: string
553
- /** Activity data (JSON string) */
554
- data?: string
555
- }
556
- /** SubAgent information with metadata and current activity */
557
- export interface SubAgentInfo {
558
- id: string
559
- agentType: string
560
- description: string
561
- state: string
562
- parentId?: string
563
- createdAt: number
564
- updatedAt: number
565
- currentActivity?: SubAgentActivity
566
- }
567
- /** SubAgent activity entry (id + activity) */
568
- export interface SubAgentActivityEntry {
569
- id: string
570
- activity: SubAgentActivity
571
- }
572
- /** SubAgent state entry (id + state) */
573
- export interface SubAgentStateEntry {
574
- id: string
575
- state: string
576
- }
577
537
  /** Streaming event iterator. Use `for await (const event of stream)` or call `.next()` manually. */
578
538
  export declare class EventStream {
579
539
  /**
@@ -638,35 +598,6 @@ export declare class DefaultSecurityProvider {
638
598
  kind: string
639
599
  constructor()
640
600
  }
641
- /**
642
- * Skill-only plugin — injects custom skills into the session's skill registry
643
- * without registering any tools.
644
- *
645
- * Use this to add custom LLM guidance (instructions, tool restrictions,
646
- * prompting strategies) directly from Node.js. For tools, use MCP servers.
647
- *
648
- * ```js
649
- * import { SkillPlugin } from '@a3s-lab/code';
650
- *
651
- * const plugin = new SkillPlugin('my-plugin', [`
652
- * ---
653
- * name: my-skill
654
- * description: Use bash cautiously
655
- * allowed-tools: "bash(*)"
656
- * kind: instruction
657
- * ---
658
- * Always explain what command you're about to run before executing it.
659
- * `]);
660
- *
661
- * agent.session('.', { plugins: [plugin] });
662
- * ```
663
- */
664
- export declare class SkillPlugin {
665
- kind: string
666
- pluginName?: string
667
- skills?: Array<string>
668
- constructor(name: string, skills: Array<string>)
669
- }
670
601
  /**
671
602
  * Stdio transport for AHP (Agent Harness Protocol).
672
603
  *
@@ -857,8 +788,24 @@ export declare class Session {
857
788
  streamWithAttachments(prompt: string, attachments: Array<AttachmentObject>, history?: Array<MessageObject> | undefined | null): Promise<EventStream>
858
789
  /** Return the session's conversation history. */
859
790
  history(): Array<MessageObject>
791
+ /** Return run snapshots recorded by this session. */
792
+ runs(): Promise<any>
793
+ /** Return a run snapshot by ID, or null when it is unknown. */
794
+ runSnapshot(runId: string): Promise<any>
795
+ /** Return recorded runtime events for a run. */
796
+ runEvents(runId: string): Promise<any>
797
+ /** Return the currently running operation, or null when idle. */
798
+ currentRun(): Promise<any>
799
+ /** Cancel a specific run only if it is still the active run. */
800
+ cancelRun(runId: string): Promise<boolean>
860
801
  /** Execute a tool by name, bypassing the LLM. */
861
802
  tool(name: string, args: any): Promise<ToolResult>
803
+ /** Delegate a bounded task to a child agent through the built-in `task` tool. */
804
+ delegateTask(options: DelegateTaskOptions): Promise<ToolResult>
805
+ /** Execute several delegated child-agent tasks concurrently through `parallel_task`. */
806
+ parallelTask(tasks: DelegateTaskOptions[]): Promise<ToolResult>
807
+ /** Run a bounded JavaScript script through the embedded QuickJS `program` tool. */
808
+ program(options: ProgramScriptOptions): Promise<ToolResult>
862
809
  /** Read a file from the workspace. */
863
810
  readFile(path: string): Promise<string>
864
811
  /** Execute a bash command in the workspace. */
@@ -961,6 +908,8 @@ export declare class Session {
961
908
  * @returns Array of tool name strings
962
909
  */
963
910
  toolNames(): Array<string>
911
+ /** Return full model-visible tool definitions currently registered on this session. */
912
+ toolDefinitions(): any
964
913
  /**
965
914
  * Register a hook for lifecycle event interception.
966
915
  *
@@ -1121,61 +1070,3 @@ export declare class Session {
1121
1070
  */
1122
1071
  close(): void
1123
1072
  }
1124
- /** SubAgent handle for control and monitoring. */
1125
- export declare class SubAgentHandle {
1126
- /** Get SubAgent ID */
1127
- get id(): string
1128
- /** Get current state (non-blocking) */
1129
- state(): string
1130
- /** Get current activity */
1131
- activity(): SubAgentActivity
1132
- /** Pause execution */
1133
- pause(): void
1134
- /** Resume execution */
1135
- resume(): void
1136
- /** Cancel execution */
1137
- cancel(): void
1138
- /** Wait for completion and get result */
1139
- wait(): string
1140
- /** Subscribe to sub-agent events. */
1141
- events(): SubAgentEventStream
1142
- }
1143
- /** SubAgent event stream for monitoring sub-agent events. */
1144
- export declare class SubAgentEventStream {
1145
- /** Receive the next sub-agent event, or `null` on timeout / end-of-stream. */
1146
- recv(timeoutMs?: number | undefined | null): Promise<any | null>
1147
- }
1148
- /**
1149
- * Advanced orchestrator for explicit SubAgent lifecycle control.
1150
- *
1151
- * Routine multi-agent work should use `task` / `parallelTask` delegation; this
1152
- * API is for monitoring and controlling long-running SubAgents directly.
1153
- */
1154
- export declare class Orchestrator {
1155
- /**
1156
- * Create a new orchestrator.
1157
- *
1158
- * @param agent - `Agent` instance used to execute spawned SubAgents.
1159
- */
1160
- static create(agent: Agent): Orchestrator
1161
- /** Spawn a new SubAgent */
1162
- spawnSubagent(config: SubAgentConfig): SubAgentHandle
1163
- /** Get active SubAgent count */
1164
- activeCount(): number
1165
- /** Get all SubAgent information list */
1166
- listSubagents(): Array<SubAgentInfo>
1167
- /** Get specific SubAgent information */
1168
- getSubagentInfo(id: string): SubAgentInfo | null
1169
- /** Get all active SubAgent activities */
1170
- getActiveActivities(): Array<SubAgentActivityEntry>
1171
- /** Get all SubAgent states */
1172
- getAllStates(): Array<SubAgentStateEntry>
1173
- /** Pause a SubAgent */
1174
- pauseSubagent(id: string): void
1175
- /** Resume a SubAgent */
1176
- resumeSubagent(id: string): void
1177
- /** Cancel a SubAgent */
1178
- cancelSubagent(id: string): void
1179
- /** Wait for all SubAgents to complete */
1180
- waitAll(): void
1181
- }
package/index.js CHANGED
@@ -310,7 +310,7 @@ if (!nativeBinding) {
310
310
  throw new Error(`Failed to load native binding`)
311
311
  }
312
312
 
313
- const { formatVerificationSummary, EventStream, FileMemoryStore, FileSessionStore, MemorySessionStore, DefaultSecurityProvider, SkillPlugin, StdioTransport, HttpTransport, WebSocketTransport, UnixSocketTransport, Agent, Session, builtinSkills, BrowserBackend, SubAgentHandle, SubAgentEventStream, Orchestrator } = nativeBinding
313
+ const { formatVerificationSummary, EventStream, FileMemoryStore, FileSessionStore, MemorySessionStore, DefaultSecurityProvider, StdioTransport, HttpTransport, WebSocketTransport, UnixSocketTransport, Agent, Session, builtinSkills, BrowserBackend } = nativeBinding
314
314
 
315
315
  module.exports.formatVerificationSummary = formatVerificationSummary
316
316
  module.exports.EventStream = EventStream
@@ -318,7 +318,6 @@ module.exports.FileMemoryStore = FileMemoryStore
318
318
  module.exports.FileSessionStore = FileSessionStore
319
319
  module.exports.MemorySessionStore = MemorySessionStore
320
320
  module.exports.DefaultSecurityProvider = DefaultSecurityProvider
321
- module.exports.SkillPlugin = SkillPlugin
322
321
  module.exports.StdioTransport = StdioTransport
323
322
  module.exports.HttpTransport = HttpTransport
324
323
  module.exports.WebSocketTransport = WebSocketTransport
@@ -327,6 +326,3 @@ module.exports.Agent = Agent
327
326
  module.exports.Session = Session
328
327
  module.exports.builtinSkills = builtinSkills
329
328
  module.exports.BrowserBackend = BrowserBackend
330
- module.exports.SubAgentHandle = SubAgentHandle
331
- module.exports.SubAgentEventStream = SubAgentEventStream
332
- module.exports.Orchestrator = Orchestrator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/code",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "A3S Code - Native Node.js bindings for the coding-agent runtime",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -37,17 +37,14 @@
37
37
  "build:debug": "napi build --platform --js index.js --dts index.d.ts",
38
38
  "prepublishOnly": "napi prepublish -t npm",
39
39
  "test": "node test.mjs",
40
- "test:helpers": "node test-helpers.mjs",
41
- "test:agentic-search-locators": "node examples/search/test-agentic-search-locators.js",
42
- "test:agentic-search-sampled-lines": "node examples/search/test-agentic-search-sampled-lines.js",
43
- "test:agentic-parse-llm-blocks": "node examples/search/test-agentic-parse-llm-blocks.js"
40
+ "test:helpers": "node test-helpers.mjs"
44
41
  },
45
42
  "optionalDependencies": {
46
- "@a3s-lab/code-darwin-arm64": "2.0.0",
47
- "@a3s-lab/code-linux-x64-gnu": "2.0.0",
48
- "@a3s-lab/code-linux-x64-musl": "2.0.0",
49
- "@a3s-lab/code-linux-arm64-gnu": "2.0.0",
50
- "@a3s-lab/code-linux-arm64-musl": "2.0.0",
51
- "@a3s-lab/code-win32-x64-msvc": "2.0.0"
43
+ "@a3s-lab/code-darwin-arm64": "2.1.0",
44
+ "@a3s-lab/code-linux-x64-gnu": "2.1.0",
45
+ "@a3s-lab/code-linux-x64-musl": "2.1.0",
46
+ "@a3s-lab/code-linux-arm64-gnu": "2.1.0",
47
+ "@a3s-lab/code-linux-arm64-musl": "2.1.0",
48
+ "@a3s-lab/code-win32-x64-msvc": "2.1.0"
52
49
  }
53
50
  }