@a3s-lab/code 0.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.
package/README.md ADDED
@@ -0,0 +1,902 @@
1
+ # A3S Code TypeScript SDK
2
+
3
+ <p align="center">
4
+ <strong>TypeScript/JavaScript Client for A3S Code Agent</strong>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <em>Full-featured gRPC client for building AI coding agent applications</em>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <img src="https://img.shields.io/badge/API_Coverage-100%25-brightgreen" alt="API Coverage">
13
+ <img src="https://img.shields.io/badge/Methods-53-blue" alt="Methods">
14
+ <img src="https://img.shields.io/badge/TypeScript-5.3+-blue" alt="TypeScript">
15
+ <img src="https://img.shields.io/badge/License-MIT-green" alt="License">
16
+ </p>
17
+
18
+ <p align="center">
19
+ <a href="#features">Features</a> •
20
+ <a href="#installation">Installation</a> •
21
+ <a href="#quick-start">Quick Start</a> •
22
+ <a href="#api-reference">API Reference</a> •
23
+ <a href="./examples">Examples</a>
24
+ </p>
25
+
26
+ ---
27
+
28
+ ## Overview
29
+
30
+ **@a3s-lab/code** is the official TypeScript SDK for [A3S Code](https://github.com/a3s-lab/a3s), providing a complete gRPC client implementation for the CodeAgentService API. Build AI-powered coding assistants, IDE integrations, and automation tools with full access to A3S Code's capabilities.
31
+
32
+ ### Why This SDK?
33
+
34
+ - **100% API Coverage**: All 53 RPCs from CodeAgentService fully implemented
35
+ - **Type-Safe**: Full TypeScript definitions for all types and enums
36
+ - **Async/Await**: Modern Promise-based API with streaming support
37
+ - **Flexible Configuration**: Environment variables, config files, or programmatic setup
38
+ - **Real-World Examples**: Comprehensive examples with real LLM API integration
39
+
40
+ ## Features
41
+
42
+ | Category | Features |
43
+ |----------|----------|
44
+ | **Lifecycle** | Health check, capabilities, initialization, shutdown |
45
+ | **Sessions** | Create, list, get, configure, destroy with persistence |
46
+ | **Generation** | Streaming/non-streaming responses, structured output, context compaction |
47
+ | **Tools** | Load/unload skills, list available tools, custom tool registration |
48
+ | **Context** | Add/clear context, manage conversation history, usage monitoring |
49
+ | **Control** | Abort operations, pause/resume, cancel confirmations |
50
+ | **Events** | Subscribe to real-time agent events, tool execution tracking |
51
+ | **HITL** | Human-in-the-loop confirmations, approval workflows |
52
+ | **Permissions** | Fine-grained permission policies, tool access control |
53
+ | **Todos** | Task tracking for multi-step workflows, goal management |
54
+ | **Providers** | Multi-provider LLM configuration (Anthropic, OpenAI, KIMI, etc.) |
55
+ | **Planning** | Execution plans, goal extraction, achievement checking |
56
+ | **Memory** | Episodic/semantic/procedural memory storage and retrieval |
57
+ | **Storage** | Configurable session storage (memory, file, custom) |
58
+
59
+ ## Installation
60
+
61
+ ```bash
62
+ npm install @a3s-lab/code
63
+ # or
64
+ yarn add @a3s-lab/code
65
+ # or
66
+ pnpm add @a3s-lab/code
67
+ ```
68
+
69
+ ## Quick Start
70
+
71
+ ### Basic Usage
72
+
73
+ ```typescript
74
+ import { A3sClient } from '@a3s-lab/code';
75
+
76
+ // Create client with default config
77
+ const client = new A3sClient();
78
+
79
+ // Or with explicit address
80
+ const client = new A3sClient({ address: 'localhost:4088' });
81
+
82
+ // Or load from config file
83
+ const client = new A3sClient({ configDir: '/path/to/.a3s' });
84
+
85
+ async function main() {
86
+ // Check health
87
+ const health = await client.healthCheck();
88
+ console.log('Agent status:', health.status);
89
+
90
+ // Create a session
91
+ const session = await client.createSession({
92
+ name: 'my-session',
93
+ workspace: '/path/to/project',
94
+ systemPrompt: 'You are a helpful coding assistant.',
95
+ });
96
+
97
+ // Generate a response (streaming)
98
+ for await (const chunk of client.streamGenerate(session.sessionId, [
99
+ { role: 'user', content: 'Explain this codebase structure' }
100
+ ])) {
101
+ if (chunk.type === 'CHUNK_TYPE_CONTENT' && chunk.content) {
102
+ process.stdout.write(chunk.content);
103
+ }
104
+ }
105
+
106
+ // Clean up
107
+ await client.destroySession(session.sessionId);
108
+ client.close();
109
+ }
110
+
111
+ main().catch(console.error);
112
+ ```
113
+
114
+ ### 📚 Complete Examples
115
+
116
+ See the [examples](./examples) directory for comprehensive, runnable examples:
117
+
118
+ | Example | Description | Run |
119
+ |---------|-------------|-----|
120
+ | [kimi-test.ts](./examples/src/kimi-test.ts) | Test with KIMI K2.5 model | `npm run kimi-test` |
121
+ | [chat-simulation.ts](./examples/src/chat-simulation.ts) | Multi-turn chat with skills | `npm run chat` |
122
+ | [code-generation-interactive.ts](./examples/src/code-generation-interactive.ts) | Interactive code generation | `npm run code-gen` |
123
+ | [skill-usage-demo.ts](./examples/src/skill-usage-demo.ts) | Skill loading and usage | `npm run skill-demo` |
124
+ | [simple-test.ts](./examples/src/simple-test.ts) | Basic SDK usage | `npm run dev` |
125
+ | [storage-configuration.ts](./examples/src/storage-configuration.ts) | Memory vs file storage | `npm run storage` |
126
+ | [hitl-confirmation.ts](./examples/src/hitl-confirmation.ts) | Human-in-the-loop | `npm run hitl` |
127
+ | [provider-config.ts](./examples/src/provider-config.ts) | Provider management | `npm run provider` |
128
+ | [context-management.ts](./examples/src/context-management.ts) | Context monitoring | `npm run context` |
129
+ | [code-review-agent.ts](./examples/src/code-review-agent.ts) | Complete production example | `npm run code-review` |
130
+
131
+ **Quick start with examples:**
132
+
133
+ ```bash
134
+ cd examples
135
+ npm install
136
+
137
+ # Test with KIMI model (recommended)
138
+ npm run kimi-test
139
+
140
+ # Try chat simulation
141
+ npm run chat
142
+ ```
143
+
144
+ See [examples/README.md](./examples/README.md) for detailed documentation and [TESTING_WITH_REAL_MODELS.md](./examples/TESTING_WITH_REAL_MODELS.md) for API configuration guide.
145
+
146
+ ## Usage Examples
147
+
148
+ ### Multi-Turn Conversations
149
+
150
+ ```typescript
151
+ import { A3sClient } from '@a3s-lab/code';
152
+
153
+ const client = new A3sClient({ configDir: '~/.a3s' });
154
+
155
+ async function multiTurnChat() {
156
+ await client.connect();
157
+
158
+ const { sessionId } = await client.createSession({
159
+ name: 'chat-session',
160
+ workspace: '/path/to/project',
161
+ });
162
+
163
+ // First turn
164
+ for await (const chunk of client.streamGenerate(sessionId, [
165
+ { role: 'user', content: 'List all TypeScript files in this project' }
166
+ ])) {
167
+ if (chunk.content) process.stdout.write(chunk.content);
168
+ }
169
+
170
+ // Second turn - context is preserved
171
+ for await (const chunk of client.streamGenerate(sessionId, [
172
+ { role: 'user', content: 'Now analyze the main entry point' }
173
+ ])) {
174
+ if (chunk.content) process.stdout.write(chunk.content);
175
+ }
176
+
177
+ // Get conversation history
178
+ const { messages } = await client.getMessages(sessionId, { limit: 10 });
179
+ console.log(`\nConversation has ${messages.length} messages`);
180
+
181
+ await client.destroySession(sessionId);
182
+ client.close();
183
+ }
184
+ ```
185
+
186
+ ### Event Subscription
187
+
188
+ ```typescript
189
+ import { A3sClient } from '@a3s-lab/code';
190
+
191
+ const client = new A3sClient();
192
+
193
+ async function subscribeToEvents() {
194
+ await client.connect();
195
+
196
+ const { sessionId } = await client.createSession({
197
+ name: 'event-demo',
198
+ workspace: '/tmp/workspace',
199
+ });
200
+
201
+ // Subscribe to all events
202
+ const eventStream = client.subscribeEvents(sessionId);
203
+
204
+ // Handle events in background
205
+ (async () => {
206
+ for await (const event of eventStream) {
207
+ console.log(`[${event.type}] ${event.message}`);
208
+
209
+ if (event.type === 'EVENT_TYPE_TOOL_CALLED') {
210
+ console.log(` Tool: ${event.metadata?.tool_name}`);
211
+ }
212
+
213
+ if (event.type === 'EVENT_TYPE_CONFIRMATION_REQUIRED') {
214
+ console.log(` Confirmation needed for: ${event.metadata?.tool_name}`);
215
+ }
216
+ }
217
+ })();
218
+
219
+ // Generate with tool usage
220
+ for await (const chunk of client.streamGenerate(sessionId, [
221
+ { role: 'user', content: 'Read the README.md file' }
222
+ ])) {
223
+ if (chunk.content) process.stdout.write(chunk.content);
224
+ }
225
+
226
+ await client.destroySession(sessionId);
227
+ client.close();
228
+ }
229
+ ```
230
+
231
+ ### Human-in-the-Loop (HITL)
232
+
233
+ ```typescript
234
+ import { A3sClient } from '@a3s-lab/code';
235
+
236
+ const client = new A3sClient();
237
+
238
+ async function hitlDemo() {
239
+ await client.connect();
240
+
241
+ const { sessionId } = await client.createSession({
242
+ name: 'hitl-demo',
243
+ workspace: '/path/to/project',
244
+ });
245
+
246
+ // Set confirmation policy - require approval for bash commands
247
+ await client.setConfirmationPolicy(sessionId, {
248
+ defaultAction: 'TIMEOUT_ACTION_REJECT',
249
+ timeoutMs: 30000,
250
+ rules: [
251
+ {
252
+ toolPattern: 'bash',
253
+ action: 'TIMEOUT_ACTION_REJECT',
254
+ requireConfirmation: true,
255
+ }
256
+ ]
257
+ });
258
+
259
+ // Subscribe to events to detect confirmation requests
260
+ const eventStream = client.subscribeEvents(sessionId);
261
+
262
+ (async () => {
263
+ for await (const event of eventStream) {
264
+ if (event.type === 'EVENT_TYPE_CONFIRMATION_REQUIRED') {
265
+ const toolName = event.metadata?.tool_name;
266
+ const toolArgs = event.metadata?.tool_args;
267
+
268
+ console.log(`\nConfirmation required:`);
269
+ console.log(` Tool: ${toolName}`);
270
+ console.log(` Args: ${toolArgs}`);
271
+
272
+ // Auto-approve for demo (in real app, prompt user)
273
+ const approved = true;
274
+
275
+ await client.confirmToolExecution(sessionId, {
276
+ approved,
277
+ reason: approved ? 'User approved' : 'User rejected',
278
+ });
279
+ }
280
+ }
281
+ })();
282
+
283
+ // This will trigger confirmation
284
+ for await (const chunk of client.streamGenerate(sessionId, [
285
+ { role: 'user', content: 'Run "ls -la" command' }
286
+ ])) {
287
+ if (chunk.content) process.stdout.write(chunk.content);
288
+ }
289
+
290
+ await client.destroySession(sessionId);
291
+ client.close();
292
+ }
293
+ ```
294
+
295
+ ### Permission Policies
296
+
297
+ ```typescript
298
+ import { A3sClient } from '@a3s-lab/code';
299
+
300
+ const client = new A3sClient();
301
+
302
+ async function permissionDemo() {
303
+ await client.connect();
304
+
305
+ const { sessionId } = await client.createSession({
306
+ name: 'permission-demo',
307
+ workspace: '/path/to/project',
308
+ });
309
+
310
+ // Set permission policy - read-only mode
311
+ await client.setPermissionPolicy(sessionId, {
312
+ defaultDecision: 'PERMISSION_DECISION_DENY',
313
+ rules: [
314
+ {
315
+ toolPattern: 'read',
316
+ decision: 'PERMISSION_DECISION_ALLOW',
317
+ },
318
+ {
319
+ toolPattern: 'grep',
320
+ decision: 'PERMISSION_DECISION_ALLOW',
321
+ },
322
+ {
323
+ toolPattern: 'glob',
324
+ decision: 'PERMISSION_DECISION_ALLOW',
325
+ },
326
+ {
327
+ toolPattern: 'ls',
328
+ decision: 'PERMISSION_DECISION_ALLOW',
329
+ },
330
+ {
331
+ toolPattern: 'write',
332
+ decision: 'PERMISSION_DECISION_DENY',
333
+ },
334
+ {
335
+ toolPattern: 'bash',
336
+ decision: 'PERMISSION_DECISION_ASK',
337
+ }
338
+ ]
339
+ });
340
+
341
+ // Check permission before operation
342
+ const canWrite = await client.checkPermission(sessionId, {
343
+ toolName: 'write',
344
+ args: { file_path: '/tmp/test.txt' }
345
+ });
346
+
347
+ console.log(`Can write: ${canWrite.decision === 'PERMISSION_DECISION_ALLOW'}`);
348
+
349
+ // This will be allowed (read-only tools)
350
+ for await (const chunk of client.streamGenerate(sessionId, [
351
+ { role: 'user', content: 'List all files in the current directory' }
352
+ ])) {
353
+ if (chunk.content) process.stdout.write(chunk.content);
354
+ }
355
+
356
+ await client.destroySession(sessionId);
357
+ client.close();
358
+ }
359
+ ```
360
+
361
+ ### Provider Configuration
362
+
363
+ ```typescript
364
+ import { A3sClient } from '@a3s-lab/code';
365
+
366
+ const client = new A3sClient();
367
+
368
+ async function providerDemo() {
369
+ await client.connect();
370
+
371
+ // List available providers
372
+ const { providers } = await client.listProviders();
373
+ console.log('Available providers:', providers.map(p => p.name));
374
+
375
+ // Add a new provider
376
+ await client.addProvider({
377
+ name: 'openai',
378
+ apiKey: 'sk-...',
379
+ baseUrl: 'https://api.openai.com/v1',
380
+ models: [
381
+ {
382
+ id: 'gpt-4',
383
+ name: 'GPT-4',
384
+ family: 'gpt',
385
+ toolCall: true,
386
+ }
387
+ ]
388
+ });
389
+
390
+ // Set default model
391
+ await client.setDefaultModel('openai', 'gpt-4');
392
+
393
+ // Get current default
394
+ const { provider, model } = await client.getDefaultModel();
395
+ console.log(`Default: ${provider}/${model}`);
396
+
397
+ // Create session with specific model
398
+ const { sessionId } = await client.createSession({
399
+ name: 'openai-session',
400
+ workspace: '/tmp/workspace',
401
+ llmConfig: {
402
+ provider: 'openai',
403
+ model: 'gpt-4',
404
+ temperature: 0.7,
405
+ }
406
+ });
407
+
408
+ await client.destroySession(sessionId);
409
+ client.close();
410
+ }
411
+ ```
412
+
413
+ ### Context Management
414
+
415
+ ```typescript
416
+ import { A3sClient } from '@a3s-lab/code';
417
+
418
+ const client = new A3sClient();
419
+
420
+ async function contextDemo() {
421
+ await client.connect();
422
+
423
+ const { sessionId } = await client.createSession({
424
+ name: 'context-demo',
425
+ workspace: '/path/to/project',
426
+ });
427
+
428
+ // Have a long conversation...
429
+ for (let i = 0; i < 10; i++) {
430
+ await client.generate(sessionId, [
431
+ { role: 'user', content: `Question ${i + 1}: Tell me about this project` }
432
+ ]);
433
+ }
434
+
435
+ // Check context usage
436
+ const usage = await client.getContextUsage(sessionId);
437
+ console.log(`Context tokens: ${usage.totalTokens}/${usage.maxTokens}`);
438
+ console.log(`Messages: ${usage.messageCount}`);
439
+
440
+ if (usage.totalTokens > usage.maxTokens * 0.8) {
441
+ console.log('Context is getting full, compacting...');
442
+
443
+ // Compact context using LLM summarization
444
+ const result = await client.compactContext(sessionId);
445
+ console.log(`Compacted: ${result.originalMessages} → ${result.compactedMessages} messages`);
446
+ console.log(`Saved: ${result.tokensSaved} tokens`);
447
+ }
448
+
449
+ await client.destroySession(sessionId);
450
+ client.close();
451
+ }
452
+ ```
453
+
454
+ ### Skills Management
455
+
456
+ ```typescript
457
+ import { A3sClient } from '@a3s-lab/code';
458
+ import { readFileSync } from 'fs';
459
+
460
+ const client = new A3sClient();
461
+
462
+ async function skillsDemo() {
463
+ await client.connect();
464
+
465
+ const { sessionId } = await client.createSession({
466
+ name: 'skills-demo',
467
+ workspace: '/path/to/project',
468
+ });
469
+
470
+ // Load a custom skill from markdown file
471
+ const skillContent = readFileSync('./my-skill.md', 'utf-8');
472
+
473
+ await client.loadSkill(sessionId, 'my-custom-tool', skillContent);
474
+
475
+ // List all available skills
476
+ const { skills } = await client.listSkills(sessionId);
477
+ console.log('Available skills:', skills.map(s => s.name));
478
+
479
+ // Use the custom skill
480
+ for await (const chunk of client.streamGenerate(sessionId, [
481
+ { role: 'user', content: 'Use my-custom-tool to process data' }
482
+ ])) {
483
+ if (chunk.content) process.stdout.write(chunk.content);
484
+ }
485
+
486
+ // Unload the skill
487
+ await client.unloadSkill(sessionId, 'my-custom-tool');
488
+
489
+ await client.destroySession(sessionId);
490
+ client.close();
491
+ }
492
+ ```
493
+
494
+ ### Todo/Task Tracking
495
+
496
+ ```typescript
497
+ import { A3sClient } from '@a3s-lab/code';
498
+
499
+ const client = new A3sClient();
500
+
501
+ async function todoDemo() {
502
+ await client.connect();
503
+
504
+ const { sessionId } = await client.createSession({
505
+ name: 'todo-demo',
506
+ workspace: '/path/to/project',
507
+ });
508
+
509
+ // Set initial todos
510
+ await client.setTodos(sessionId, [
511
+ {
512
+ id: '1',
513
+ title: 'Analyze codebase structure',
514
+ description: 'Understand the project layout',
515
+ completed: false,
516
+ },
517
+ {
518
+ id: '2',
519
+ title: 'Fix bug in authentication',
520
+ description: 'User login fails with invalid token',
521
+ completed: false,
522
+ }
523
+ ]);
524
+
525
+ // Agent works on tasks...
526
+ await client.generate(sessionId, [
527
+ { role: 'user', content: 'Complete the first todo item' }
528
+ ]);
529
+
530
+ // Get updated todos
531
+ const { todos } = await client.getTodos(sessionId);
532
+ console.log('Todos:');
533
+ todos.forEach(todo => {
534
+ const status = todo.completed ? '✓' : '○';
535
+ console.log(` ${status} ${todo.title}`);
536
+ });
537
+
538
+ await client.destroySession(sessionId);
539
+ client.close();
540
+ }
541
+ ```
542
+
543
+ ### Operation Control
544
+
545
+ ```typescript
546
+ import { A3sClient } from '@a3s-lab/code';
547
+
548
+ const client = new A3sClient();
549
+
550
+ async function controlDemo() {
551
+ await client.connect();
552
+
553
+ const { sessionId } = await client.createSession({
554
+ name: 'control-demo',
555
+ workspace: '/path/to/project',
556
+ });
557
+
558
+ // Start a long-running operation
559
+ const generatePromise = (async () => {
560
+ for await (const chunk of client.streamGenerate(sessionId, [
561
+ { role: 'user', content: 'Analyze all files in this large project' }
562
+ ])) {
563
+ if (chunk.content) process.stdout.write(chunk.content);
564
+ }
565
+ })();
566
+
567
+ // Cancel after 5 seconds
568
+ setTimeout(async () => {
569
+ console.log('\nCancelling operation...');
570
+ await client.cancel(sessionId);
571
+ }, 5000);
572
+
573
+ try {
574
+ await generatePromise;
575
+ } catch (error) {
576
+ console.log('Operation was cancelled');
577
+ }
578
+
579
+ // Pause and resume
580
+ await client.pause(sessionId);
581
+ console.log('Session paused');
582
+
583
+ await client.resume(sessionId);
584
+ console.log('Session resumed');
585
+
586
+ await client.destroySession(sessionId);
587
+ client.close();
588
+ }
589
+ ```
590
+
591
+ ## Configuration
592
+
593
+ ### Using Real LLM APIs
594
+
595
+ The SDK requires a running A3S Code service configured with real LLM API credentials. See [examples/TESTING_WITH_REAL_MODELS.md](./examples/TESTING_WITH_REAL_MODELS.md) for detailed setup instructions.
596
+
597
+ **Quick setup:**
598
+
599
+ 1. **Configure A3S Code** - Edit `a3s/.a3s/config.json`:
600
+
601
+ ```json
602
+ {
603
+ "defaultProvider": "openai",
604
+ "defaultModel": "kimi-k2.5",
605
+ "providers": [
606
+ {
607
+ "name": "anthropic",
608
+ "apiKey": "sk-ant-xxx",
609
+ "baseUrl": "https://api.anthropic.com",
610
+ "models": [
611
+ {
612
+ "id": "claude-sonnet-4-20250514",
613
+ "name": "Claude Sonnet 4",
614
+ "family": "claude-sonnet",
615
+ "toolCall": true
616
+ }
617
+ ]
618
+ },
619
+ {
620
+ "name": "openai",
621
+ "models": [
622
+ {
623
+ "id": "kimi-k2.5",
624
+ "name": "KIMI K2.5",
625
+ "apiKey": "sk-xxx",
626
+ "baseUrl": "http://your-endpoint/v1",
627
+ "toolCall": true
628
+ }
629
+ ]
630
+ }
631
+ ]
632
+ }
633
+ ```
634
+
635
+ 2. **Start A3S Code service:**
636
+
637
+ ```bash
638
+ cd /path/to/a3s
639
+ ./target/debug/a3s-code -d .a3s -w /tmp/a3s-workspace
640
+ ```
641
+
642
+ 3. **Use SDK with config:**
643
+
644
+ ```typescript
645
+ import { A3sClient } from '@a3s-lab/code';
646
+
647
+ // Load configuration from A3S Code config directory
648
+ const client = new A3sClient({
649
+ address: 'localhost:4088',
650
+ configDir: '/path/to/a3s/.a3s'
651
+ });
652
+
653
+ // Create session - will use default model from config
654
+ const session = await client.createSession({
655
+ name: 'my-session',
656
+ workspace: '/tmp/workspace'
657
+ });
658
+
659
+ // Or specify model explicitly
660
+ const session = await client.createSession({
661
+ name: 'my-session',
662
+ workspace: '/tmp/workspace',
663
+ llm: {
664
+ provider: 'openai',
665
+ model: 'kimi-k2.5'
666
+ }
667
+ });
668
+ ```
669
+
670
+ ### Environment Variables
671
+
672
+ | Variable | Description | Default |
673
+ |----------|-------------|---------|
674
+ | `A3S_ADDRESS` | gRPC server address | `localhost:4088` |
675
+ | `A3S_CONFIG_DIR` | Configuration directory | - |
676
+
677
+ ### Programmatic Configuration
678
+
679
+ ```typescript
680
+ import { A3sClient, loadConfigFromDir } from '@a3s-lab/code';
681
+
682
+ // Load config from directory
683
+ const config = loadConfigFromDir('/path/to/.a3s');
684
+
685
+ // Create client with loaded config
686
+ const client = new A3sClient({
687
+ address: config.address || 'localhost:4088',
688
+ configDir: '/path/to/.a3s'
689
+ });
690
+
691
+ // Access config values
692
+ console.log('Default provider:', config.defaultProvider);
693
+ console.log('Default model:', config.defaultModel);
694
+ console.log('API key:', config.apiKey ? '(set)' : '(not set)');
695
+ ```
696
+
697
+ ### Legacy Config File Format
698
+
699
+ ```json
700
+ {
701
+ "address": "localhost:4088",
702
+ "defaultProvider": "anthropic",
703
+ "defaultModel": "claude-sonnet-4-20250514",
704
+ "providers": [
705
+ {
706
+ "name": "anthropic",
707
+ "apiKey": "sk-ant-...",
708
+ "models": [
709
+ { "id": "claude-sonnet-4-20250514", "name": "Claude Sonnet 4" }
710
+ ]
711
+ }
712
+ ]
713
+ }
714
+ ```
715
+
716
+ ## API Reference
717
+
718
+ ### Client Methods
719
+
720
+ #### Lifecycle (4 methods)
721
+
722
+ | Method | Description |
723
+ |--------|-------------|
724
+ | `healthCheck()` | Check agent health status |
725
+ | `getCapabilities()` | Get agent capabilities |
726
+ | `initialize(workspace, env?)` | Initialize the agent |
727
+ | `shutdown()` | Shutdown the agent |
728
+
729
+ #### Sessions (6 methods)
730
+
731
+ | Method | Description |
732
+ |--------|-------------|
733
+ | `createSession(config)` | Create a new session |
734
+ | `destroySession(id)` | Destroy a session |
735
+ | `listSessions()` | List all sessions |
736
+ | `getSession(id)` | Get session by ID |
737
+ | `configureSession(id, config)` | Update session configuration |
738
+ | `getMessages(id, limit?)` | Get conversation history |
739
+
740
+ #### Generation (4 methods)
741
+
742
+ | Method | Description |
743
+ |--------|-------------|
744
+ | `generate(sessionId, messages)` | Generate response (non-streaming) |
745
+ | `streamGenerate(sessionId, messages)` | Generate response (streaming) |
746
+ | `generateStructured(sessionId, messages, schema)` | Generate structured output |
747
+ | `streamGenerateStructured(sessionId, messages, schema)` | Stream structured output |
748
+
749
+ #### Context Management (3 methods)
750
+
751
+ | Method | Description |
752
+ |--------|-------------|
753
+ | `getContextUsage(sessionId)` | Get context token usage |
754
+ | `compactContext(sessionId)` | Compact session context |
755
+ | `clearContext(sessionId)` | Clear session context |
756
+
757
+ #### Skills (3 methods)
758
+
759
+ | Method | Description |
760
+ |--------|-------------|
761
+ | `loadSkill(sessionId, name)` | Load a skill |
762
+ | `unloadSkill(sessionId, name)` | Unload a skill |
763
+ | `listSkills(sessionId?)` | List available/loaded skills |
764
+
765
+ #### Control (3 methods)
766
+
767
+ | Method | Description |
768
+ |--------|-------------|
769
+ | `cancel(sessionId)` | Cancel running operation |
770
+ | `pause(sessionId)` | Pause session |
771
+ | `resume(sessionId)` | Resume session |
772
+
773
+ #### Events (1 method)
774
+
775
+ | Method | Description |
776
+ |--------|-------------|
777
+ | `subscribeEvents(sessionId)` | Subscribe to real-time events |
778
+
779
+ #### HITL (3 methods)
780
+
781
+ | Method | Description |
782
+ |--------|-------------|
783
+ | `confirmToolExecution(sessionId, response)` | Respond to confirmation request |
784
+ | `setConfirmationPolicy(sessionId, policy)` | Set confirmation policy |
785
+ | `getConfirmationPolicy(sessionId)` | Get confirmation policy |
786
+
787
+ #### Permissions (4 methods)
788
+
789
+ | Method | Description |
790
+ |--------|-------------|
791
+ | `setPermissionPolicy(sessionId, policy)` | Set permission policy |
792
+ | `getPermissionPolicy(sessionId)` | Get permission policy |
793
+ | `checkPermission(sessionId, request)` | Check tool permission |
794
+ | `addPermissionRule(sessionId, rule)` | Add permission rule |
795
+
796
+ #### External Tasks (4 methods)
797
+
798
+ | Method | Description |
799
+ |--------|-------------|
800
+ | `setLaneHandler(sessionId, lane, handler)` | Set lane handler |
801
+ | `getLaneHandler(sessionId, lane)` | Get lane handler |
802
+ | `completeExternalTask(sessionId, taskId, result)` | Complete external task |
803
+ | `listPendingExternalTasks(sessionId)` | List pending tasks |
804
+
805
+ #### Todos (2 methods)
806
+
807
+ | Method | Description |
808
+ |--------|-------------|
809
+ | `getTodos(sessionId)` | Get todo list |
810
+ | `setTodos(sessionId, todos)` | Set todo list |
811
+
812
+ #### Providers (7 methods)
813
+
814
+ | Method | Description |
815
+ |--------|-------------|
816
+ | `listProviders()` | List available providers |
817
+ | `getProvider(name)` | Get provider details |
818
+ | `addProvider(provider)` | Add a provider |
819
+ | `updateProvider(name, provider)` | Update provider |
820
+ | `removeProvider(name)` | Remove provider |
821
+ | `setDefaultModel(provider, model)` | Set default model |
822
+ | `getDefaultModel()` | Get default model |
823
+
824
+ #### Planning & Goals (4 methods)
825
+
826
+ | Method | Description |
827
+ |--------|-------------|
828
+ | `createPlan(sessionId, prompt, context?)` | Create execution plan |
829
+ | `getPlan(sessionId, planId)` | Get existing plan |
830
+ | `extractGoal(sessionId, prompt)` | Extract goal from prompt |
831
+ | `checkGoalAchievement(sessionId, goal, state)` | Check goal completion |
832
+
833
+ #### Memory System (5 methods)
834
+
835
+ | Method | Description |
836
+ |--------|-------------|
837
+ | `storeMemory(sessionId, memory)` | Store memory item |
838
+ | `retrieveMemory(sessionId, memoryId)` | Retrieve memory by ID |
839
+ | `searchMemories(sessionId, query, tags?, limit?)` | Search memories |
840
+ | `getMemoryStats(sessionId)` | Get memory statistics |
841
+ | `clearMemories(sessionId, type?)` | Clear memories |
842
+
843
+ **Total: 53 methods (100% API coverage)**
844
+
845
+ ### Types
846
+
847
+ See `ts/types.ts` for complete type definitions including:
848
+
849
+ - `SessionConfig`, `Session`
850
+ - `Message`, `MessageRole`
851
+ - `GenerateResponse`, `GenerateChunk`
852
+ - `HealthStatus`, `HealthStatusCode`
853
+ - `ProviderInfo`, `ModelInfo`
854
+ - `Todo`, `Skill`, `AgentEvent`
855
+
856
+ ## Development
857
+
858
+ ```bash
859
+ # Install dependencies
860
+ just install
861
+
862
+ # Build
863
+ just build
864
+
865
+ # Run tests
866
+ just test
867
+
868
+ # Run tests with coverage
869
+ just test-cov
870
+
871
+ # Type check
872
+ just check
873
+
874
+ # Lint
875
+ just lint
876
+
877
+ # Format
878
+ just fmt
879
+
880
+ # All checks
881
+ just ci
882
+ ```
883
+
884
+ ## A3S Ecosystem
885
+
886
+ This SDK is part of the A3S ecosystem:
887
+
888
+ | Project | Package | Purpose |
889
+ |---------|---------|---------|
890
+ | [a3s](https://github.com/a3s-lab/a3s) | `a3s-code` | AI coding agent framework |
891
+ | [sdk/typescript](.) | `@a3s-lab/code` | TypeScript SDK (this package) |
892
+ | [sdk/python](../python) | `a3s-code` | Python SDK |
893
+
894
+ ## License
895
+
896
+ MIT License - see [LICENSE](LICENSE) for details.
897
+
898
+ ---
899
+
900
+ <p align="center">
901
+ Built by <a href="https://github.com/a3s-lab">A3S Lab</a>
902
+ </p>