@providerprotocol/agents 0.0.2 → 0.0.3

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 (73) hide show
  1. package/dist/checkpoint/index.d.ts +43 -0
  2. package/dist/checkpoint/index.js +64 -0
  3. package/dist/checkpoint/index.js.map +1 -0
  4. package/{src/execution/loop.ts → dist/chunk-4ESYN66B.js} +54 -162
  5. package/dist/chunk-4ESYN66B.js.map +1 -0
  6. package/dist/chunk-EKRXMSDX.js +8 -0
  7. package/dist/chunk-EKRXMSDX.js.map +1 -0
  8. package/dist/chunk-PHI5ULBV.js +427 -0
  9. package/dist/chunk-PHI5ULBV.js.map +1 -0
  10. package/dist/execution/index.d.ts +105 -0
  11. package/dist/execution/index.js +679 -0
  12. package/dist/execution/index.js.map +1 -0
  13. package/dist/index-qsPwbY86.d.ts +65 -0
  14. package/dist/index.d.ts +101 -0
  15. package/dist/index.js +218 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/middleware/index.d.ts +23 -0
  18. package/dist/middleware/index.js +82 -0
  19. package/dist/middleware/index.js.map +1 -0
  20. package/dist/thread-tree/index.d.ts +115 -0
  21. package/dist/thread-tree/index.js +4 -0
  22. package/dist/thread-tree/index.js.map +1 -0
  23. package/dist/types-2Vsthzyu.d.ts +163 -0
  24. package/dist/types-BhX9uD_d.d.ts +91 -0
  25. package/dist/types-DR02gtFv.d.ts +270 -0
  26. package/dist/types-NGQMdnaD.d.ts +65 -0
  27. package/package.json +40 -8
  28. package/.claude/settings.local.json +0 -29
  29. package/AGENTS.md +0 -681
  30. package/CLAUDE.md +0 -681
  31. package/bun.lock +0 -472
  32. package/eslint.config.js +0 -75
  33. package/index.ts +0 -1
  34. package/llms.md +0 -796
  35. package/specs/UAP-1.0.md +0 -2355
  36. package/src/agent/index.ts +0 -384
  37. package/src/agent/types.ts +0 -91
  38. package/src/checkpoint/file.ts +0 -126
  39. package/src/checkpoint/index.ts +0 -40
  40. package/src/checkpoint/types.ts +0 -95
  41. package/src/execution/index.ts +0 -37
  42. package/src/execution/plan.ts +0 -497
  43. package/src/execution/react.ts +0 -340
  44. package/src/execution/tool-ordering.ts +0 -186
  45. package/src/execution/types.ts +0 -315
  46. package/src/index.ts +0 -80
  47. package/src/middleware/index.ts +0 -7
  48. package/src/middleware/logging.ts +0 -123
  49. package/src/middleware/types.ts +0 -69
  50. package/src/state/index.ts +0 -301
  51. package/src/state/types.ts +0 -173
  52. package/src/thread-tree/index.ts +0 -249
  53. package/src/thread-tree/types.ts +0 -29
  54. package/src/utils/uuid.ts +0 -7
  55. package/tests/live/agent-anthropic.test.ts +0 -288
  56. package/tests/live/agent-strategy-hooks.test.ts +0 -268
  57. package/tests/live/checkpoint.test.ts +0 -243
  58. package/tests/live/execution-strategies.test.ts +0 -255
  59. package/tests/live/plan-strategy.test.ts +0 -160
  60. package/tests/live/subagent-events.live.test.ts +0 -249
  61. package/tests/live/thread-tree.test.ts +0 -186
  62. package/tests/unit/agent.test.ts +0 -703
  63. package/tests/unit/checkpoint.test.ts +0 -232
  64. package/tests/unit/execution/equivalence.test.ts +0 -402
  65. package/tests/unit/execution/loop.test.ts +0 -437
  66. package/tests/unit/execution/plan.test.ts +0 -590
  67. package/tests/unit/execution/react.test.ts +0 -604
  68. package/tests/unit/execution/subagent-events.test.ts +0 -235
  69. package/tests/unit/execution/tool-ordering.test.ts +0 -310
  70. package/tests/unit/middleware/logging.test.ts +0 -276
  71. package/tests/unit/state.test.ts +0 -573
  72. package/tests/unit/thread-tree.test.ts +0 -249
  73. package/tsconfig.json +0 -29
package/llms.md DELETED
@@ -1,796 +0,0 @@
1
- # How to Use @providerprotocol/agents
2
-
3
- `@providerprotocol/agents` is a Unified Agent Protocol (UAP) 1.0 implementation built on `@providerprotocol/ai` (UPP-1.2). It provides a complete framework for building AI agents with explicit control, functional state management, and composable execution strategies.
4
-
5
- **Core Philosophy: "UAP is a pipe, not a nanny."**
6
- The protocol provides orchestration primitives; the developer provides the constraints. There are no artificial limits by default - infinite execution is standard.
7
-
8
- ## Quick Start
9
-
10
- ```typescript
11
- import { agent, AgentState } from '@providerprotocol/agents';
12
- import { anthropic } from '@providerprotocol/ai/anthropic';
13
-
14
- // Create an agent
15
- const coder = agent({
16
- model: anthropic('claude-sonnet-4-20250514'),
17
- params: { max_tokens: 4096 },
18
- system: 'You are an expert software engineer.',
19
- tools: [myReadTool, myWriteTool],
20
- });
21
-
22
- // Execute with immutable state
23
- const state = AgentState.initial();
24
- const { turn, state: newState } = await coder.generate('Hello!', state);
25
- console.log(turn.response.text);
26
- ```
27
-
28
- ## Installation
29
-
30
- ```bash
31
- bun install @providerprotocol/agents @providerprotocol/ai
32
- ```
33
-
34
- The library requires `@providerprotocol/ai >= 0.0.11` as a peer dependency.
35
-
36
- ## Architecture Overview
37
-
38
- ```
39
- Application Layer (your code)
40
- |
41
- Agent Interface (generate, stream, ask, query)
42
- |
43
- Middleware Pipeline (logging, guardrails, context pruning)
44
- |
45
- Execution Strategies (loop, react, plan)
46
- |
47
- UPP-1.2 Layer (@providerprotocol/ai)
48
- |
49
- LLM Provider Adapters (Anthropic, OpenAI, Google, Ollama, etc.)
50
- ```
51
-
52
- ## Creating Agents
53
-
54
- ### Basic Agent
55
-
56
- ```typescript
57
- import { agent, AgentState } from '@providerprotocol/agents';
58
- import { anthropic } from '@providerprotocol/ai/anthropic';
59
-
60
- const myAgent = agent({
61
- model: anthropic('claude-sonnet-4-20250514'),
62
- params: { max_tokens: 4096 },
63
- system: 'You are a helpful assistant.',
64
- });
65
- ```
66
-
67
- ### Agent with Tools
68
-
69
- ```typescript
70
- import { agent, AgentState } from '@providerprotocol/agents';
71
- import { anthropic } from '@providerprotocol/ai/anthropic';
72
-
73
- const calculator = {
74
- name: 'calculate',
75
- description: 'Perform arithmetic calculations',
76
- parameters: {
77
- type: 'object' as const,
78
- properties: {
79
- expression: { type: 'string' as const, description: 'Math expression' },
80
- },
81
- required: ['expression'],
82
- },
83
- run: async (params: { expression: string }) => {
84
- return String(eval(params.expression)); // Use a proper math parser in production
85
- },
86
- };
87
-
88
- const mathAgent = agent({
89
- model: anthropic('claude-sonnet-4-20250514'),
90
- params: { max_tokens: 1000 },
91
- tools: [calculator],
92
- });
93
- ```
94
-
95
- ### Full Agent Options
96
-
97
- ```typescript
98
- import { agent, AgentState } from '@providerprotocol/agents';
99
- import { react } from '@providerprotocol/agents/execution';
100
- import { logging } from '@providerprotocol/agents/middleware';
101
- import { anthropic } from '@providerprotocol/ai/anthropic';
102
-
103
- const fullAgent = agent({
104
- // Required: Model from UPP provider
105
- model: anthropic('claude-sonnet-4-20250514'),
106
-
107
- // LLM parameters (provider-specific)
108
- params: { max_tokens: 8192 },
109
-
110
- // Provider configuration
111
- config: {
112
- apiKey: 'sk-...', // Override env var
113
- baseUrl: 'https://...', // Custom endpoint
114
- },
115
-
116
- // System prompt
117
- system: 'You are an expert coder.',
118
-
119
- // Tools array
120
- tools: [readTool, writeTool, bashTool],
121
-
122
- // Execution strategy (default: loop())
123
- execution: react({ maxSteps: 20 }),
124
-
125
- // Middleware pipeline
126
- middleware: [logging({ level: 'info' })],
127
-
128
- // Lifecycle hooks
129
- strategy: {
130
- stopCondition: (state) => state.step > 50,
131
- onStepStart: (step, state) => console.log(`Step ${step}`),
132
- onComplete: (result) => console.log('Done!'),
133
- },
134
-
135
- // Tool execution hooks (passed to UPP)
136
- toolStrategy: {
137
- maxIterations: Infinity,
138
- onToolCall: (tool, params) => console.log(`Calling ${tool.name}`),
139
- },
140
-
141
- // Checkpointing for persistence
142
- checkpoints: fileCheckpoints({ dir: '.checkpoints' }),
143
- sessionId: 'my-session-123', // Auto-generated if not provided
144
- });
145
- ```
146
-
147
- ## Agent Methods
148
-
149
- ### generate(input, state)
150
-
151
- Execute agent and return result with new state.
152
-
153
- ```typescript
154
- const state = AgentState.initial();
155
- const { turn, state: newState } = await myAgent.generate('Hello!', state);
156
-
157
- console.log(turn.response.text); // Response text
158
- console.log(turn.usage.totalTokens); // Token usage
159
- console.log(turn.toolExecutions); // Tool executions
160
- console.log(newState.step); // Current step number
161
- console.log(newState.messages.length); // Message count
162
- ```
163
-
164
- ### stream(input, state)
165
-
166
- Execute agent with streaming events.
167
-
168
- ```typescript
169
- const stream = myAgent.stream('Explain quantum computing', state);
170
-
171
- // Iterate over events
172
- for await (const event of stream) {
173
- if (event.source === 'upp' && event.upp?.type === 'text_delta') {
174
- // LLM text streaming
175
- process.stdout.write(event.upp.delta.text ?? '');
176
- }
177
- if (event.source === 'uap' && event.uap?.type === 'step_start') {
178
- // Agent-level events
179
- console.log(`\nStep ${event.uap.step} started`);
180
- }
181
- }
182
-
183
- // Get final result after stream completes
184
- const { turn, state: newState } = await stream.result;
185
-
186
- // Abort if needed
187
- stream.abort();
188
- ```
189
-
190
- ### ask(input, state)
191
-
192
- Multi-turn convenience method that automatically appends messages to state.
193
-
194
- ```typescript
195
- let state = AgentState.initial();
196
-
197
- // First turn
198
- const result1 = await myAgent.ask('My name is Alice', state);
199
- state = result1.state;
200
-
201
- // Second turn (model remembers context)
202
- const result2 = await myAgent.ask('What is my name?', state);
203
- // result2.turn.response.text contains "Alice"
204
- ```
205
-
206
- ### query(input)
207
-
208
- Stateless single-turn execution. Creates ephemeral state, executes, discards state.
209
-
210
- ```typescript
211
- const turn = await myAgent.query('What is 2+2?');
212
- console.log(turn.response.text); // "4"
213
- ```
214
-
215
- ## Execution Strategies
216
-
217
- Import from `@providerprotocol/agents/execution`.
218
-
219
- ### loop() - Simple Tool Loop
220
-
221
- Simplest strategy - equivalent to UPP's built-in tool loop.
222
-
223
- ```typescript
224
- import { loop } from '@providerprotocol/agents/execution';
225
-
226
- const agent = agent({
227
- model: anthropic('claude-sonnet-4-20250514'),
228
- execution: loop({ maxIterations: Infinity }), // Default
229
- });
230
- ```
231
-
232
- Behavior:
233
- 1. Send input to LLM
234
- 2. If response has tool calls, execute tools
235
- 3. Loop until no more tool calls or maxIterations reached
236
-
237
- ### react() - Reason-Act-Observe
238
-
239
- ReAct pattern with explicit reasoning phase.
240
-
241
- ```typescript
242
- import { react } from '@providerprotocol/agents/execution';
243
-
244
- const agent = agent({
245
- model: anthropic('claude-sonnet-4-20250514'),
246
- execution: react({
247
- maxSteps: Infinity, // Default
248
- reasoningPrompt: 'Think step by step about what you need to do next.',
249
- }),
250
- });
251
- ```
252
-
253
- Behavior:
254
- 1. **Reason**: LLM outputs reasoning about what to do
255
- 2. **Act**: LLM selects and executes tool(s)
256
- 3. **Observe**: Tool results fed back
257
- 4. Repeat until no actions or maxSteps reached
258
-
259
- Stream events emitted: `step_start`, `reasoning`, `action`, `observation`, `step_end`
260
-
261
- ### plan() - Plan-then-Execute
262
-
263
- Generate structured plan with dependencies, then execute.
264
-
265
- ```typescript
266
- import { plan } from '@providerprotocol/agents/execution';
267
-
268
- const agent = agent({
269
- model: anthropic('claude-sonnet-4-20250514'),
270
- execution: plan({
271
- maxPlanSteps: Infinity, // Default
272
- allowReplan: true, // Replan on failure
273
- }),
274
- });
275
- ```
276
-
277
- Behavior:
278
- 1. **Planning phase**: LLM generates structured plan with step dependencies
279
- 2. **Execution phase**: Execute steps in topological order
280
- 3. Optionally replan if a step fails
281
-
282
- Stream events emitted: `plan_created`, `plan_step_start`, `action`, `observation`, `plan_step_end`
283
-
284
- ## State Management
285
-
286
- `AgentState` is immutable - all operations return new instances.
287
-
288
- ### Creating State
289
-
290
- ```typescript
291
- import { AgentState } from '@providerprotocol/agents';
292
-
293
- // Create initial state
294
- const state = AgentState.initial();
295
- ```
296
-
297
- ### State Operations
298
-
299
- All operations return new `AgentState` instances:
300
-
301
- ```typescript
302
- // Add message
303
- const state2 = state.withMessage(new UserMessage('Hello'));
304
-
305
- // Add multiple messages
306
- const state3 = state.withMessages([msg1, msg2]);
307
-
308
- // Replace entire context (for pruning/summarization)
309
- const state4 = state.withContext([prunedMessages]);
310
-
311
- // Update step number
312
- const state5 = state.withStep(5);
313
-
314
- // Add metadata
315
- const state6 = state.withMetadata('customKey', 'value');
316
-
317
- // Add reasoning trace (ReAct)
318
- const state7 = state.withReasoning('I should read the file first...');
319
-
320
- // Set execution plan
321
- const state8 = state.withPlan([
322
- { id: 'step1', description: 'Read file', status: 'pending', dependsOn: [] },
323
- ]);
324
- ```
325
-
326
- ### State Properties
327
-
328
- ```typescript
329
- state.id // UUIDv4 state identifier
330
- state.messages // Conversation messages (readonly)
331
- state.step // Current step number
332
- state.metadata // Key-value metadata
333
- state.reasoning // Reasoning traces (ReAct)
334
- state.plan // Execution plan steps
335
- ```
336
-
337
- ### Serialization
338
-
339
- ```typescript
340
- // Save state
341
- const json = state.toJSON();
342
- await Bun.write('state.json', JSON.stringify(json));
343
-
344
- // Restore state
345
- const loaded = await Bun.file('state.json').json();
346
- const restoredState = AgentState.fromJSON(loaded);
347
- ```
348
-
349
- ## Middleware
350
-
351
- Import from `@providerprotocol/agents/middleware`.
352
-
353
- ### Built-in Logging Middleware
354
-
355
- ```typescript
356
- import { logging } from '@providerprotocol/agents/middleware';
357
-
358
- const agent = agent({
359
- model: anthropic('claude-sonnet-4-20250514'),
360
- middleware: [
361
- logging({
362
- level: 'info', // 'debug' | 'info' | 'warn' | 'error'
363
- logger: console.log, // Custom logger function
364
- includeMessages: false, // Log message contents
365
- includeTiming: true, // Log execution duration
366
- }),
367
- ],
368
- });
369
- ```
370
-
371
- ### Custom Middleware
372
-
373
- ```typescript
374
- import type { Middleware, MiddlewareContext } from '@providerprotocol/agents/middleware';
375
- import type { GenerateResult } from '@providerprotocol/agents';
376
-
377
- const myMiddleware: Middleware = {
378
- name: 'my-middleware',
379
-
380
- // Runs before execution (forward order)
381
- async before(context: MiddlewareContext) {
382
- console.log('Before:', context.input);
383
- // Optionally return modified context
384
- return context;
385
- },
386
-
387
- // Runs after execution (reverse order)
388
- async after(context: MiddlewareContext, result: GenerateResult) {
389
- console.log('After:', result.turn.response.text);
390
- // Must return result (possibly modified)
391
- return result;
392
- },
393
-
394
- // Runs on error (reverse order)
395
- async onError(context: MiddlewareContext, error: Error) {
396
- console.error('Error:', error.message);
397
- // Return recovery result or undefined to propagate error
398
- return undefined;
399
- },
400
- };
401
- ```
402
-
403
- ### Middleware Execution Order
404
-
405
- ```
406
- first.before() → second.before() → third.before()
407
- → Agent Execution
408
- → third.after() → second.after() → first.after()
409
- ```
410
-
411
- ## Thread Trees
412
-
413
- For branching conversations. Import from `@providerprotocol/agents/thread-tree`.
414
-
415
- ```typescript
416
- import { ThreadTree } from '@providerprotocol/agents/thread-tree';
417
- import { agent, AgentState } from '@providerprotocol/agents';
418
-
419
- // Create tree
420
- const tree = new ThreadTree();
421
-
422
- // Execute on current node
423
- const { turn, state } = await myAgent.generate('Start conversation', tree.history());
424
- tree.current.state = state;
425
-
426
- // Create a branch
427
- const branchId = tree.branch(tree.current.id, 'alternative-path');
428
-
429
- // Switch to branch
430
- tree.checkout(branchId);
431
-
432
- // Execute on branch
433
- const { turn: t2, state: s2 } = await myAgent.generate('Different direction', tree.history());
434
- tree.current.state = s2;
435
-
436
- // Navigation
437
- tree.getLeaves(); // All leaf node IDs
438
- tree.getBranches(); // Map of node IDs to names
439
-
440
- // Serialization
441
- const json = tree.toJSON();
442
- const restored = ThreadTree.fromJSON(json);
443
- ```
444
-
445
- ## Checkpointing
446
-
447
- For session persistence and recovery.
448
-
449
- ### File-based Checkpoints
450
-
451
- ```typescript
452
- import { agent, AgentState } from '@providerprotocol/agents';
453
- import { fileCheckpoints } from '@providerprotocol/agents/checkpoint';
454
-
455
- const store = fileCheckpoints({ dir: '.checkpoints' });
456
-
457
- const myAgent = agent({
458
- model: anthropic('claude-sonnet-4-20250514'),
459
- checkpoints: store,
460
- sessionId: 'my-session', // Auto-generated UUIDv4 if not provided
461
- });
462
-
463
- // Execute - checkpoints saved automatically after each step
464
- const { turn, state } = await myAgent.generate('Hello', AgentState.initial());
465
-
466
- // Later: manually load checkpoint
467
- const savedState = await store.load('my-session');
468
- if (savedState) {
469
- const restoredState = AgentState.fromJSON(savedState);
470
- // Continue from saved state
471
- const { turn: t2 } = await myAgent.generate('Continue', restoredState);
472
- }
473
-
474
- // List all sessions
475
- const sessions = await store.list();
476
-
477
- // Delete a session
478
- await store.delete('my-session');
479
- ```
480
-
481
- ### Custom Checkpoint Store
482
-
483
- ```typescript
484
- import type { CheckpointStore, AgentStateJSON } from '@providerprotocol/agents';
485
-
486
- const customStore: CheckpointStore = {
487
- async save(sessionId: string, state: AgentStateJSON): Promise<void> {
488
- // Save to database, S3, etc.
489
- },
490
- async load(sessionId: string): Promise<AgentStateJSON | null> {
491
- // Load from storage
492
- },
493
- async delete(sessionId: string): Promise<void> {
494
- // Delete from storage
495
- },
496
- async list(): Promise<string[]> {
497
- // List all session IDs
498
- },
499
- };
500
- ```
501
-
502
- ## Strategy Hooks
503
-
504
- Control agent lifecycle with hooks:
505
-
506
- ```typescript
507
- const agent = agent({
508
- model: anthropic('claude-sonnet-4-20250514'),
509
- strategy: {
510
- // Stop execution when condition is met
511
- stopCondition: async (state) => {
512
- return state.step > 50 || state.metadata.shouldStop === true;
513
- },
514
-
515
- // Called when each step begins
516
- onStepStart: (step, state) => {
517
- console.log(`Step ${step} starting...`);
518
- },
519
-
520
- // Called during reasoning phase (ReAct strategy)
521
- onReason: (step, reasoning) => {
522
- console.log(`Reasoning: ${reasoning}`);
523
- },
524
-
525
- // Called when tools are invoked
526
- onAct: (step, toolCalls) => {
527
- console.log(`Tools: ${toolCalls.map(t => t.toolName).join(', ')}`);
528
- },
529
-
530
- // Called when tool results are received
531
- onObserve: (step, observations) => {
532
- console.log(`Results: ${observations.length} tool outputs`);
533
- },
534
-
535
- // Called when each step completes
536
- onStepEnd: (step, result) => {
537
- console.log(`Step ${step} complete, tokens: ${result.turn.usage?.totalTokens}`);
538
- },
539
-
540
- // Called when execution completes successfully
541
- onComplete: (result) => {
542
- console.log(`Done! Total steps: ${result.state.step}`);
543
- },
544
-
545
- // Called on error
546
- onError: (error, state) => {
547
- console.error(`Error at step ${state.step}: ${error.message}`);
548
- // Optionally return recovery result
549
- return undefined;
550
- },
551
- },
552
- });
553
- ```
554
-
555
- ## Stream Events
556
-
557
- ### UAP Events (source: 'uap')
558
-
559
- Agent-level events from execution strategies:
560
-
561
- | Event | Data | Description |
562
- |-------|------|-------------|
563
- | `step_start` | `{ step, agentId, data }` | Step began |
564
- | `step_end` | `{ step, agentId, data }` | Step completed |
565
- | `reasoning` | `{ step, agentId, data: { reasoning } }` | ReAct reasoning |
566
- | `action` | `{ step, agentId, data: { toolCalls } }` | Tools invoked |
567
- | `observation` | `{ step, agentId, data: { observations } }` | Tool results |
568
- | `plan_created` | `{ step, agentId, data: { plan } }` | Plan generated |
569
- | `plan_step_start` | `{ step, agentId, data: { planStep } }` | Plan step began |
570
- | `plan_step_end` | `{ step, agentId, data: { planStep } }` | Plan step done |
571
-
572
- ### UPP Events (source: 'upp')
573
-
574
- LLM-level events from @providerprotocol/ai:
575
-
576
- | Event | Data | Description |
577
- |-------|------|-------------|
578
- | `text_delta` | `{ delta: { text } }` | Streaming text |
579
- | `tool_call_delta` | `{ delta: { toolCallId, toolName, argumentsJson } }` | Tool call streaming |
580
- | `message_start` | - | Message began |
581
- | `message_stop` | - | Message completed |
582
- | `content_block_start` | - | Content block began |
583
- | `content_block_stop` | - | Content block done |
584
-
585
- ## Tool Dependencies
586
-
587
- Tools can declare execution ordering:
588
-
589
- ```typescript
590
- import type { ToolWithDependencies } from '@providerprotocol/agents/execution';
591
-
592
- const readTool: ToolWithDependencies = {
593
- name: 'read_file',
594
- description: 'Read file contents',
595
- parameters: { /* ... */ },
596
- sequential: true, // Must complete before other tools
597
- run: async (params) => { /* ... */ },
598
- };
599
-
600
- const writeTool: ToolWithDependencies = {
601
- name: 'write_file',
602
- description: 'Write file contents',
603
- parameters: { /* ... */ },
604
- dependsOn: ['read_file'], // Waits for read_file
605
- run: async (params) => { /* ... */ },
606
- };
607
- ```
608
-
609
- ## Sub-agents
610
-
611
- Agents can spawn sub-agents via tools:
612
-
613
- ```typescript
614
- import { agent, AgentState } from '@providerprotocol/agents';
615
- import type { OnSubagentEvent } from '@providerprotocol/agents';
616
-
617
- // Sub-agent event callback
618
- const onSubagentEvent: OnSubagentEvent = (event) => {
619
- switch (event.type) {
620
- case 'subagent_start':
621
- console.log(`Sub-agent ${event.subagentType} started`);
622
- break;
623
- case 'subagent_event':
624
- console.log(`Sub-agent event: ${event.innerEvent.source}`);
625
- break;
626
- case 'subagent_end':
627
- console.log(`Sub-agent completed: ${event.success}`);
628
- break;
629
- }
630
- };
631
-
632
- // Create sub-agent tool
633
- const explorerTool = {
634
- name: 'explore',
635
- description: 'Explore codebase for information',
636
- parameters: {
637
- type: 'object' as const,
638
- properties: {
639
- query: { type: 'string' as const },
640
- },
641
- required: ['query'],
642
- },
643
- run: async (params: { query: string }) => {
644
- const explorer = agent({
645
- model: anthropic('claude-3-5-haiku-latest'),
646
- params: { max_tokens: 2000 },
647
- tools: [globTool, grepTool, readTool],
648
- });
649
-
650
- const turn = await explorer.query(params.query);
651
- return turn.response.text;
652
- },
653
- };
654
- ```
655
-
656
- ## Provider Support
657
-
658
- All providers from `@providerprotocol/ai` are supported:
659
-
660
- ```typescript
661
- // Anthropic
662
- import { anthropic } from '@providerprotocol/ai/anthropic';
663
- agent({ model: anthropic('claude-sonnet-4-20250514'), params: { max_tokens: 4096 } });
664
-
665
- // OpenAI
666
- import { openai } from '@providerprotocol/ai/openai';
667
- agent({ model: openai('gpt-4o'), params: { max_output_tokens: 4096 } });
668
-
669
- // Google
670
- import { google } from '@providerprotocol/ai/google';
671
- agent({ model: google('gemini-2.0-flash'), params: { maxOutputTokens: 4096 } });
672
-
673
- // Ollama (local)
674
- import { ollama } from '@providerprotocol/ai/ollama';
675
- agent({ model: ollama('llama3:8b'), params: { num_predict: 4096 } });
676
-
677
- // OpenRouter
678
- import { openrouter } from '@providerprotocol/ai/openrouter';
679
- agent({ model: openrouter('anthropic/claude-3.5-sonnet'), params: { max_tokens: 4096 } });
680
-
681
- // xAI
682
- import { xai } from '@providerprotocol/ai/xai';
683
- agent({ model: xai('grok-2'), params: { max_tokens: 4096 } });
684
- ```
685
-
686
- ## Environment Variables
687
-
688
- Set API keys in `.env` (Bun auto-loads):
689
-
690
- ```
691
- ANTHROPIC_API_KEY=sk-ant-...
692
- OPENAI_API_KEY=sk-...
693
- GOOGLE_API_KEY=AI...
694
- XAI_API_KEY=xai-...
695
- OPENROUTER_API_KEY=sk-or-...
696
- ```
697
-
698
- ## Testing
699
-
700
- Run tests with Bun:
701
-
702
- ```bash
703
- bun test # All tests
704
- bun test:unit # Unit tests only
705
- bun test:live # Live API tests
706
- ```
707
-
708
- ## Complete Example
709
-
710
- ```typescript
711
- import { agent, AgentState } from '@providerprotocol/agents';
712
- import { react } from '@providerprotocol/agents/execution';
713
- import { logging } from '@providerprotocol/agents/middleware';
714
- import { anthropic } from '@providerprotocol/ai/anthropic';
715
-
716
- // Define tools
717
- const readFile = {
718
- name: 'read_file',
719
- description: 'Read contents of a file',
720
- parameters: {
721
- type: 'object' as const,
722
- properties: {
723
- path: { type: 'string' as const, description: 'File path' },
724
- },
725
- required: ['path'],
726
- },
727
- run: async (params: { path: string }) => {
728
- return await Bun.file(params.path).text();
729
- },
730
- };
731
-
732
- // Create agent
733
- const coder = agent({
734
- model: anthropic('claude-sonnet-4-20250514'),
735
- params: { max_tokens: 8192 },
736
- system: `You are an expert software engineer.
737
- Always read files before suggesting changes.
738
- Think step by step about the best approach.`,
739
- tools: [readFile],
740
- execution: react({ maxSteps: 10 }),
741
- middleware: [logging({ level: 'info' })],
742
- strategy: {
743
- onStepEnd: (step, result) => {
744
- console.log(`Step ${step}: ${result.turn.usage?.totalTokens} tokens`);
745
- },
746
- },
747
- });
748
-
749
- // Interactive session
750
- async function main() {
751
- let state = AgentState.initial();
752
-
753
- // First turn
754
- const r1 = await coder.ask('Read package.json and summarize dependencies', state);
755
- console.log(r1.turn.response.text);
756
- state = r1.state;
757
-
758
- // Follow-up (with context)
759
- const r2 = await coder.ask('Which of these are dev dependencies?', state);
760
- console.log(r2.turn.response.text);
761
- }
762
-
763
- main();
764
- ```
765
-
766
- ## Key Exports
767
-
768
- ```typescript
769
- // Main entry
770
- import { agent, AgentState } from '@providerprotocol/agents';
771
-
772
- // Types
773
- import type {
774
- Agent,
775
- AgentOptions,
776
- GenerateResult,
777
- AgentStreamResult,
778
- AgentStreamEvent,
779
- AgentStrategy,
780
- } from '@providerprotocol/agents';
781
-
782
- // Execution strategies
783
- import { loop, react, plan } from '@providerprotocol/agents/execution';
784
- import type { LoopOptions, ReactOptions, PlanOptions } from '@providerprotocol/agents/execution';
785
-
786
- // Middleware
787
- import { logging } from '@providerprotocol/agents/middleware';
788
- import type { Middleware, LoggingOptions } from '@providerprotocol/agents/middleware';
789
-
790
- // Thread trees
791
- import { ThreadTree, ThreadNode } from '@providerprotocol/agents/thread-tree';
792
-
793
- // Checkpoints
794
- import { fileCheckpoints } from '@providerprotocol/agents/checkpoint';
795
- import type { CheckpointStore } from '@providerprotocol/agents';
796
- ```