@falai/agent 0.3.0 → 0.3.11

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 (114) hide show
  1. package/README.md +257 -24
  2. package/dist/cjs/core/Agent.d.ts +37 -0
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +167 -1
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/DomainRegistry.d.ts +10 -0
  7. package/dist/cjs/core/DomainRegistry.d.ts.map +1 -1
  8. package/dist/cjs/core/DomainRegistry.js +25 -0
  9. package/dist/cjs/core/DomainRegistry.js.map +1 -1
  10. package/dist/cjs/core/PromptBuilder.d.ts +9 -1
  11. package/dist/cjs/core/PromptBuilder.d.ts.map +1 -1
  12. package/dist/cjs/core/PromptBuilder.js +49 -2
  13. package/dist/cjs/core/PromptBuilder.js.map +1 -1
  14. package/dist/cjs/core/Route.d.ts +16 -0
  15. package/dist/cjs/core/Route.d.ts.map +1 -1
  16. package/dist/cjs/core/Route.js +22 -0
  17. package/dist/cjs/core/Route.js.map +1 -1
  18. package/dist/cjs/index.d.ts +2 -0
  19. package/dist/cjs/index.d.ts.map +1 -1
  20. package/dist/cjs/index.js +3 -1
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/cjs/providers/AnthropicProvider.d.ts +43 -0
  23. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -0
  24. package/dist/cjs/providers/AnthropicProvider.js +328 -0
  25. package/dist/cjs/providers/AnthropicProvider.js.map +1 -0
  26. package/dist/cjs/providers/GeminiProvider.d.ts +4 -1
  27. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  28. package/dist/cjs/providers/GeminiProvider.js +96 -0
  29. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  30. package/dist/cjs/providers/OpenAIProvider.d.ts +4 -1
  31. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  32. package/dist/cjs/providers/OpenAIProvider.js +115 -0
  33. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  34. package/dist/cjs/providers/OpenRouterProvider.d.ts +4 -1
  35. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  36. package/dist/cjs/providers/OpenRouterProvider.js +115 -0
  37. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  38. package/dist/cjs/providers/index.d.ts +13 -0
  39. package/dist/cjs/providers/index.d.ts.map +1 -0
  40. package/dist/cjs/providers/index.js +16 -0
  41. package/dist/cjs/providers/index.js.map +1 -0
  42. package/dist/cjs/types/ai.d.ts +28 -0
  43. package/dist/cjs/types/ai.d.ts.map +1 -1
  44. package/dist/cjs/types/route.d.ts +6 -0
  45. package/dist/cjs/types/route.d.ts.map +1 -1
  46. package/dist/core/Agent.d.ts +37 -0
  47. package/dist/core/Agent.d.ts.map +1 -1
  48. package/dist/core/Agent.js +167 -1
  49. package/dist/core/Agent.js.map +1 -1
  50. package/dist/core/DomainRegistry.d.ts +10 -0
  51. package/dist/core/DomainRegistry.d.ts.map +1 -1
  52. package/dist/core/DomainRegistry.js +25 -0
  53. package/dist/core/DomainRegistry.js.map +1 -1
  54. package/dist/core/PromptBuilder.d.ts +9 -1
  55. package/dist/core/PromptBuilder.d.ts.map +1 -1
  56. package/dist/core/PromptBuilder.js +49 -2
  57. package/dist/core/PromptBuilder.js.map +1 -1
  58. package/dist/core/Route.d.ts +16 -0
  59. package/dist/core/Route.d.ts.map +1 -1
  60. package/dist/core/Route.js +22 -0
  61. package/dist/core/Route.js.map +1 -1
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +1 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/providers/AnthropicProvider.d.ts +43 -0
  67. package/dist/providers/AnthropicProvider.d.ts.map +1 -0
  68. package/dist/providers/AnthropicProvider.js +321 -0
  69. package/dist/providers/AnthropicProvider.js.map +1 -0
  70. package/dist/providers/GeminiProvider.d.ts +4 -1
  71. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  72. package/dist/providers/GeminiProvider.js +96 -0
  73. package/dist/providers/GeminiProvider.js.map +1 -1
  74. package/dist/providers/OpenAIProvider.d.ts +4 -1
  75. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  76. package/dist/providers/OpenAIProvider.js +115 -0
  77. package/dist/providers/OpenAIProvider.js.map +1 -1
  78. package/dist/providers/OpenRouterProvider.d.ts +4 -1
  79. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  80. package/dist/providers/OpenRouterProvider.js +115 -0
  81. package/dist/providers/OpenRouterProvider.js.map +1 -1
  82. package/dist/providers/index.d.ts +13 -0
  83. package/dist/providers/index.d.ts.map +1 -0
  84. package/dist/providers/index.js +9 -0
  85. package/dist/providers/index.js.map +1 -0
  86. package/dist/types/ai.d.ts +28 -0
  87. package/dist/types/ai.d.ts.map +1 -1
  88. package/dist/types/route.d.ts +6 -0
  89. package/dist/types/route.d.ts.map +1 -1
  90. package/docs/API_REFERENCE.md +357 -2
  91. package/docs/CONSTRUCTOR_OPTIONS.md +178 -37
  92. package/docs/GETTING_STARTED.md +10 -2
  93. package/docs/PROVIDERS.md +139 -2
  94. package/examples/business-onboarding.ts +708 -0
  95. package/examples/declarative-agent.ts +1 -1
  96. package/examples/domain-scoping.ts +267 -0
  97. package/examples/healthcare-agent.ts +4 -4
  98. package/examples/openai-agent.ts +6 -4
  99. package/examples/rules-prohibitions.ts +258 -0
  100. package/examples/streaming-agent.ts +371 -0
  101. package/examples/travel-agent.ts +7 -4
  102. package/package.json +2 -1
  103. package/src/core/Agent.ts +220 -1
  104. package/src/core/DomainRegistry.ts +30 -0
  105. package/src/core/PromptBuilder.ts +70 -3
  106. package/src/core/Route.ts +28 -0
  107. package/src/index.ts +2 -0
  108. package/src/providers/AnthropicProvider.ts +467 -0
  109. package/src/providers/GeminiProvider.ts +135 -0
  110. package/src/providers/OpenAIProvider.ts +157 -0
  111. package/src/providers/OpenRouterProvider.ts +157 -0
  112. package/src/providers/index.ts +16 -0
  113. package/src/types/ai.ts +32 -0
  114. package/src/types/route.ts +6 -0
@@ -41,48 +41,48 @@ interface AgentOptions<TContext = unknown> {
41
41
 
42
42
  ```typescript
43
43
  const agent = new Agent({
44
- name: "SupportBot",
45
- description: "Helpful customer support",
46
- goal: "Resolve issues efficiently",
47
- ai: new GeminiProvider({ apiKey: "...", model: "..." }),
48
- context: { userId: "123" },
44
+ name: 'SupportBot',
45
+ description: 'Helpful customer support',
46
+ goal: 'Resolve issues efficiently',
47
+ ai: new GeminiProvider({ apiKey: '...', model: '...' }),
48
+ context: { userId: '123' },
49
49
 
50
50
  terms: [
51
51
  {
52
- name: "SLA",
53
- description: "Service Level Agreement",
54
- synonyms: ["response time"],
52
+ name: 'SLA',
53
+ description: 'Service Level Agreement',
54
+ synonyms: ['response time'],
55
55
  },
56
56
  ],
57
57
 
58
58
  guidelines: [
59
59
  {
60
- condition: "User is frustrated",
61
- action: "Show empathy and offer escalation",
62
- tags: ["support"],
60
+ condition: 'User is frustrated',
61
+ action: 'Show empathy and offer escalation',
62
+ tags: ['support'],
63
63
  enabled: true,
64
64
  },
65
65
  ],
66
66
 
67
67
  capabilities: [
68
- { title: "Ticket Management", description: "Create and track tickets" },
68
+ { title: 'Ticket Management', description: 'Create and track tickets' },
69
69
  ],
70
70
 
71
71
  routes: [
72
72
  {
73
- title: "Create Ticket",
74
- description: "Help user create a support ticket",
75
- conditions: ["User wants to report an issue"],
73
+ title: 'Create Ticket',
74
+ description: 'Help user create a support ticket',
75
+ conditions: ['User wants to report an issue'],
76
76
  guidelines: [
77
- { condition: "Issue is urgent", action: "Prioritize immediately" },
77
+ { condition: 'Issue is urgent', action: 'Prioritize immediately' },
78
78
  ],
79
79
  },
80
80
  ],
81
81
 
82
82
  observations: [
83
83
  {
84
- description: "User mentions problem but unclear what kind",
85
- routeRefs: ["Create Ticket", "Check Ticket Status"], // By title!
84
+ description: 'User mentions problem but unclear what kind',
85
+ routeRefs: ['Create Ticket', 'Check Ticket Status'], // By title!
86
86
  },
87
87
  ],
88
88
  });
@@ -98,33 +98,49 @@ interface RouteOptions {
98
98
  title: string;
99
99
 
100
100
  // Optional
101
+ id?: string; // Custom ID (auto-generated from title if not provided)
101
102
  description?: string;
102
103
  conditions?: string[];
103
- guidelines?: Guideline[]; // NEW!
104
+ guidelines?: Guideline[];
105
+ domains?: string[]; // Restrict which domains are available in this route
106
+ rules?: string[]; // Absolute rules the agent MUST follow
107
+ prohibitions?: string[]; // Absolute prohibitions the agent MUST NEVER do
104
108
  }
105
109
  ```
106
110
 
111
+ **Domain Scoping:**
112
+ - Use `domains` to limit which registered domains (tools/methods) can be accessed during this route
113
+ - If `undefined` or omitted, all registered domains are available
114
+ - Useful for security (preventing unauthorized tool calls) and performance (reducing AI decision space)
115
+
116
+ **Rules & Prohibitions:**
117
+ - **Rules**: Absolute requirements the agent must follow in this route (style, format, behavior)
118
+ - **Prohibitions**: Things the agent must never do in this route
119
+ - These override general guidelines if there's any conflict
120
+ - Applied automatically when the route is active
121
+ - Perfect for controlling message style, tone, length, emoji usage, etc.
122
+
107
123
  ### Example: Route with Nested Guidelines
108
124
 
109
125
  ```typescript
110
126
  const agent = new Agent({
111
- name: "Bot",
127
+ name: 'Bot',
112
128
  ai: provider,
113
129
  routes: [
114
130
  {
115
- title: "Onboarding",
116
- description: "Guide new users",
117
- conditions: ["User is new"],
131
+ title: 'Onboarding',
132
+ description: 'Guide new users',
133
+ conditions: ['User is new'],
118
134
  guidelines: [
119
135
  {
120
- condition: "User skips a step",
136
+ condition: 'User skips a step',
121
137
  action: "Gently remind them it's important",
122
- tags: ["onboarding"],
138
+ tags: ['onboarding'],
123
139
  },
124
140
  {
125
- condition: "User seems confused",
126
- action: "Offer a quick tutorial video",
127
- tags: ["help"],
141
+ condition: 'User seems confused',
142
+ action: 'Offer a quick tutorial video',
143
+ tags: ['help'],
128
144
  },
129
145
  ],
130
146
  },
@@ -132,6 +148,131 @@ const agent = new Agent({
132
148
  });
133
149
  ```
134
150
 
151
+ ### Example: Route with Domain Scoping
152
+
153
+ ```typescript
154
+ // Register domains
155
+ agent.addDomain('scraping', {
156
+ scrapeSite: async (url: string) => {
157
+ /* ... */
158
+ },
159
+ extractData: async (html: string) => {
160
+ /* ... */
161
+ },
162
+ });
163
+
164
+ agent.addDomain('calendar', {
165
+ scheduleEvent: async (date: Date, title: string) => {
166
+ /* ... */
167
+ },
168
+ listEvents: async () => {
169
+ /* ... */
170
+ },
171
+ });
172
+
173
+ agent.addDomain('payment', {
174
+ processPayment: async (amount: number) => {
175
+ /* ... */
176
+ },
177
+ });
178
+
179
+ // Create routes with domain restrictions
180
+ agent.createRoute({
181
+ title: 'Data Collection',
182
+ description: 'Collect and process web data',
183
+ domains: ['scraping'], // ✅ Only scraping tools available
184
+ });
185
+
186
+ agent.createRoute({
187
+ title: 'Schedule Meeting',
188
+ description: 'Book appointments',
189
+ domains: ['calendar'], // ✅ Only calendar tools available
190
+ });
191
+
192
+ agent.createRoute({
193
+ title: 'Checkout',
194
+ description: 'Process purchase',
195
+ domains: ['payment', 'calendar'], // ✅ Multiple domains allowed
196
+ });
197
+
198
+ agent.createRoute({
199
+ title: 'FAQ Support',
200
+ description: 'Answer general questions',
201
+ domains: [], // ✅ No tools available (conversation only)
202
+ });
203
+
204
+ agent.createRoute({
205
+ title: 'Admin Support',
206
+ description: 'Administrative tasks',
207
+ // domains not specified = all domains available (for demo purposes)
208
+ });
209
+ ```
210
+
211
+ ### Example: Route with Rules & Prohibitions
212
+
213
+ ```typescript
214
+ // WhatsApp support bot with different styles per route
215
+ agent.createRoute({
216
+ title: 'Customer Support',
217
+ description: 'Help customers with issues',
218
+ domains: [],
219
+ rules: [
220
+ 'Keep messages short (maximum 2 lines per message)',
221
+ 'Use maximum 1 emoji per message',
222
+ 'Always ask if the issue is resolved before ending',
223
+ 'Professional but friendly tone'
224
+ ],
225
+ prohibitions: [
226
+ 'Never send messages longer than 3 paragraphs',
227
+ 'Do not use slang or informal language',
228
+ 'Never promise what you cannot deliver',
229
+ 'Do not ask for sensitive information via chat'
230
+ ]
231
+ });
232
+
233
+ agent.createRoute({
234
+ title: 'Sales Consultation',
235
+ description: 'Help customer discover needs and present solutions',
236
+ domains: ['calendar', 'analytics'],
237
+ rules: [
238
+ 'Ask open-ended questions to discover needs',
239
+ 'Use storytelling when presenting solutions',
240
+ 'Emoji only to reinforce positive emotions 😊',
241
+ 'Always present value before mentioning price'
242
+ ],
243
+ prohibitions: [
244
+ 'Never talk about price before showing value',
245
+ 'Do not pressure the customer',
246
+ 'Avoid complex technical terms',
247
+ 'Never send more than 2 messages in a row without customer response'
248
+ ]
249
+ });
250
+
251
+ agent.createRoute({
252
+ title: 'Emergency Support',
253
+ description: 'Handle urgent customer issues',
254
+ domains: ['notifications', 'ticketing'],
255
+ rules: [
256
+ 'Respond immediately and acknowledge urgency',
257
+ 'Use clear, direct language',
258
+ 'Provide concrete next steps',
259
+ 'Set clear expectations on resolution time'
260
+ ],
261
+ prohibitions: [
262
+ 'Never downplay the customer\'s concern',
263
+ 'Do not use emojis',
264
+ 'Never say "calm down" or similar phrases',
265
+ 'Do not transfer without explaining why'
266
+ ]
267
+ });
268
+ ```
269
+
270
+ **How it works:**
271
+ - Rules and prohibitions are automatically applied when the route is active
272
+ - They override general guidelines if there's any conflict
273
+ - Perfect for controlling communication style per context
274
+ - Applied in the AI prompt to ensure compliance
275
+
135
276
  ---
136
277
 
137
278
  ## 🔍 Observation Options
@@ -175,14 +316,14 @@ All constructor options also have fluent methods that **return `this`** for chai
175
316
 
176
317
  ```typescript
177
318
  agent
178
- .createTerm({ name: "API", description: "..." })
179
- .createGuideline({ condition: "...", action: "..." })
180
- .createCapability({ title: "...", description: "..." });
319
+ .createTerm({ name: 'API', description: '...' })
320
+ .createGuideline({ condition: '...', action: '...' })
321
+ .createCapability({ title: '...', description: '...' });
181
322
 
182
- const route = agent.createRoute({ title: "..." });
183
- route.createGuideline({ condition: "...", action: "..." });
323
+ const route = agent.createRoute({ title: '...' });
324
+ route.createGuideline({ condition: '...', action: '...' });
184
325
 
185
- const obs = agent.createObservation("User intent unclear");
326
+ const obs = agent.createObservation('User intent unclear');
186
327
  obs.disambiguate([route1, route2]);
187
328
  ```
188
329
 
@@ -209,7 +350,7 @@ obs.disambiguate([route1, route2]);
209
350
  ```typescript
210
351
  // Start with static config
211
352
  const agent = new Agent({
212
- name: "Bot",
353
+ name: 'Bot',
213
354
  ai: provider,
214
355
  terms: loadTermsFromFile(),
215
356
  guidelines: loadGuidelinesFromDB(),
@@ -218,8 +359,8 @@ const agent = new Agent({
218
359
  // Add dynamic features
219
360
  if (user.isPremium) {
220
361
  agent.createGuideline({
221
- condition: "User asks for priority support",
222
- action: "Escalate immediately to premium team",
362
+ condition: 'User asks for priority support',
363
+ action: 'Escalate immediately to premium team',
223
364
  });
224
365
  }
225
366
  ```
@@ -154,7 +154,9 @@ const onboardingRoute = agent.createRoute({
154
154
  conditions: ["User is new and needs onboarding"],
155
155
  });
156
156
 
157
- // Build the flow
157
+ // Build the flow - two approaches:
158
+
159
+ // Approach 1: Step-by-step (great for complex flows with branching)
158
160
  const step1 = onboardingRoute.initialState.transitionTo({
159
161
  chatState: "Ask for user's name",
160
162
  });
@@ -167,8 +169,14 @@ const step3 = step2.transitionTo({
167
169
  chatState: "Confirm details and welcome user",
168
170
  });
169
171
 
170
- // End the route
171
172
  step3.transitionTo({ state: END_ROUTE });
173
+
174
+ // Approach 2: Fluent chaining (concise for linear flows)
175
+ onboardingRoute.initialState
176
+ .transitionTo({ chatState: "Ask for user's name" })
177
+ .transitionTo({ chatState: "Ask for user's email" })
178
+ .transitionTo({ chatState: "Confirm details and welcome user" })
179
+ .transitionTo({ state: END_ROUTE });
172
180
  ```
173
181
 
174
182
  ### Handle Context Dynamically
package/docs/PROVIDERS.md CHANGED
@@ -10,11 +10,111 @@ This guide covers the available AI providers and how to configure them for optim
10
10
  - ✅ Configure provider-specific settings
11
11
  - ✅ Use backup models for failover
12
12
  - ✅ Customize retry logic and timeouts
13
+ - ⚡ **Stream responses in real-time** (all providers)
14
+
15
+ ## Streaming Support
16
+
17
+ **All providers support real-time streaming** via the `respondStream()` method on the Agent class.
18
+
19
+ Streaming provides:
20
+
21
+ - 🌊 Real-time text generation for better UX
22
+ - 📊 Incremental delivery with `delta` and `accumulated` properties
23
+ - 🛑 Cancellable streams using AbortSignal
24
+ - ✅ Full compatibility with routes, states, and tool calls
25
+
26
+ **Example:**
27
+
28
+ ```typescript
29
+ for await (const chunk of agent.respondStream({ history })) {
30
+ process.stdout.write(chunk.delta); // Print incremental text
31
+
32
+ if (chunk.done) {
33
+ // Access final metadata
34
+ console.log("Route:", chunk.route?.title);
35
+ console.log("Tool calls:", chunk.toolCalls?.length);
36
+ }
37
+ }
38
+ ```
39
+
40
+ See [streaming-agent.ts](../examples/streaming-agent.ts) for comprehensive examples with all providers.
13
41
 
14
42
  ---
15
43
 
16
44
  ## Available Providers
17
45
 
46
+ ### 🤖 Anthropic (Claude)
47
+
48
+ **Package:** `@anthropic-ai/sdk`
49
+
50
+ #### Overview
51
+
52
+ Anthropic's Claude models are known for their exceptional reasoning, analysis, and long context windows. Claude 3.5 Sonnet offers:
53
+
54
+ - State-of-the-art reasoning and analysis
55
+ - 200K context window
56
+ - Excellent at following complex instructions
57
+ - Strong coding and writing capabilities
58
+
59
+ #### Installation
60
+
61
+ ```bash
62
+ bun add @anthropic-ai/sdk
63
+ # or
64
+ npm install @anthropic-ai/sdk
65
+ ```
66
+
67
+ #### Basic Usage
68
+
69
+ ```typescript
70
+ import { AnthropicProvider } from "@falai/agent";
71
+
72
+ const provider = new AnthropicProvider({
73
+ apiKey: process.env.ANTHROPIC_API_KEY!,
74
+ model: "claude-sonnet-4-5", // Latest Claude 4.5 Sonnet
75
+ });
76
+ ```
77
+
78
+ #### Configuration Options
79
+
80
+ All models are specified by the user - see [Anthropic Models](https://docs.anthropic.com/en/docs/models-overview) for available options.
81
+
82
+ ```typescript
83
+ const provider = new AnthropicProvider({
84
+ // Required
85
+ apiKey: string;
86
+ model: string; // e.g., "claude-sonnet-4-5", "claude-opus-4-1", etc.
87
+
88
+ // Optional
89
+ backupModels?: string[]; // Default: []
90
+ config?: Partial<Omit<MessageCreateParamsNonStreaming, "model" | "messages" | "max_tokens">>; // Uses @anthropic-ai/sdk types
91
+ retryConfig?: {
92
+ timeout?: number; // Default: 60000ms (60s)
93
+ retries?: number; // Default: 3
94
+ };
95
+ });
96
+ ```
97
+
98
+ #### Example: Advanced Configuration
99
+
100
+ ```typescript
101
+ const provider = new AnthropicProvider({
102
+ apiKey: process.env.ANTHROPIC_API_KEY!,
103
+ model: "claude-sonnet-4-5",
104
+ backupModels: ["claude-opus-4-1", "claude-sonnet-4-0"],
105
+ config: {
106
+ temperature: 0.7,
107
+ top_p: 0.9,
108
+ },
109
+ retryConfig: {
110
+ timeout: 45000,
111
+ retries: 2,
112
+ },
113
+ });
114
+ ```
115
+
116
+ ---
117
+
18
118
  ### 🌐 OpenRouter (Multi-Model Access)
19
119
 
20
120
  **Package:** `openai` (OpenRouter uses OpenAI-compatible API)
@@ -274,7 +374,22 @@ const provider = new OpenAIProvider({
274
374
  You can easily switch between providers:
275
375
 
276
376
  ```typescript
277
- import { Agent, GeminiProvider, OpenAIProvider } from "@falai/agent";
377
+ import {
378
+ Agent,
379
+ AnthropicProvider,
380
+ GeminiProvider,
381
+ OpenAIProvider,
382
+ OpenRouterProvider,
383
+ } from "@falai/agent";
384
+
385
+ // Use Anthropic (Claude)
386
+ const claudeAgent = new Agent({
387
+ name: "Claude Assistant",
388
+ ai: new AnthropicProvider({
389
+ apiKey: process.env.ANTHROPIC_API_KEY!,
390
+ model: "claude-sonnet-4-5",
391
+ }),
392
+ });
278
393
 
279
394
  // Use Gemini
280
395
  const geminiAgent = new Agent({
@@ -290,10 +405,20 @@ const openaiAgent = new Agent({
290
405
  name: "OpenAI Assistant",
291
406
  ai: new OpenAIProvider({
292
407
  apiKey: process.env.OPENAI_API_KEY!,
408
+ model: "gpt-5",
293
409
  }),
294
410
  });
295
411
 
296
- // Both agents have the same interface!
412
+ // Use OpenRouter (access to 200+ models)
413
+ const openrouterAgent = new Agent({
414
+ name: "OpenRouter Assistant",
415
+ ai: new OpenRouterProvider({
416
+ apiKey: process.env.OPENROUTER_API_KEY!,
417
+ model: "anthropic/claude-sonnet-4-5",
418
+ }),
419
+ });
420
+
421
+ // All agents have the same interface!
297
422
  ```
298
423
 
299
424
  ---
@@ -304,8 +429,10 @@ It's recommended to store API keys in environment variables:
304
429
 
305
430
  ```bash
306
431
  # .env
432
+ ANTHROPIC_API_KEY=your-anthropic-api-key-here
307
433
  GEMINI_API_KEY=your-gemini-api-key-here
308
434
  OPENAI_API_KEY=your-openai-api-key-here
435
+ OPENROUTER_API_KEY=your-openrouter-api-key-here
309
436
  ```
310
437
 
311
438
  Then load them:
@@ -314,6 +441,11 @@ Then load them:
314
441
  import { config } from "dotenv";
315
442
  config();
316
443
 
444
+ const anthropicProvider = new AnthropicProvider({
445
+ apiKey: process.env.ANTHROPIC_API_KEY!,
446
+ model: "claude-sonnet-4-5",
447
+ });
448
+
317
449
  const geminiProvider = new GeminiProvider({
318
450
  apiKey: process.env.GEMINI_API_KEY!,
319
451
  model: "models/gemini-2.5-flash",
@@ -323,6 +455,11 @@ const openaiProvider = new OpenAIProvider({
323
455
  apiKey: process.env.OPENAI_API_KEY!,
324
456
  model: "gpt-5",
325
457
  });
458
+
459
+ const openrouterProvider = new OpenRouterProvider({
460
+ apiKey: process.env.OPENROUTER_API_KEY!,
461
+ model: "anthropic/claude-sonnet-4-5",
462
+ });
326
463
  ```
327
464
 
328
465
  ---