agentic-ai-framework 1.0.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,626 @@
1
+ # @insider/agent-framework
2
+
3
+ Reusable agentic framework for Node.js (ES Modules). Provides session memory, LLM-driven tool-calling, Chain-of-Thought, and multi-agent team coordination with pluggable LLM providers.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```js
10
+ // In another package inside the monorepo
11
+ import { createAgent, createTeam, Tool } from '@insider/agent-framework';
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Quick Start
17
+
18
+ ```js
19
+ import 'dotenv/config';
20
+ import { createAgent, Tool } from '@insider/agent-framework';
21
+
22
+ const agent = createAgent({
23
+ name: 'my-agent',
24
+ provider: 'grok', // 'grok' | 'claude' | 'openai'
25
+ apiKey: process.env.GROK_API_KEY,
26
+ systemPromptTemplate: 'You are a helpful assistant for ${userName}.',
27
+ chainOfThought: true,
28
+ });
29
+
30
+ agent.registerTool(new Tool({
31
+ name: 'get_data',
32
+ description: 'Fetch data by ID',
33
+ parameters: {
34
+ type: 'object',
35
+ properties: { id: { type: 'string' } },
36
+ required: ['id'],
37
+ },
38
+ handler: async ({ id }) => `Data for ${id}`,
39
+ }));
40
+
41
+ agent.setContext('userName', 'Alice');
42
+ const result = await agent.run('Fetch data for item-42');
43
+ console.log(result.text);
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Core Concepts
49
+
50
+ ### Agent
51
+
52
+ The main class. Each agent owns an LLM provider, tool registry, session memory, and a prompt builder.
53
+
54
+ **One instance per request** — create a fresh agent per HTTP request. Instances have no shared mutable state between themselves.
55
+
56
+ ```js
57
+ import { createAgent } from '@insider/agent-framework';
58
+
59
+ const agent = createAgent(options); // shorthand for: new Agent(new AgentConfig(options))
60
+ ```
61
+
62
+ ### AgentConfig Options
63
+
64
+ All options passed to `createAgent()`. Unknown keys throw an error (strict validation).
65
+
66
+ | Option | Type | Default | Description |
67
+ |--------|------|---------|-------------|
68
+ | `name` | `string` | **required** | Unique agent name |
69
+ | `provider` | `'grok'│'claude'│'openai'` | **required** | LLM provider |
70
+ | `apiKey` | `string` | **required** | Provider API key |
71
+ | `systemPromptTemplate` | `string` | one of these required | Inline system prompt with `${var}` placeholders |
72
+ | `systemPromptFile` | `string` | one of these required | Path to `.md`/`.txt` prompt file |
73
+ | `model` | `string` | provider default | Model ID |
74
+ | `temperature` | `number` | `0.1` | Sampling temperature (0–2) |
75
+ | `maxTokens` | `number` | `4000` | Max output tokens |
76
+ | `maxToolIterations` | `number` | `5` | Max tool-calling loop iterations |
77
+ | `loopTimeoutMs` | `number` | `300000` | Tool loop timeout in ms (5 min) |
78
+ | `requestTimeoutMs` | `number` | provider default | Individual LLM request timeout |
79
+ | `maxHistoryMessages` | `number` | `50` | Max session history messages |
80
+ | `persistenceDir` | `string` | `null` | Directory for session JSON files |
81
+ | `chainOfThought` | `boolean` | `true` | Inject CoT reasoning block into prompt |
82
+ | `cotMode` | `'prompt'│'reflect'` | `'prompt'` | CoT strategy |
83
+ | `cotStyle` | `'step-by-step'│'pros-cons'│'custom'` | `'step-by-step'` | CoT block style |
84
+ | `cotCustomInstructions` | `string` | `null` | Custom CoT text (when `cotStyle='custom'`) |
85
+ | `description` | `string` | `''` | Agent description (used by AgentTeam) |
86
+ | `outputSchema` | `object` | `null` | JSON Schema for structured output |
87
+
88
+ ---
89
+
90
+ ## Tools
91
+
92
+ ### Defining a Tool
93
+
94
+ ```js
95
+ import { Tool } from '@insider/agent-framework';
96
+
97
+ const myTool = new Tool({
98
+ name: 'search_docs', // snake_case, unique
99
+ description: 'Search documentation', // shown to the LLM — be descriptive
100
+ parameters: { // JSON Schema object
101
+ type: 'object',
102
+ properties: {
103
+ query: { type: 'string', description: 'Search query' },
104
+ limit: { type: 'number', description: 'Max results' },
105
+ strict: { type: 'boolean', description: 'Exact match only' },
106
+ },
107
+ required: ['query'],
108
+ },
109
+ handler: async ({ query, limit = 10, strict }) => {
110
+ // Do real work here
111
+ return `Results for "${query}"`; // return string or JSON-serializable object
112
+ },
113
+ });
114
+ ```
115
+
116
+ **Zod schema** is also accepted for `parameters`:
117
+
118
+ ```js
119
+ import { z } from 'zod';
120
+
121
+ const myTool = new Tool({
122
+ name: 'create_ticket',
123
+ description: 'Create a support ticket',
124
+ parameters: z.object({
125
+ title: z.string(),
126
+ priority: z.enum(['low', 'medium', 'high']),
127
+ assignee: z.string().optional(),
128
+ }),
129
+ handler: async ({ title, priority, assignee }) => {
130
+ // ...
131
+ },
132
+ });
133
+ ```
134
+
135
+ Supported Zod types: `z.string()`, `z.number()`, `z.boolean()`, `z.array()`, `z.enum()`, `z.object()`, `z.optional()`, `z.nullable()`, `z.default()`. All others throw — use a plain JSON Schema object for complex types.
136
+
137
+ ### Registering Tools
138
+
139
+ ```js
140
+ agent.registerTool(myTool); // single tool
141
+ agent.registerTools([tool1, tool2]); // multiple tools — both return agent (chainable)
142
+
143
+ // Chainable
144
+ agent
145
+ .registerTool(searchTool)
146
+ .registerTool(createTool);
147
+ ```
148
+
149
+ ### Handler Contract
150
+
151
+ - Receives parsed argument object from the LLM
152
+ - Returns `string` or any JSON-serializable value (objects are auto-stringified)
153
+ - Throwing an error causes the runner to report the error to the LLM as the tool result — the LLM can then decide how to recover
154
+
155
+ ---
156
+
157
+ ## Session Memory
158
+
159
+ ### Stateful (Session) Pattern
160
+
161
+ ```js
162
+ // Start or resume a named session
163
+ const sessionId = await agent.startSession('user-123');
164
+
165
+ // Inject variables into system prompt as ${key}
166
+ agent.setContext('userName', 'Alice');
167
+ agent.setContext('role', 'admin');
168
+
169
+ const r1 = await agent.run('What tickets are assigned to me?');
170
+ const r2 = await agent.run('Show only the high-priority ones.'); // remembers previous turn
171
+
172
+ await agent.saveSession(); // persist to disk (requires persistenceDir in config)
173
+ await agent.endSession(); // clear in-memory state
174
+ // await agent.endSession(true); // also delete the file on disk
175
+ ```
176
+
177
+ Resuming a session restores history and context from disk:
178
+
179
+ ```js
180
+ // Next request — session restored automatically
181
+ await agent.startSession('user-123'); // loads history from {persistenceDir}/user-123.json
182
+ ```
183
+
184
+ ### Stateless (Per-Request) Pattern
185
+
186
+ ```js
187
+ // No startSession() needed — pass appendToHistory: false
188
+ const result = await agent.run(userInput, { appendToHistory: false });
189
+ ```
190
+
191
+ ### Context Values
192
+
193
+ `setContext(key, value)` injects values into system prompt `${key}` placeholders. Values must be JSON-serializable (strings, numbers, booleans, arrays, plain objects). Functions and Symbols are rejected.
194
+
195
+ ```js
196
+ agent.setContext('companyName', 'Insider');
197
+ agent.setContext('userTier', 'enterprise');
198
+ // System prompt: "You are an assistant for ${companyName} users on the ${userTier} plan."
199
+ // Rendered as: "You are an assistant for Insider users on the enterprise plan."
200
+ ```
201
+
202
+ ---
203
+
204
+ ## AgentResult
205
+
206
+ Every `agent.run()` returns an `AgentResult`:
207
+
208
+ ```js
209
+ {
210
+ success: true, // false if LLM failed or max iterations reached
211
+ text: 'Final answer...', // convenience: best text representation of the answer
212
+ content: 'Raw LLM output', // raw text from the last LLM response
213
+ parsed: null, // parsed JSON when outputSchema is set
214
+ toolCallHistory: [ // all tool calls that happened in this run
215
+ {
216
+ id: 'call_abc',
217
+ name: 'get_data',
218
+ arguments: { id: 'item-42' },
219
+ result: 'Data for item-42',
220
+ iteration: 1,
221
+ timestamp: '2026-03-13T10:00:00.000Z',
222
+ }
223
+ ],
224
+ usage: {
225
+ promptTokens: 120,
226
+ completionTokens: 45,
227
+ totalTokens: 165,
228
+ },
229
+ iterations: 1, // number of tool-calling iterations
230
+ error: undefined, // error message when success=false
231
+ cotTrace: undefined, // present when cotMode='reflect'
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Chain of Thought (CoT)
238
+
239
+ ### Prompt Mode (default)
240
+
241
+ A reasoning block is appended to the system prompt. Zero extra LLM calls.
242
+
243
+ ```js
244
+ createAgent({
245
+ // ...
246
+ chainOfThought: true,
247
+ cotMode: 'prompt', // default
248
+ cotStyle: 'step-by-step', // default
249
+ });
250
+ ```
251
+
252
+ Available styles:
253
+ - `'step-by-step'` — numbered reasoning steps before answering
254
+ - `'pros-cons'` — trade-off analysis before deciding
255
+ - `'custom'` — provide your own instructions via `cotCustomInstructions`
256
+
257
+ ### Reflect Mode
258
+
259
+ After the tool-calling loop produces a final answer, a second LLM call verifies it. Use for high-stakes agents where accuracy matters more than cost.
260
+
261
+ ```js
262
+ createAgent({
263
+ // ...
264
+ chainOfThought: true,
265
+ cotMode: 'reflect',
266
+ });
267
+
268
+ // result.cotTrace = { original, reflected, changed: true/false }
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Multi-Agent Teams
274
+
275
+ ### Router Mode
276
+
277
+ The coordinator LLM decides which specialist(s) to call via tool-calling. Maps to the existing MasterAgent pattern.
278
+
279
+ ```js
280
+ import { createAgent, createTeam } from '@insider/agent-framework';
281
+
282
+ const sqlAgent = createAgent({
283
+ name: 'sql-agent',
284
+ provider: 'grok',
285
+ apiKey: process.env.GROK_API_KEY,
286
+ description: 'Answers questions by generating SQL queries',
287
+ systemPromptTemplate: 'You are a SQL specialist. Table: tickets(id, status, priority).',
288
+ });
289
+
290
+ const ragAgent = createAgent({
291
+ name: 'rag-agent',
292
+ provider: 'grok',
293
+ apiKey: process.env.GROK_API_KEY,
294
+ description: 'Searches documentation for policy questions',
295
+ systemPromptTemplate: 'You are a knowledge base specialist.',
296
+ });
297
+
298
+ const coordinator = createAgent({
299
+ name: 'coordinator',
300
+ provider: 'grok',
301
+ apiKey: process.env.GROK_API_KEY,
302
+ systemPromptTemplate: `You orchestrate specialist agents.
303
+ Available specialists:
304
+ \${teamMembers}
305
+ Always delegate to the most appropriate specialist.`,
306
+ });
307
+
308
+ const team = createTeam({
309
+ coordinator,
310
+ members: [sqlAgent, ragAgent],
311
+ mode: 'router', // default
312
+ });
313
+
314
+ const result = await team.run('How many open tickets are there?');
315
+ console.log(result.final); // final synthesized answer
316
+ console.log(result.memberResults); // per-member results keyed by agent name
317
+ ```
318
+
319
+ The `${teamMembers}` placeholder in the coordinator's system prompt is auto-populated with the member list.
320
+
321
+ ### Parallel Mode
322
+
323
+ All members run simultaneously. The coordinator synthesizes all responses.
324
+
325
+ ```js
326
+ const team = createTeam({
327
+ coordinator: synthesizerAgent,
328
+ members: [sqlAgent, ragAgent],
329
+ mode: 'parallel',
330
+ });
331
+
332
+ const result = await team.run('How many critical tickets are open and what is the SLA?');
333
+ // sqlAgent and ragAgent run in parallel, coordinator combines both answers
334
+ ```
335
+
336
+ Use parallel mode when a question genuinely needs multiple specialists. Use router when only one specialist is needed per question.
337
+
338
+ ### TeamResult
339
+
340
+ ```js
341
+ {
342
+ success: true,
343
+ final: 'Synthesized answer...',
344
+ memberResults: {
345
+ 'sql-agent': { success: true, text: '...', content: '...', toolCallHistory: [] },
346
+ 'rag-agent': { success: true, text: '...', content: '...', toolCallHistory: [] },
347
+ },
348
+ coordinatorResult: { /* AgentResult */ },
349
+ mode: 'router',
350
+ error: null,
351
+ }
352
+
353
+ // Helper methods
354
+ result.getMemberResult('sql-agent'); // get one member's result
355
+ result.getSuccessfulMembers(); // ['sql-agent', 'rag-agent']
356
+ ```
357
+
358
+ ### Dynamic Member Management
359
+
360
+ ```js
361
+ team.addMember(analyticsAgent); // add at runtime
362
+ team.removeMember('sql-agent'); // remove by name
363
+ team.getMembers(); // ['rag-agent', 'analytics-agent']
364
+ team.getInfo(); // coordinator + members info + mode
365
+ ```
366
+
367
+ ---
368
+
369
+ ## LLM Providers
370
+
371
+ ### Built-in Providers
372
+
373
+ | Name | API | Default Model |
374
+ |------|-----|---------------|
375
+ | `'grok'` | xAI / OpenAI-compatible | `grok-code-fast-1` |
376
+ | `'claude'` | Anthropic Messages API | `claude-sonnet-4-20250514` |
377
+ | `'openai'` | OpenAI Chat Completions | `gpt-4o` |
378
+
379
+ ```js
380
+ // Grok
381
+ createAgent({ provider: 'grok', apiKey: process.env.GROK_API_KEY, model: 'grok-2', ... });
382
+
383
+ // Claude
384
+ createAgent({ provider: 'claude', apiKey: process.env.ANTHROPIC_API_KEY, model: 'claude-opus-4-20250514', ... });
385
+
386
+ // OpenAI
387
+ createAgent({ provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o-mini', ... });
388
+ ```
389
+
390
+ Provider instances are cached by `(provider, model, apiKey)` — the same combination always returns the same instance.
391
+
392
+ ### Custom Provider
393
+
394
+ ```js
395
+ import { BaseLLMProvider, LLMRouter } from '@insider/agent-framework';
396
+
397
+ class MyProvider extends BaseLLMProvider {
398
+ constructor(apiKey, model = 'my-model') {
399
+ super();
400
+ this.apiKey = apiKey;
401
+ this.model = model;
402
+ }
403
+
404
+ async complete(prompt, options = {}) {
405
+ const messages = options.messages ?? [{ role: 'user', content: prompt }];
406
+ // call your API...
407
+ return {
408
+ content: 'response text',
409
+ parsed: null,
410
+ usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
411
+ model: this.model,
412
+ finishReason: 'stop',
413
+ toolCalls: undefined,
414
+ messages: [...messages, { role: 'assistant', content: 'response text' }],
415
+ };
416
+ }
417
+
418
+ async completeWithSchema(prompt, schema, options = {}) { /* ... */ }
419
+ async testConnection() { return true; }
420
+ }
421
+
422
+ LLMRouter.register('my-provider', MyProvider);
423
+
424
+ // Now usable in createAgent
425
+ createAgent({ provider: 'my-provider', apiKey: '...', ... });
426
+ ```
427
+
428
+ ---
429
+
430
+ ## Structured Output
431
+
432
+ Force the LLM to respond with a specific JSON shape:
433
+
434
+ ```js
435
+ const agent = createAgent({
436
+ // ...
437
+ outputSchema: {
438
+ type: 'object',
439
+ properties: {
440
+ answer: { type: 'string' },
441
+ confidence: { type: 'number' },
442
+ sources: { type: 'array', items: { type: 'string' } },
443
+ },
444
+ required: ['answer', 'confidence'],
445
+ },
446
+ });
447
+
448
+ const result = await agent.run('What is our refund policy?');
449
+ console.log(result.parsed.answer); // string
450
+ console.log(result.parsed.confidence); // number
451
+ ```
452
+
453
+ ---
454
+
455
+ ## Error Handling
456
+
457
+ Framework throws typed errors — catch them specifically:
458
+
459
+ ```js
460
+ import {
461
+ AgentError, ToolError, LLMError, ConfigError, MemoryError
462
+ } from '@insider/agent-framework';
463
+
464
+ try {
465
+ const result = await agent.run(userInput);
466
+ if (!result.success) {
467
+ console.error('Agent failed:', result.error);
468
+ }
469
+ } catch (err) {
470
+ if (err instanceof LLMError) { /* API key bad, network down, etc. */ }
471
+ if (err instanceof ToolError) { /* tool registration or execution issue */ }
472
+ if (err instanceof MemoryError) { /* session load/save failed */ }
473
+ if (err instanceof ConfigError) { /* bad AgentConfig options */ }
474
+ if (err instanceof AgentError) { /* other agent-level issue */ }
475
+ }
476
+ ```
477
+
478
+ `agent.run()` itself does **not** throw on LLM failures — it returns `{ success: false, error: '...' }`. It only throws for programming errors (wrong arguments, missing session, etc.).
479
+
480
+ Transient LLM errors (rate limits, 5xx, timeouts) are **automatically retried** up to 2 times with exponential backoff before failing.
481
+
482
+ ---
483
+
484
+ ## Logging
485
+
486
+ Structured JSON logging via pino. Set log level with the `AGENT_LOG_LEVEL` environment variable.
487
+
488
+ ```bash
489
+ AGENT_LOG_LEVEL=debug node app.js # debug | info | warn | error | silent
490
+ ```
491
+
492
+ In development, if `pino-pretty` is installed, logs are pretty-printed. In production (`NODE_ENV=production`) plain JSON is used regardless.
493
+
494
+ ---
495
+
496
+ ## Complete Backend API Handler Example
497
+
498
+ ```js
499
+ import { createAgent, Tool, AgentError } from '@insider/agent-framework';
500
+ import { queryDatabase } from './db.js';
501
+
502
+ // Agent definition is typically created once at module load
503
+ function buildSQLAgent() {
504
+ const agent = createAgent({
505
+ name: 'sql-agent',
506
+ provider: 'grok',
507
+ apiKey: process.env.GROK_API_KEY,
508
+ systemPromptTemplate: `You are a SQL specialist for ${`\${companyName}`}.
509
+ Table: zendesk_tickets(id, status, assignee, created_at, priority, subject)`,
510
+ chainOfThought: true,
511
+ maxToolIterations: 3,
512
+ });
513
+
514
+ agent.registerTool(new Tool({
515
+ name: 'run_sql',
516
+ description: 'Execute a SQL query and return results',
517
+ parameters: {
518
+ type: 'object',
519
+ properties: { sql: { type: 'string', description: 'SQL query to execute' } },
520
+ required: ['sql'],
521
+ },
522
+ handler: async ({ sql }) => {
523
+ const rows = await queryDatabase(sql);
524
+ return JSON.stringify(rows);
525
+ },
526
+ }));
527
+
528
+ return agent;
529
+ }
530
+
531
+ // Express / Fastify handler
532
+ export async function handleQuestion(req, res) {
533
+ const { question, sessionId, companyName } = req.body;
534
+
535
+ // Fresh agent per request — no shared state
536
+ const agent = buildSQLAgent();
537
+ agent.setContext('companyName', companyName);
538
+
539
+ let activeSessionId;
540
+ try {
541
+ activeSessionId = await agent.startSession(sessionId); // restores history if exists
542
+ const result = await agent.run(question);
543
+
544
+ if (!result.success) {
545
+ return res.status(500).json({ error: result.error });
546
+ }
547
+
548
+ await agent.saveSession();
549
+
550
+ return res.json({
551
+ answer: result.text,
552
+ sessionId: activeSessionId,
553
+ toolsUsed: result.toolCallHistory.map(t => t.name),
554
+ });
555
+
556
+ } catch (err) {
557
+ return res.status(500).json({ error: err.message });
558
+ } finally {
559
+ await agent.endSession(); // always clear in-memory state
560
+ }
561
+ }
562
+ ```
563
+
564
+ ---
565
+
566
+ ## Public API Reference
567
+
568
+ ```
569
+ createAgent(options) → Agent
570
+ createTeam(options) → AgentTeam
571
+
572
+ Agent
573
+ .registerTool(tool) → Agent (chainable)
574
+ .registerTools(tools[]) → Agent (chainable)
575
+ .getToolRegistry() → ToolRegistry
576
+ .startSession(sessionId?) → Promise<string>
577
+ .saveSession() → Promise<void>
578
+ .endSession(deletePersisted?) → Promise<void>
579
+ .setContext(key, value) → Agent (chainable)
580
+ .getContext(key) → any
581
+ .run(input, opts?) → Promise<AgentResult>
582
+ .getInfo() → Object
583
+ .testConnection() → Promise<boolean>
584
+
585
+ AgentTeam
586
+ .addMember(agent) → void
587
+ .removeMember(name) → void
588
+ .getMembers() → string[]
589
+ .run(input, opts?) → Promise<TeamResult>
590
+ .getInfo() → Object
591
+
592
+ Tool
593
+ new Tool({ name, description, parameters, handler })
594
+ .toDefinition() → { name, description, parameters }
595
+ .execute(args) → Promise<string | object>
596
+
597
+ ToolRegistry
598
+ .register(tool) → void (throws if duplicate)
599
+ .registerOrReplace(tool) → void
600
+ .unregister(name) → void
601
+ .has(name) → boolean
602
+ .listNames() → string[]
603
+ .getDefinitions() → Array
604
+ .execute(name, args) → Promise<string>
605
+
606
+ LLMRouter
607
+ .get(provider, model, apiKey) → BaseLLMProvider
608
+ .register(name, Class) → void
609
+ .clearCache() → void
610
+ .listProviders() → string[]
611
+
612
+ SessionMemory
613
+ .appendExchange(user, assistant) → void
614
+ .getHistory() → Array
615
+ .setContext(key, value) → void
616
+ .getContext(key) → any
617
+ .snapshot() → Object
618
+ .restore(snapshot) → void
619
+ .clear() → void
620
+
621
+ MemoryManager
622
+ .load(sessionId) → Promise<Object | null>
623
+ .save(sessionId, snapshot) → Promise<void>
624
+ .delete(sessionId) → Promise<void>
625
+ .list() → Promise<string[]>
626
+ ```
package/index.js ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @insider/agent-framework
3
+ *
4
+ * Public API surface. Import from this file:
5
+ * import { createAgent, Agent, Tool, AgentTeam } from '@insider/agent-framework';
6
+ */
7
+
8
+ // ── Core ──────────────────────────────────────────────────────────────────────
9
+ export { Agent } from './src/agent/Agent.js';
10
+ export { AgentConfig } from './src/agent/AgentConfig.js';
11
+ export { AgentRunner } from './src/agent/AgentRunner.js';
12
+
13
+ // ── Memory ────────────────────────────────────────────────────────────────────
14
+ export { SessionMemory } from './src/memory/SessionMemory.js';
15
+ export { MemoryManager } from './src/memory/MemoryManager.js';
16
+ export { FileStore } from './src/memory/FileStore.js';
17
+
18
+ // ── Tools ─────────────────────────────────────────────────────────────────────
19
+ export { Tool } from './src/tool/Tool.js';
20
+ export { ToolRegistry } from './src/tool/ToolRegistry.js';
21
+
22
+ // ── LLM ───────────────────────────────────────────────────────────────────────
23
+ export { BaseLLMProvider } from './src/llm/BaseLLMProvider.js';
24
+ export { LLMRouter } from './src/llm/LLMRouter.js';
25
+ export { GrokProvider } from './src/llm/providers/GrokProvider.js';
26
+ export { ClaudeProvider } from './src/llm/providers/ClaudeProvider.js';
27
+ export { OpenAIProvider } from './src/llm/providers/OpenAIProvider.js';
28
+
29
+ // ── Prompt ────────────────────────────────────────────────────────────────────
30
+ export { PromptBuilder } from './src/prompt/PromptBuilder.js';
31
+ export { PromptTemplate } from './src/prompt/PromptTemplate.js';
32
+
33
+ // ── Team ──────────────────────────────────────────────────────────────────────
34
+ export { AgentTeam } from './src/team/AgentTeam.js';
35
+ export { TeamResult } from './src/team/TeamResult.js';
36
+
37
+ // ── Errors ────────────────────────────────────────────────────────────────────
38
+ export { AgentError, ToolError, LLMError, ConfigError, MemoryError } from './src/utils/errors.js';
39
+
40
+ // ── Convenience factories ─────────────────────────────────────────────────────
41
+ // Import classes for use in factories (separate from re-exports above)
42
+ import { Agent as _Agent } from './src/agent/Agent.js';
43
+ import { AgentConfig as _AgentConfig } from './src/agent/AgentConfig.js';
44
+ import { AgentTeam as _AgentTeam } from './src/team/AgentTeam.js';
45
+
46
+ /**
47
+ * Create an Agent from a plain config object.
48
+ * Shorthand for: new Agent(new AgentConfig(options))
49
+ *
50
+ * @param {Object} options - See AgentConfig for all options
51
+ * @returns {Agent}
52
+ *
53
+ * @example
54
+ * const agent = createAgent({
55
+ * name: 'my-agent',
56
+ * provider: 'grok',
57
+ * apiKey: process.env.GROK_API_KEY,
58
+ * systemPromptTemplate: 'You are a helpful assistant.',
59
+ * });
60
+ */
61
+ export function createAgent(options) {
62
+ return new _Agent(new _AgentConfig(options));
63
+ }
64
+
65
+ /**
66
+ * Create an AgentTeam from a coordinator and optional member agents.
67
+ * Shorthand for: new AgentTeam({ coordinator, members, mode })
68
+ *
69
+ * @param {Object} options
70
+ * @param {Agent} options.coordinator
71
+ * @param {Agent[]} [options.members=[]]
72
+ * @param {'router' | 'parallel'} [options.mode='router']
73
+ * @returns {AgentTeam}
74
+ *
75
+ * @example
76
+ * const team = createTeam({
77
+ * coordinator: masterAgent,
78
+ * members: [sqlAgent, ragAgent],
79
+ * mode: 'router',
80
+ * });
81
+ */
82
+ export function createTeam(options) {
83
+ return new _AgentTeam(options);
84
+ }