@igniter-js/agents 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/AGENTS.md +2913 -0
- package/CHANGELOG.md +5 -0
- package/README.md +1585 -0
- package/dist/adapters/index.d.mts +2 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +1024 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/index.mjs +1021 -0
- package/dist/adapters/index.mjs.map +1 -0
- package/dist/index-CX4IgrRt.d.mts +2181 -0
- package/dist/index-CX4IgrRt.d.ts +2181 -0
- package/dist/index.d.mts +3170 -0
- package/dist/index.d.ts +3170 -0
- package/dist/index.js +4045 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4011 -0
- package/dist/index.mjs.map +1 -0
- package/dist/shim.d.mts +72 -0
- package/dist/shim.d.ts +72 -0
- package/dist/shim.js +105 -0
- package/dist/shim.js.map +1 -0
- package/dist/shim.mjs +89 -0
- package/dist/shim.mjs.map +1 -0
- package/dist/telemetry/index.d.mts +340 -0
- package/dist/telemetry/index.d.ts +340 -0
- package/dist/telemetry/index.js +157 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/index.mjs +155 -0
- package/dist/telemetry/index.mjs.map +1 -0
- package/package.json +116 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,2913 @@
|
|
|
1
|
+
# AGENTS.md - @igniter-js/agents
|
|
2
|
+
|
|
3
|
+
> **Last Updated:** 2025-12-23
|
|
4
|
+
> **Version:** 0.1.0
|
|
5
|
+
> **Goal:** This document serves as the complete operational manual for Code Agents maintaining and consuming the @igniter-js/agents package. It is designed to be hyper-robust, training-ready, and exhaustive, aiming for at least 1,500 lines of high-quality content to ensure the agent fully dominates the package's domain, architecture, and usage.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Package Vision & Context
|
|
10
|
+
|
|
11
|
+
**@igniter-js/agents** is the comprehensive AI agent framework for the Igniter.js ecosystem. In the rapidly evolving landscape of AI-powered applications, traditional API-first architectures often struggle to provide natural, conversational interfaces that can handle complex multi-step tasks, adapt to context, and learn from interactions. This package bridges that gap by providing a type-safe, observable, and extensible foundation for building AI agents that can seamlessly integrate with Igniter.js APIs, maintain persistent memory, execute tools, and communicate via Model Context Protocol (MCP).
|
|
12
|
+
|
|
13
|
+
### Core Value Propositions
|
|
14
|
+
|
|
15
|
+
1. **Type-Safe Agent Development:** Leverages TypeScript's advanced type system to ensure that agent tools, prompts, and configurations are validated at compile time, preventing runtime errors and improving developer productivity.
|
|
16
|
+
|
|
17
|
+
2. **Multi-Agent Orchestration:** Provides a manager pattern that can coordinate multiple specialized agents, each with their own tools, memory, and context, enabling complex workflows and task delegation.
|
|
18
|
+
|
|
19
|
+
3. **Memory Persistence:** Implements an adapter-based memory system that supports different storage backends (currently in-memory, extensible to Redis, Prisma, etc.) for maintaining conversation history and learned context across sessions.
|
|
20
|
+
|
|
21
|
+
4. **MCP Integration:** Native support for the Model Context Protocol, enabling agents to communicate with MCP-compatible servers and access external tools and resources.
|
|
22
|
+
|
|
23
|
+
5. **Comprehensive Observability:** Deep integration with @igniter-js/telemetry for tracking agent lifecycle, tool usage, memory operations, and performance metrics.
|
|
24
|
+
|
|
25
|
+
6. **Hook-Based Extensibility:** Extensive hook system allowing customization of agent behavior at every stage of execution.
|
|
26
|
+
|
|
27
|
+
### The Problem Space
|
|
28
|
+
|
|
29
|
+
Building AI agents in production applications faces several challenges:
|
|
30
|
+
|
|
31
|
+
- **Type Safety Gaps:** Most agent frameworks use dynamic tool definitions that are validated at runtime, leading to errors in production.
|
|
32
|
+
- **Memory Management:** Simple in-memory storage doesn't scale and loses context across deployments.
|
|
33
|
+
- **Tool Orchestration:** Coordinating multiple tools and managing their execution order is complex and error-prone.
|
|
34
|
+
- **Observability Blind Spots:** Understanding what agents are doing, how they're performing, and where they're failing is difficult without comprehensive telemetry.
|
|
35
|
+
- **MCP Compatibility:** Integrating with the emerging Model Context Protocol standard requires significant boilerplate.
|
|
36
|
+
|
|
37
|
+
### The Igniter.js Solution
|
|
38
|
+
|
|
39
|
+
@igniter-js/agents provides a production-ready, type-safe agent framework that:
|
|
40
|
+
|
|
41
|
+
1. **Guarantees Type Safety:** Every tool, prompt, and configuration is validated at compile time.
|
|
42
|
+
2. **Manages Memory Intelligently:** Adapter-based storage with automatic persistence and retrieval.
|
|
43
|
+
3. **Orchestrates Tools Seamlessly:** Builder patterns for composing complex toolsets and agent behaviors.
|
|
44
|
+
4. **Provides Full Observability:** Comprehensive telemetry for every agent operation.
|
|
45
|
+
5. **Enables MCP Integration:** Native MCP client support with type-safe tool calling.
|
|
46
|
+
|
|
47
|
+
### Place in the Igniter.js Ecosystem
|
|
48
|
+
|
|
49
|
+
The agents package serves as the "intelligent layer" that sits atop the Igniter.js ecosystem:
|
|
50
|
+
|
|
51
|
+
- **The Intelligence Layer:** Provides AI-powered interfaces to Igniter.js APIs
|
|
52
|
+
- **The Orchestration Layer:** Coordinates complex workflows across multiple services
|
|
53
|
+
- **The Memory Layer:** Persists context and learning across interactions
|
|
54
|
+
- **The Integration Layer:** Bridges Igniter.js with external AI tools and MCP servers
|
|
55
|
+
- **The Observability Layer:** Provides comprehensive monitoring of AI agent behavior
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## I. MAINTAINER GUIDE (Internal Architecture)
|
|
60
|
+
|
|
61
|
+
### 2. FileSystem Topology (Maintenance)
|
|
62
|
+
|
|
63
|
+
Maintainers must respect the following directory structure and responsibilities to ensure the package remains modular, easy to extend, and predictable.
|
|
64
|
+
|
|
65
|
+
#### Directory Breakdown
|
|
66
|
+
|
|
67
|
+
- **`src/adapters/`**: Storage layer implementations.
|
|
68
|
+
- `index.ts`: Central export for all adapter factories.
|
|
69
|
+
- `memory.adapter.ts`: In-memory adapter implementation with full storage interface compliance.
|
|
70
|
+
- `memory.adapter.spec.ts`: Comprehensive tests for memory operations, serialization, and error handling.
|
|
71
|
+
|
|
72
|
+
- **`src/builders/`**: Configuration layer.
|
|
73
|
+
- `index.ts`: Builder exports barrel.
|
|
74
|
+
- `agent.builder.ts`: `IgniterAgentBuilder` for individual agent configuration.
|
|
75
|
+
- `agent.builder.spec.ts`: Builder validation and chaining tests.
|
|
76
|
+
- `main.builder.ts`: `IgniterAgentManagerBuilder` for multi-agent orchestration.
|
|
77
|
+
- `main.builder.spec.ts`: Manager builder tests including agent registration.
|
|
78
|
+
- `tool.builder.ts`: `IgniterAgentTool` for type-safe tool definitions.
|
|
79
|
+
- `tool.builder.spec.ts`: Tool schema validation and inference tests.
|
|
80
|
+
- `toolset.builder.ts`: `IgniterAgentToolset` for tool composition.
|
|
81
|
+
- `toolset.builder.spec.ts`: Toolset aggregation and conflict resolution tests.
|
|
82
|
+
- `mcp.builder.ts`: `IgniterAgentMCPClient` for MCP integration.
|
|
83
|
+
- `mcp.builder.spec.ts`: MCP protocol compliance and message handling tests.
|
|
84
|
+
- `prompt.builder.ts`: `IgniterAgentPrompt` for prompt engineering.
|
|
85
|
+
- `prompt.builder.spec.ts`: Prompt template validation and interpolation tests.
|
|
86
|
+
|
|
87
|
+
- **`src/core/`**: Runtime execution layer.
|
|
88
|
+
- `agent.ts`: `IgniterAgentCore` - individual agent runtime with Vercel AI integration.
|
|
89
|
+
- `manager.ts`: `IgniterAgentManagerCore` - multi-agent orchestration engine.
|
|
90
|
+
- `manager.spec.ts`: Manager lifecycle and agent coordination tests.
|
|
91
|
+
- `memory.ts`: Memory runtime with adapter abstraction.
|
|
92
|
+
- `telemetry.spec.ts`: Telemetry emission and attribute validation tests.
|
|
93
|
+
|
|
94
|
+
- **`src/errors/`**: Error handling standardization.
|
|
95
|
+
- `agent.error.ts`: `IgniterAgentError` class with typed error codes.
|
|
96
|
+
- `index.ts`: Error exports barrel.
|
|
97
|
+
|
|
98
|
+
- **`src/telemetry/`**: Observability definitions.
|
|
99
|
+
- `index.ts`: `IgniterAgentTelemetryEvents` registry with all agent events.
|
|
100
|
+
|
|
101
|
+
- **`src/types/`**: Type system contracts.
|
|
102
|
+
- `adapter.ts`: Memory adapter interface definitions.
|
|
103
|
+
- `builder.ts`: Builder configuration type definitions.
|
|
104
|
+
- `common.ts`: Shared types across the package.
|
|
105
|
+
- `hooks.ts`: Hook function signatures.
|
|
106
|
+
- `manager.ts`: Manager and agent interface definitions.
|
|
107
|
+
- `memory.ts`: Memory operation types.
|
|
108
|
+
- `prompt.ts`: Prompt template types.
|
|
109
|
+
- `utils.ts`: Utility type helpers.
|
|
110
|
+
- `index.ts`: Type exports barrel.
|
|
111
|
+
|
|
112
|
+
- **`src/utils/`**: Pure utility functions.
|
|
113
|
+
- `async.ts`: Async operation helpers with error handling.
|
|
114
|
+
- `async.spec.ts`: Async utility tests.
|
|
115
|
+
- `objects.ts`: Object manipulation utilities.
|
|
116
|
+
- `objects.spec.ts`: Object utility tests.
|
|
117
|
+
- `strings.ts`: String processing helpers.
|
|
118
|
+
- `strings.spec.ts`: String utility tests.
|
|
119
|
+
- `validation.ts`: Schema validation utilities.
|
|
120
|
+
- `validation.spec.ts`: Validation utility tests.
|
|
121
|
+
- `index.ts`: Utility exports barrel.
|
|
122
|
+
|
|
123
|
+
- **`src/index.ts`**: Public API entry point with organized exports.
|
|
124
|
+
- **`src/shim.ts`**: Browser import protection shim.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### 3. Architecture Deep-Dive
|
|
129
|
+
|
|
130
|
+
#### 3.1 The Builder Pattern Cascade
|
|
131
|
+
|
|
132
|
+
The agents package implements a sophisticated builder pattern cascade that ensures type safety across the entire configuration chain:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// Builder Cascade Flow
|
|
136
|
+
IgniterAgentManager.create()
|
|
137
|
+
.withLogger(logger) // Adds logging context
|
|
138
|
+
.withTelemetry(telemetry) // Adds telemetry context
|
|
139
|
+
.withMemory(memoryAdapter) // Adds memory context
|
|
140
|
+
.addAgent(agentBuilder) // Adds agent with inherited context
|
|
141
|
+
.build(); // Produces fully configured manager
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Each builder accumulates state immutably, passing context down to child builders while maintaining type inference.
|
|
145
|
+
|
|
146
|
+
#### 3.2 Agent Runtime Architecture
|
|
147
|
+
|
|
148
|
+
The `IgniterAgentCore` wraps Vercel AI's `ToolLoopAgent` with comprehensive lifecycle management:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
Agent Execution Flow:
|
|
152
|
+
1. Hook: onAgentStart
|
|
153
|
+
2. Memory: Load conversation history
|
|
154
|
+
3. Telemetry: agent.started event
|
|
155
|
+
4. AI Generation: Tool selection and reasoning
|
|
156
|
+
5. Tool Execution Loop:
|
|
157
|
+
- Hook: onToolCallStart
|
|
158
|
+
- Tool validation and execution
|
|
159
|
+
- Hook: onToolCallEnd
|
|
160
|
+
- Telemetry: tool.called event
|
|
161
|
+
6. Memory: Persist conversation state
|
|
162
|
+
7. Telemetry: agent.completed event
|
|
163
|
+
8. Hook: onAgentComplete
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### 3.3 Memory System Design
|
|
167
|
+
|
|
168
|
+
The memory system uses a layered adapter pattern:
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Memory Layer Architecture:
|
|
172
|
+
┌─────────────────┐
|
|
173
|
+
│ IgniterAgentCore │ ← Uses memory interface
|
|
174
|
+
└─────────────────┘
|
|
175
|
+
│
|
|
176
|
+
▼
|
|
177
|
+
┌─────────────────┐
|
|
178
|
+
│ Memory Runtime │ ← Coordinates operations
|
|
179
|
+
└─────────────────┘
|
|
180
|
+
│
|
|
181
|
+
▼
|
|
182
|
+
┌─────────────────┐
|
|
183
|
+
│ Memory Adapter │ ← Storage implementation
|
|
184
|
+
└─────────────────┘
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This design allows seamless swapping of storage backends while maintaining consistent API.
|
|
188
|
+
|
|
189
|
+
#### 3.4 MCP Integration Flow
|
|
190
|
+
|
|
191
|
+
MCP client integration follows a strict protocol:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
MCP Communication Flow:
|
|
195
|
+
1. Client initialization with server capabilities
|
|
196
|
+
2. Tool discovery and schema validation
|
|
197
|
+
3. Message encoding/decoding
|
|
198
|
+
4. Error handling and retry logic
|
|
199
|
+
5. Telemetry emission for all operations
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### 3.5 Telemetry Integration
|
|
203
|
+
|
|
204
|
+
Every operation emits structured telemetry events:
|
|
205
|
+
|
|
206
|
+
- **Agent Lifecycle:** `agent.started`, `agent.completed`, `agent.error`
|
|
207
|
+
- **Tool Execution:** `tool.called`, `tool.completed`, `tool.error`
|
|
208
|
+
- **Memory Operations:** `memory.stored`, `memory.retrieved`, `memory.error`
|
|
209
|
+
- **MCP Operations:** `mcp.connected`, `mcp.message.sent`, `mcp.message.received`
|
|
210
|
+
|
|
211
|
+
All events include contextual attributes and error details when applicable.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### 4. Operational Flow Mapping (Pipelines)
|
|
216
|
+
|
|
217
|
+
#### 4.1 Method: `IgniterAgentManagerBuilder.build()`
|
|
218
|
+
|
|
219
|
+
1. **Configuration Validation:** Ensures all required dependencies (logger, telemetry, memory) are configured.
|
|
220
|
+
2. **Context Inheritance:** Creates shared context object with logger, telemetry, and memory references.
|
|
221
|
+
3. **Agent Instantiation:** For each registered agent builder, calls `agentBuilder.build(context)` to produce `IgniterAgentCore` instances.
|
|
222
|
+
4. **Manager Creation:** Instantiates `IgniterAgentManagerCore` with the agent registry.
|
|
223
|
+
5. **Telemetry:** Emits `manager.created` event with agent count and configuration metadata.
|
|
224
|
+
6. **Return:** Returns the fully configured manager instance.
|
|
225
|
+
|
|
226
|
+
#### 4.2 Method: `IgniterAgentCore.generate(input)`
|
|
227
|
+
|
|
228
|
+
1. **Input Validation:** Validates input against agent's context schema using Zod.
|
|
229
|
+
2. **Hook Execution:** Fires `onAgentStart` hook with input and context.
|
|
230
|
+
3. **Memory Loading:** Retrieves conversation history from memory adapter (if configured).
|
|
231
|
+
4. **Telemetry:** Emits `generation.generate.started` event with input metadata.
|
|
232
|
+
5. **AI Processing:** Initializes Vercel AI ToolLoopAgent with tools and system prompt.
|
|
233
|
+
6. **Tool Loop:** Executes tool calling loop, validating each tool call and firing appropriate hooks.
|
|
234
|
+
7. **Memory Persistence:** Stores conversation state after each interaction.
|
|
235
|
+
8. **Telemetry:** Emits `generation.generate.success` or `generation.generate.error` event.
|
|
236
|
+
9. **Hook Execution:** Fires `onAgentComplete` or `onAgentError` hook.
|
|
237
|
+
10. **Return:** Returns the final AI response (AgentCallResult).
|
|
238
|
+
|
|
239
|
+
#### 4.3 Method: `IgniterAgentCore.stream(input)`
|
|
240
|
+
|
|
241
|
+
1. **Input Validation:** Validates input against agent's context schema using Zod.
|
|
242
|
+
2. **Hook Execution:** Fires `onAgentStart` hook with input and context.
|
|
243
|
+
3. **Telemetry:** Emits `generation.stream.started` event with input metadata.
|
|
244
|
+
4. **Stream Initialization:** Creates a streaming connection with Vercel AI ToolLoopAgent.
|
|
245
|
+
5. **Chunk Emission:** Yields response chunks as they arrive from the AI.
|
|
246
|
+
6. **Telemetry:** Emits `generation.stream.chunk` event for each chunk.
|
|
247
|
+
7. **Telemetry:** Emits `generation.stream.success` or `generation.stream.error` event at completion.
|
|
248
|
+
8. **Hook Execution:** Fires `onAgentComplete` or `onAgentError` hook.
|
|
249
|
+
9. **Return:** Returns an async iterable or readable stream of response chunks.
|
|
250
|
+
|
|
251
|
+
#### 4.4 Method: `IgniterAgentManagerCore.startAll()`
|
|
252
|
+
|
|
253
|
+
1. **Agent Iteration:** Loops through all registered agents.
|
|
254
|
+
2. **Dependency Resolution:** Ensures agents have required dependencies (logger, telemetry, memory).
|
|
255
|
+
3. **Parallel Initialization:** Starts all agents concurrently using `Promise.allSettled`.
|
|
256
|
+
4. **Status Tracking:** Updates internal status map for each agent.
|
|
257
|
+
5. **Telemetry:** Emits `manager.agents.started` event with success/failure counts.
|
|
258
|
+
6. **Error Handling:** Collects initialization errors and logs them without failing the entire operation.
|
|
259
|
+
7. **Return:** Returns summary object with started agents and any errors.
|
|
260
|
+
|
|
261
|
+
#### 4.5 Method: `IgniterAgentTool.execute(input, context)`
|
|
262
|
+
|
|
263
|
+
1. **Schema Validation:** Validates input against tool's input schema.
|
|
264
|
+
2. **Hook Execution:** Fires `onToolExecute` hook if configured.
|
|
265
|
+
3. **Telemetry:** Emits `tool.executed` event with input metadata.
|
|
266
|
+
4. **Handler Execution:** Calls the tool's handler function with validated input and context.
|
|
267
|
+
5. **Result Validation:** Validates output against tool's output schema if provided.
|
|
268
|
+
6. **Telemetry:** Emits `tool.completed` or `tool.error` event.
|
|
269
|
+
7. **Return:** Returns the validated result or throws error.
|
|
270
|
+
|
|
271
|
+
#### 4.6 Method: `IgniterAgentMemory.store(key, value)`
|
|
272
|
+
|
|
273
|
+
1. **Serialization:** Converts value to JSON-compatible format.
|
|
274
|
+
2. **Adapter Delegation:** Calls memory adapter's `set` method.
|
|
275
|
+
3. **Error Handling:** Wraps adapter errors in `IgniterAgentError`.
|
|
276
|
+
4. **Telemetry:** Emits `memory.stored` event with key and size metadata.
|
|
277
|
+
5. **Return:** Returns success boolean.
|
|
278
|
+
|
|
279
|
+
#### 4.6 Method: `IgniterAgentMCPClient.connect()`
|
|
280
|
+
|
|
281
|
+
1. **Connection Establishment:** Initializes MCP transport layer.
|
|
282
|
+
2. **Capability Discovery:** Queries server for available tools and resources.
|
|
283
|
+
3. **Schema Validation:** Validates discovered tools against expected schemas.
|
|
284
|
+
4. **Telemetry:** Emits `mcp.connected` event with capability metadata.
|
|
285
|
+
5. **Hook Execution:** Fires `onConnected` hook with server capabilities.
|
|
286
|
+
6. **Return:** Returns connection status and available tools.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
### 5. Dependency & Type Graph
|
|
291
|
+
|
|
292
|
+
#### 5.1 External Dependencies
|
|
293
|
+
|
|
294
|
+
| Package | Purpose | Version |
|
|
295
|
+
| ----------------------- | ---------------------------------------- | --------- |
|
|
296
|
+
| `@igniter-js/core` | Base error classes and logger interfaces | `^0.4.0` |
|
|
297
|
+
| `@igniter-js/telemetry` | Telemetry manager integration | `^0.1.0` |
|
|
298
|
+
| `ai` | Vercel AI SDK for agent runtime | `^6.0.0` |
|
|
299
|
+
| `zod` | Schema validation and type inference | `^4.0.0` |
|
|
300
|
+
| `zod-to-json-schema` | Schema conversion for MCP | `^4.0.0` |
|
|
301
|
+
|
|
302
|
+
#### 5.2 Type Flow Architecture
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
Builder Configuration Flow:
|
|
306
|
+
IgniterAgentManagerBuilder
|
|
307
|
+
├── withLogger() → Logger context
|
|
308
|
+
├── withTelemetry() → Telemetry context
|
|
309
|
+
├── withMemory() → Memory context
|
|
310
|
+
└── addAgent() → Agent registration
|
|
311
|
+
|
|
312
|
+
Agent Instantiation Flow:
|
|
313
|
+
AgentBuilder → AgentConfig → IgniterAgentCore
|
|
314
|
+
ToolBuilder → ToolConfig → IgniterAgentTool
|
|
315
|
+
MCPBuilder → MCPConfig → IgniterAgentMCPClient
|
|
316
|
+
|
|
317
|
+
Runtime Type Flow:
|
|
318
|
+
IgniterAgentManagerCore
|
|
319
|
+
├── agents: Map<string, IgniterAgentCore>
|
|
320
|
+
├── memory: IgniterAgentMemory
|
|
321
|
+
├── telemetry: IgniterTelemetryManager
|
|
322
|
+
└── logger: IgniterLogger
|
|
323
|
+
|
|
324
|
+
Execution Type Flow:
|
|
325
|
+
Input (Zod-validated) → ToolExecution → Output (Zod-validated) → Memory → Telemetry
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### 6. Maintenance Checklist
|
|
331
|
+
|
|
332
|
+
#### Feature Addition Workflow
|
|
333
|
+
|
|
334
|
+
1. [ ] Define types in `src/types/` with proper Zod schemas
|
|
335
|
+
2. [ ] Implement builder methods with immutable state accumulation
|
|
336
|
+
3. [ ] Add runtime logic in `src/core/` with telemetry emission
|
|
337
|
+
4. [ ] Create utility functions in `src/utils/` with full test coverage
|
|
338
|
+
5. [ ] Add comprehensive tests covering all code paths
|
|
339
|
+
6. [ ] Update `AGENTS.md` with new operational flows and examples
|
|
340
|
+
7. [ ] Ensure TSDoc comments are complete and accurate
|
|
341
|
+
8. [ ] Run full test suite and verify telemetry coverage
|
|
342
|
+
|
|
343
|
+
#### Bugfix Workflow
|
|
344
|
+
|
|
345
|
+
1. [ ] Identify the affected component (builder, core, adapter, utils)
|
|
346
|
+
2. [ ] Create reproduction test case
|
|
347
|
+
3. [ ] Implement fix with minimal changes
|
|
348
|
+
4. [ ] Verify telemetry events are correctly emitted
|
|
349
|
+
5. [ ] Update tests to prevent regression
|
|
350
|
+
6. [ ] Update documentation if behavior changed
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
### 7. Maintainer Troubleshooting
|
|
355
|
+
|
|
356
|
+
#### Q: Agent tool calls are failing with type errors
|
|
357
|
+
|
|
358
|
+
**A:** Check that the tool's input/output schemas are properly defined and that the handler function matches the schema types. Use `z.infer<typeof schema>` to ensure type alignment.
|
|
359
|
+
|
|
360
|
+
#### Q: Memory operations are not persisting
|
|
361
|
+
|
|
362
|
+
**A:** Verify that the memory adapter is properly configured and that the adapter's `set` and `get` methods are implemented correctly. Check telemetry events for memory operation failures.
|
|
363
|
+
|
|
364
|
+
#### Q: MCP connections are timing out
|
|
365
|
+
|
|
366
|
+
**A:** Ensure the MCP server URL is accessible and that the transport layer is properly configured. Check telemetry events for connection failures and review timeout settings.
|
|
367
|
+
|
|
368
|
+
#### Q: Telemetry events are not being emitted
|
|
369
|
+
|
|
370
|
+
**A:** Verify that `withTelemetry()` was called on the manager builder and that the telemetry manager is properly initialized. Check that event keys match those defined in `src/telemetry/index.ts`.
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## II. CONSUMER GUIDE (Developer Manual)
|
|
375
|
+
|
|
376
|
+
### 8. Distribution Anatomy (Consumption)
|
|
377
|
+
|
|
378
|
+
#### Package Structure After Build
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
@igniter-js/agents/
|
|
382
|
+
├── dist/
|
|
383
|
+
│ ├── index.mjs # ESM main entry
|
|
384
|
+
│ ├── index.d.mts # TypeScript declarations
|
|
385
|
+
│ ├── adapters/
|
|
386
|
+
│ │ ├── index.mjs # Adapter exports
|
|
387
|
+
│ │ └── index.d.mts # Adapter types
|
|
388
|
+
│ └── telemetry/
|
|
389
|
+
│ ├── index.mjs # Telemetry exports
|
|
390
|
+
│ └── index.d.mts # Telemetry types
|
|
391
|
+
├── package.json
|
|
392
|
+
└── README.md
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
#### Import Patterns
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// Main package - full API
|
|
399
|
+
import {
|
|
400
|
+
IgniterAgent,
|
|
401
|
+
IgniterAgentManager,
|
|
402
|
+
IgniterAgentTool,
|
|
403
|
+
} from "@igniter-js/agents";
|
|
404
|
+
|
|
405
|
+
// Adapters only
|
|
406
|
+
import { MemoryAdapter } from "@igniter-js/agents/adapters";
|
|
407
|
+
|
|
408
|
+
// Telemetry only
|
|
409
|
+
import { IgniterAgentTelemetryEvents } from "@igniter-js/agents/telemetry";
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### Runtime Requirements
|
|
413
|
+
|
|
414
|
+
- **Node.js:** 18.0.0+
|
|
415
|
+
- **Bun:** 1.0.0+
|
|
416
|
+
- **Deno:** 1.30.0+
|
|
417
|
+
- **Server-only:** Cannot be imported in browser environments (shim.ts protection)
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### 9. Quick Start & Common Patterns
|
|
422
|
+
|
|
423
|
+
#### Basic Agent Setup
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import {
|
|
427
|
+
IgniterAgent,
|
|
428
|
+
IgniterAgentTool,
|
|
429
|
+
MemoryAdapter,
|
|
430
|
+
} from "@igniter-js/agents";
|
|
431
|
+
import { z } from "zod";
|
|
432
|
+
|
|
433
|
+
const weatherTool = IgniterAgentTool.create("get_weather")
|
|
434
|
+
.withDescription("Get current weather for a location")
|
|
435
|
+
.withInput(z.object({ location: z.string() }))
|
|
436
|
+
.withOutput(
|
|
437
|
+
z.object({ temperature: z.number(), condition: z.string() }),
|
|
438
|
+
)
|
|
439
|
+
.withExecute(async ({ location }) => {
|
|
440
|
+
// Implementation
|
|
441
|
+
return { temperature: 22, condition: "sunny" };
|
|
442
|
+
})
|
|
443
|
+
.build();
|
|
444
|
+
|
|
445
|
+
const agent = IgniterAgent.create("weather-assistant")
|
|
446
|
+
.withMemory(MemoryAdapter.create())
|
|
447
|
+
.withTool(weatherTool)
|
|
448
|
+
.withSystemPrompt("You are a helpful weather assistant.")
|
|
449
|
+
.build();
|
|
450
|
+
|
|
451
|
+
const response = await agent.generate({
|
|
452
|
+
messages: [{ role: 'user', content: 'What is the weather in New York?' }]
|
|
453
|
+
});
|
|
454
|
+
console.log(response);
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
#### Multi-Agent Manager
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
import { IgniterAgentManager, IgniterAgentToolset } from "@igniter-js/agents";
|
|
461
|
+
|
|
462
|
+
const toolset = IgniterAgentToolset.create()
|
|
463
|
+
.addTool(weatherTool)
|
|
464
|
+
.addTool(calculatorTool)
|
|
465
|
+
.build();
|
|
466
|
+
|
|
467
|
+
const manager = IgniterAgentManager.create()
|
|
468
|
+
.withMemory(MemoryAdapter.create())
|
|
469
|
+
.addAgent(weatherAgent)
|
|
470
|
+
.addAgent(mathAgent)
|
|
471
|
+
.build();
|
|
472
|
+
|
|
473
|
+
await manager.startAll();
|
|
474
|
+
const agents = manager.listAgents();
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### MCP Integration
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
import { IgniterAgentMCPClient } from "@igniter-js/agents";
|
|
481
|
+
|
|
482
|
+
const mcpClient = IgniterAgentMCPClient.create()
|
|
483
|
+
.withServerUrl("http://localhost:3000/mcp")
|
|
484
|
+
.build();
|
|
485
|
+
|
|
486
|
+
await mcpClient.connect();
|
|
487
|
+
|
|
488
|
+
const agent = IgniterAgent.create("mcp-agent").withMCPClient(mcpClient).build();
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
### 9.1 Memory Adapters Guide
|
|
494
|
+
|
|
495
|
+
The @igniter-js/agents package provides multiple memory adapter implementations for different use cases:
|
|
496
|
+
|
|
497
|
+
#### IgniterAgentInMemoryAdapter
|
|
498
|
+
|
|
499
|
+
Simple, fast in-memory storage. Data is lost on process restart.
|
|
500
|
+
|
|
501
|
+
**Best for:** Development, testing, short-lived applications, prototyping.
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
import { IgniterAgentInMemoryAdapter } from "@igniter-js/agents/adapters";
|
|
505
|
+
|
|
506
|
+
const adapter = IgniterAgentInMemoryAdapter.create({
|
|
507
|
+
namespace: "myapp",
|
|
508
|
+
maxMessages: 500,
|
|
509
|
+
maxChats: 50,
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const agent = IgniterAgent.create("my-agent")
|
|
513
|
+
.withMemory(adapter)
|
|
514
|
+
.build();
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
#### IgniterAgentJSONFileAdapter
|
|
518
|
+
|
|
519
|
+
File-based storage using JSON files. Data persists across process restarts.
|
|
520
|
+
|
|
521
|
+
**Best for:** Single-machine deployments, development with persistence, offline-first apps, simple local storage.
|
|
522
|
+
|
|
523
|
+
**Directory structure created:**
|
|
524
|
+
```
|
|
525
|
+
{dataDir}/
|
|
526
|
+
├── working-memory.json # All working memory entries
|
|
527
|
+
├── chats.json # All chat sessions
|
|
528
|
+
└── messages/
|
|
529
|
+
├── {chatId}.json # Messages for specific chat
|
|
530
|
+
└── ...
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
import { IgniterAgentJSONFileAdapter } from "@igniter-js/agents/adapters";
|
|
535
|
+
|
|
536
|
+
// Create adapter (creates data directory automatically)
|
|
537
|
+
const adapter = IgniterAgentJSONFileAdapter.create({
|
|
538
|
+
dataDir: "./data/agent-memory",
|
|
539
|
+
namespace: "myapp",
|
|
540
|
+
autoSync: true, // Save to disk automatically
|
|
541
|
+
maxMessages: 1000,
|
|
542
|
+
maxChats: 100,
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// Must connect before using
|
|
546
|
+
await adapter.connect();
|
|
547
|
+
|
|
548
|
+
// Use with agent
|
|
549
|
+
const agent = IgniterAgent.create("my-agent")
|
|
550
|
+
.withMemory(adapter)
|
|
551
|
+
.build();
|
|
552
|
+
|
|
553
|
+
// Generate conversation (auto-saves to JSON files)
|
|
554
|
+
await agent.generate({
|
|
555
|
+
messages: [{ role: 'user', content: 'Hello!' }]
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
// Disconnect when done (syncs remaining data)
|
|
559
|
+
await adapter.disconnect();
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
**Features:**
|
|
563
|
+
- Automatic file synchronization (optional)
|
|
564
|
+
- Working memory, chat sessions, and message history
|
|
565
|
+
- Namespace support for multi-tenant apps
|
|
566
|
+
- Debug logging
|
|
567
|
+
- Data limit enforcement
|
|
568
|
+
|
|
569
|
+
**Example with persistence across restarts:**
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
import { IgniterAgentJSONFileAdapter } from "@igniter-js/agents/adapters";
|
|
573
|
+
|
|
574
|
+
// First session - create and save data
|
|
575
|
+
{
|
|
576
|
+
const adapter = IgniterAgentJSONFileAdapter.create({
|
|
577
|
+
dataDir: "./memory"
|
|
578
|
+
});
|
|
579
|
+
await adapter.connect();
|
|
580
|
+
|
|
581
|
+
await adapter.updateWorkingMemory({
|
|
582
|
+
scope: 'chat',
|
|
583
|
+
identifier: 'chat_123',
|
|
584
|
+
content: 'User prefers concise responses'
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
await adapter.saveChat({
|
|
588
|
+
chatId: 'chat_123',
|
|
589
|
+
userId: 'user_456',
|
|
590
|
+
title: 'TypeScript Questions',
|
|
591
|
+
createdAt: new Date(),
|
|
592
|
+
updatedAt: new Date(),
|
|
593
|
+
messageCount: 0
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
await adapter.disconnect();
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Second session (different process) - data is loaded
|
|
600
|
+
{
|
|
601
|
+
const adapter = IgniterAgentJSONFileAdapter.create({
|
|
602
|
+
dataDir: "./memory"
|
|
603
|
+
});
|
|
604
|
+
await adapter.connect();
|
|
605
|
+
|
|
606
|
+
// Data from previous session is available
|
|
607
|
+
const memory = await adapter.getWorkingMemory({
|
|
608
|
+
scope: 'chat',
|
|
609
|
+
identifier: 'chat_123'
|
|
610
|
+
});
|
|
611
|
+
console.log(memory?.content); // "User prefers concise responses"
|
|
612
|
+
|
|
613
|
+
const chat = await adapter.getChat('chat_123');
|
|
614
|
+
console.log(chat?.title); // "TypeScript Questions"
|
|
615
|
+
|
|
616
|
+
await adapter.disconnect();
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
### 10. Real-World Use Case Library
|
|
623
|
+
|
|
624
|
+
#### Case A: Customer Support Chatbot (E-commerce)
|
|
625
|
+
|
|
626
|
+
**Scenario:** An e-commerce platform needs an AI chatbot that can handle customer inquiries about orders, products, and returns.
|
|
627
|
+
|
|
628
|
+
**Implementation:**
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
632
|
+
import { z } from "zod";
|
|
633
|
+
|
|
634
|
+
// Order lookup tool
|
|
635
|
+
const orderLookupTool = IgniterAgentTool.create("lookup_order")
|
|
636
|
+
.withDescription("Looks up an order by ID")
|
|
637
|
+
.withInput(z.object({ orderId: z.string() }))
|
|
638
|
+
.withOutput(
|
|
639
|
+
z.object({
|
|
640
|
+
status: z.string(),
|
|
641
|
+
items: z.array(z.object({ name: z.string(), price: z.number() })),
|
|
642
|
+
total: z.number(),
|
|
643
|
+
}),
|
|
644
|
+
)
|
|
645
|
+
.withExecute(async ({ orderId }) => {
|
|
646
|
+
const order = await db.orders.findUnique({ where: { id: orderId } });
|
|
647
|
+
|
|
648
|
+
return {
|
|
649
|
+
status: order.status,
|
|
650
|
+
items: order.items,
|
|
651
|
+
total: order.total,
|
|
652
|
+
};
|
|
653
|
+
})
|
|
654
|
+
.build();
|
|
655
|
+
|
|
656
|
+
// Product search tool
|
|
657
|
+
const productSearchTool = IgniterAgentTool.create("search_products")
|
|
658
|
+
.withDescription("Lists repositories for a user")
|
|
659
|
+
.withInput(
|
|
660
|
+
z.object({ query: z.string(), limit: z.number().optional() }),
|
|
661
|
+
)
|
|
662
|
+
.withOutput(
|
|
663
|
+
z.array(
|
|
664
|
+
z.object({
|
|
665
|
+
id: z.string(),
|
|
666
|
+
name: z.string(),
|
|
667
|
+
price: z.number(),
|
|
668
|
+
inStock: z.boolean(),
|
|
669
|
+
}),
|
|
670
|
+
),
|
|
671
|
+
)
|
|
672
|
+
.withExecute(async ({ query, limit = 10 }) => {
|
|
673
|
+
const products = await db.products.findMany({
|
|
674
|
+
where: { name: { contains: query } },
|
|
675
|
+
take: limit,
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
return products;
|
|
679
|
+
})
|
|
680
|
+
.build();
|
|
681
|
+
|
|
682
|
+
// Support agent
|
|
683
|
+
const supportAgent = IgniterAgent.create("customer-support")
|
|
684
|
+
.withToolset(
|
|
685
|
+
IgniterAgentToolset.create()
|
|
686
|
+
.addTool(orderLookupTool)
|
|
687
|
+
.addTool(productSearchTool)
|
|
688
|
+
.build(),
|
|
689
|
+
)
|
|
690
|
+
.withSystemPrompt(
|
|
691
|
+
`
|
|
692
|
+
You are a helpful customer support agent for an e-commerce store.
|
|
693
|
+
Help customers with order status, product information, and general inquiries.
|
|
694
|
+
Always be polite and provide accurate information.
|
|
695
|
+
`,
|
|
696
|
+
)
|
|
697
|
+
.withMemory(MemoryAdapter.create())
|
|
698
|
+
.build();
|
|
699
|
+
|
|
700
|
+
// Handle customer message
|
|
701
|
+
async function handleCustomerMessage(message: string, customerId: string) {
|
|
702
|
+
const response = await supportAgent.generate({
|
|
703
|
+
messages: [{ role: 'user', content: message }],
|
|
704
|
+
options: { userId: customerId }
|
|
705
|
+
});
|
|
706
|
+
return response;
|
|
707
|
+
}
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
**Best Practices Applied:**
|
|
711
|
+
|
|
712
|
+
- Type-safe tool definitions prevent runtime errors
|
|
713
|
+
- Memory persistence maintains conversation context
|
|
714
|
+
- Tool composition allows modular functionality
|
|
715
|
+
- Clear system prompts guide agent behavior
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
#### Case B: Code Review Assistant (DevOps)
|
|
720
|
+
|
|
721
|
+
**Scenario:** A development team needs an AI assistant that can review pull requests, suggest improvements, and enforce coding standards.
|
|
722
|
+
|
|
723
|
+
**Implementation:**
|
|
724
|
+
|
|
725
|
+
```typescript
|
|
726
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
727
|
+
import { z } from "zod";
|
|
728
|
+
|
|
729
|
+
// Git operations tool
|
|
730
|
+
const gitTool = IgniterAgentTool.create("analyze_code")
|
|
731
|
+
.withDescription("Analyzes code for issues")
|
|
732
|
+
.withInput(
|
|
733
|
+
z.object({
|
|
734
|
+
repo: z.string(),
|
|
735
|
+
prNumber: z.number(),
|
|
736
|
+
files: z.array(z.string()),
|
|
737
|
+
}),
|
|
738
|
+
)
|
|
739
|
+
.withOutput(
|
|
740
|
+
z.object({
|
|
741
|
+
issues: z.array(
|
|
742
|
+
z.object({
|
|
743
|
+
file: z.string(),
|
|
744
|
+
line: z.number(),
|
|
745
|
+
severity: z.enum(["error", "warning", "info"]),
|
|
746
|
+
message: z.string(),
|
|
747
|
+
suggestion: z.string(),
|
|
748
|
+
}),
|
|
749
|
+
),
|
|
750
|
+
summary: z.string(),
|
|
751
|
+
}),
|
|
752
|
+
)
|
|
753
|
+
.withExecute(async ({ repo, prNumber, files }) => {
|
|
754
|
+
// Analyze code using linting tools, security scanners, etc.
|
|
755
|
+
const issues = [];
|
|
756
|
+
const summary = `Found ${issues.length} issues in PR #${prNumber}`;
|
|
757
|
+
|
|
758
|
+
return { issues, summary };
|
|
759
|
+
})
|
|
760
|
+
.build();
|
|
761
|
+
|
|
762
|
+
// Testing tool
|
|
763
|
+
const testTool = IgniterAgentTool.create("run_tests")
|
|
764
|
+
.withDescription("Runs test suite")
|
|
765
|
+
.withInput(z.object({ repo: z.string(), branch: z.string() }))
|
|
766
|
+
.withOutput(
|
|
767
|
+
z.object({
|
|
768
|
+
passed: z.number(),
|
|
769
|
+
failed: z.number(),
|
|
770
|
+
coverage: z.number(),
|
|
771
|
+
errors: z.array(z.string()),
|
|
772
|
+
}),
|
|
773
|
+
)
|
|
774
|
+
.withExecute(async ({ repo, branch }) => {
|
|
775
|
+
// Run test suite
|
|
776
|
+
const result = await runTestSuite(repo, branch);
|
|
777
|
+
return result;
|
|
778
|
+
})
|
|
779
|
+
.build();
|
|
780
|
+
|
|
781
|
+
// Code review agent
|
|
782
|
+
const reviewAgent = IgniterAgent.create("code-reviewer")
|
|
783
|
+
.withToolset(
|
|
784
|
+
IgniterAgentToolset.create().addTool(gitTool).addTool(testTool).build(),
|
|
785
|
+
)
|
|
786
|
+
.withSystemPrompt(
|
|
787
|
+
`
|
|
788
|
+
You are an expert code reviewer with deep knowledge of software engineering best practices.
|
|
789
|
+
Review pull requests for code quality, security, performance, and maintainability.
|
|
790
|
+
Provide constructive feedback with specific suggestions for improvement.
|
|
791
|
+
`,
|
|
792
|
+
)
|
|
793
|
+
.withMemory(MemoryAdapter.create())
|
|
794
|
+
.onToolCallEnd((result, context) => {
|
|
795
|
+
// Log review metrics
|
|
796
|
+
console.log(`Review completed for PR #${context.prNumber}`);
|
|
797
|
+
})
|
|
798
|
+
.build();
|
|
799
|
+
|
|
800
|
+
// Review a pull request
|
|
801
|
+
async function reviewPR(repo: string, prNumber: number) {
|
|
802
|
+
const prompt = `
|
|
803
|
+
Please review pull request #${prNumber} in repository ${repo}.
|
|
804
|
+
Analyze the code changes for:
|
|
805
|
+
1. Code quality and style
|
|
806
|
+
2. Security vulnerabilities
|
|
807
|
+
3. Performance issues
|
|
808
|
+
4. Test coverage
|
|
809
|
+
5. Documentation
|
|
810
|
+
|
|
811
|
+
Provide a detailed review with specific recommendations.
|
|
812
|
+
`;
|
|
813
|
+
|
|
814
|
+
const review = await reviewAgent.generate({
|
|
815
|
+
messages: [{ role: 'user', content: prompt }],
|
|
816
|
+
options: {
|
|
817
|
+
repo,
|
|
818
|
+
prNumber,
|
|
819
|
+
context: { type: "pr_review" },
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
return review;
|
|
824
|
+
}
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
**Best Practices Applied:**
|
|
828
|
+
|
|
829
|
+
- Specialized tools for different aspects of code review
|
|
830
|
+
- Comprehensive analysis covering multiple quality dimensions
|
|
831
|
+
- Hook-based logging for audit trails
|
|
832
|
+
- Context passing for operation tracking
|
|
833
|
+
|
|
834
|
+
---
|
|
835
|
+
|
|
836
|
+
#### Case C: Data Analysis Assistant (Analytics)
|
|
837
|
+
|
|
838
|
+
**Scenario:** A data science team needs an AI assistant that can query databases, generate visualizations, and explain complex datasets.
|
|
839
|
+
|
|
840
|
+
**Implementation:**
|
|
841
|
+
|
|
842
|
+
```typescript
|
|
843
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
844
|
+
import { z } from "zod";
|
|
845
|
+
|
|
846
|
+
// Database query tool
|
|
847
|
+
const queryTool = IgniterAgentTool.create("execute_query")
|
|
848
|
+
.withInput(
|
|
849
|
+
z.object({
|
|
850
|
+
query: z.string(),
|
|
851
|
+
database: z.string(),
|
|
852
|
+
}),
|
|
853
|
+
)
|
|
854
|
+
.withOutput(
|
|
855
|
+
z.object({
|
|
856
|
+
columns: z.array(z.string()),
|
|
857
|
+
rows: z.array(z.array(z.unknown())),
|
|
858
|
+
executionTime: z.number(),
|
|
859
|
+
rowCount: z.number(),
|
|
860
|
+
}),
|
|
861
|
+
)
|
|
862
|
+
.withExecute(async ({ query, database }) => {
|
|
863
|
+
const startTime = Date.now();
|
|
864
|
+
const result = await executeSQL(query, database);
|
|
865
|
+
const executionTime = Date.now() - startTime;
|
|
866
|
+
|
|
867
|
+
return {
|
|
868
|
+
columns: result.columns,
|
|
869
|
+
rows: result.rows,
|
|
870
|
+
executionTime,
|
|
871
|
+
rowCount: result.rows.length,
|
|
872
|
+
};
|
|
873
|
+
})
|
|
874
|
+
.build();
|
|
875
|
+
|
|
876
|
+
// Visualization tool
|
|
877
|
+
const chartTool = IgniterAgentTool.create("create_chart")
|
|
878
|
+
.withInput(
|
|
879
|
+
z.object({
|
|
880
|
+
data: z.array(z.record(z.unknown())),
|
|
881
|
+
chartType: z.enum(["bar", "line", "pie", "scatter"]),
|
|
882
|
+
xAxis: z.string(),
|
|
883
|
+
yAxis: z.string(),
|
|
884
|
+
title: z.string(),
|
|
885
|
+
}),
|
|
886
|
+
)
|
|
887
|
+
.withOutput(
|
|
888
|
+
z.object({
|
|
889
|
+
chartId: z.string(),
|
|
890
|
+
imageUrl: z.string(),
|
|
891
|
+
description: z.string(),
|
|
892
|
+
}),
|
|
893
|
+
)
|
|
894
|
+
.withExecute(async ({ data, chartType, xAxis, yAxis, title }) => {
|
|
895
|
+
const chartId = generateId();
|
|
896
|
+
const imageUrl = await generateChart(data, {
|
|
897
|
+
chartType,
|
|
898
|
+
xAxis,
|
|
899
|
+
yAxis,
|
|
900
|
+
title,
|
|
901
|
+
});
|
|
902
|
+
const description = `Generated ${chartType} chart showing ${yAxis} by ${xAxis}`;
|
|
903
|
+
|
|
904
|
+
return { chartId, imageUrl, description };
|
|
905
|
+
})
|
|
906
|
+
.build();
|
|
907
|
+
|
|
908
|
+
// Statistics tool
|
|
909
|
+
const statsTool = IgniterAgentTool.create("calculate_stats")
|
|
910
|
+
.withInput(
|
|
911
|
+
z.object({
|
|
912
|
+
data: z.array(z.number()),
|
|
913
|
+
metrics: z.array(
|
|
914
|
+
z.enum(["mean", "median", "std", "min", "max", "quartiles"]),
|
|
915
|
+
),
|
|
916
|
+
}),
|
|
917
|
+
)
|
|
918
|
+
.withOutput(z.record(z.number()))
|
|
919
|
+
.withExecute(async ({ data, metrics }) => {
|
|
920
|
+
const stats = {};
|
|
921
|
+
|
|
922
|
+
if (metrics.includes("mean")) {
|
|
923
|
+
stats.mean = data.reduce((a, b) => a + b, 0) / data.length;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (metrics.includes("median")) {
|
|
927
|
+
const sorted = [...data].sort((a, b) => a - b);
|
|
928
|
+
stats.median = sorted[Math.floor(sorted.length / 2)];
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// Calculate other metrics...
|
|
932
|
+
|
|
933
|
+
return stats;
|
|
934
|
+
})
|
|
935
|
+
.build();
|
|
936
|
+
|
|
937
|
+
// Data analysis agent
|
|
938
|
+
const analysisAgent = IgniterAgent.create("data-analyst")
|
|
939
|
+
.withToolset(
|
|
940
|
+
IgniterAgentToolset.create()
|
|
941
|
+
.addTool(queryTool)
|
|
942
|
+
.addTool(chartTool)
|
|
943
|
+
.addTool(statsTool)
|
|
944
|
+
.build(),
|
|
945
|
+
)
|
|
946
|
+
.withSystemPrompt(
|
|
947
|
+
`
|
|
948
|
+
You are an expert data analyst who can query databases, perform statistical analysis,
|
|
949
|
+
and create visualizations. Help users understand their data through queries, charts,
|
|
950
|
+
and statistical insights. Always explain your findings clearly and suggest next steps.
|
|
951
|
+
`,
|
|
952
|
+
)
|
|
953
|
+
.withMemory(MemoryAdapter.create())
|
|
954
|
+
.build();
|
|
955
|
+
|
|
956
|
+
// Analyze sales data
|
|
957
|
+
async function analyzeSalesData(query: string) {
|
|
958
|
+
const prompt = `
|
|
959
|
+
Please analyze the following sales data query: "${query}"
|
|
960
|
+
|
|
961
|
+
1. Execute the query and examine the results
|
|
962
|
+
2. Calculate relevant statistics (mean, median, trends)
|
|
963
|
+
3. Create appropriate visualizations
|
|
964
|
+
4. Provide insights and recommendations
|
|
965
|
+
|
|
966
|
+
Explain your findings in a clear, actionable way.
|
|
967
|
+
`;
|
|
968
|
+
|
|
969
|
+
const analysis = await analysisAgent.generate({
|
|
970
|
+
prompt,
|
|
971
|
+
options: {
|
|
972
|
+
context: { type: "data_analysis", query },
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
|
|
976
|
+
return analysis;
|
|
977
|
+
}
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
**Best Practices Applied:**
|
|
981
|
+
|
|
982
|
+
- Modular tools for different analytical tasks
|
|
983
|
+
- Comprehensive data validation schemas
|
|
984
|
+
- Memory persistence for multi-step analysis
|
|
985
|
+
- Hook integration for audit logging
|
|
986
|
+
|
|
987
|
+
---
|
|
988
|
+
|
|
989
|
+
#### Case D: API Integration Orchestrator (Integration Platform)
|
|
990
|
+
|
|
991
|
+
**Scenario:** A platform that connects multiple third-party APIs needs an AI agent to handle complex integration workflows and data transformations.
|
|
992
|
+
|
|
993
|
+
**Implementation:**
|
|
994
|
+
|
|
995
|
+
```typescript
|
|
996
|
+
import {
|
|
997
|
+
IgniterAgentManager,
|
|
998
|
+
IgniterAgentToolset,
|
|
999
|
+
IgniterAgentMCPClient,
|
|
1000
|
+
} from "@igniter-js/agents";
|
|
1001
|
+
|
|
1002
|
+
// CRM integration agent
|
|
1003
|
+
const crmAgent = IgniterAgent.create("crm-sync")
|
|
1004
|
+
.withToolset(crmToolset) // Tools for Salesforce, HubSpot, etc.
|
|
1005
|
+
.withSystemPrompt("Handle CRM data synchronization and customer management")
|
|
1006
|
+
.build();
|
|
1007
|
+
|
|
1008
|
+
// Payment processing agent
|
|
1009
|
+
const paymentAgent = IgniterAgent.create("payment-processor")
|
|
1010
|
+
.withToolset(paymentToolset) // Tools for Stripe, PayPal, etc.
|
|
1011
|
+
.withSystemPrompt("Process payments and handle financial transactions")
|
|
1012
|
+
.build();
|
|
1013
|
+
|
|
1014
|
+
// Email marketing agent
|
|
1015
|
+
const emailAgent = IgniterAgent.create("email-campaign")
|
|
1016
|
+
.withToolset(emailToolset) // Tools for Mailchimp, SendGrid, etc.
|
|
1017
|
+
.withSystemPrompt("Manage email campaigns and subscriber communications")
|
|
1018
|
+
.build();
|
|
1019
|
+
|
|
1020
|
+
// Analytics agent with MCP
|
|
1021
|
+
const analyticsAgent = IgniterAgent.create("analytics-orchestrator")
|
|
1022
|
+
.withMCPClient(
|
|
1023
|
+
IgniterAgentMCPClient.create()
|
|
1024
|
+
.withServerUrl(process.env.ANALYTICS_MCP_URL!)
|
|
1025
|
+
.build(),
|
|
1026
|
+
)
|
|
1027
|
+
.withSystemPrompt("Orchestrate complex analytics workflows")
|
|
1028
|
+
.build();
|
|
1029
|
+
|
|
1030
|
+
// Integration manager
|
|
1031
|
+
const agentManager = IgniterAgentManager.create()
|
|
1032
|
+
.withMemory(MemoryAdapter.create())
|
|
1033
|
+
.withTelemetry(telemetryManager)
|
|
1034
|
+
.addAgent(crmAgent)
|
|
1035
|
+
.addAgent(paymentAgent)
|
|
1036
|
+
.addAgent(emailAgent)
|
|
1037
|
+
.addAgent(analyticsAgent)
|
|
1038
|
+
.build();
|
|
1039
|
+
|
|
1040
|
+
// Handle complex integration request
|
|
1041
|
+
async function handleIntegrationRequest(request: IntegrationRequest) {
|
|
1042
|
+
// Route to appropriate agent based on request type
|
|
1043
|
+
const agent = agentManager.get(request.type);
|
|
1044
|
+
|
|
1045
|
+
if (!agent) {
|
|
1046
|
+
throw new Error(`No agent available for ${request.type}`);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
const result = await agent.generate({
|
|
1050
|
+
prompt: request.description,
|
|
1051
|
+
options: {
|
|
1052
|
+
context: request.metadata,
|
|
1053
|
+
userId: request.userId,
|
|
1054
|
+
}
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
// Store integration result
|
|
1058
|
+
await agents.memory.store(`integration:${request.id}`, {
|
|
1059
|
+
result,
|
|
1060
|
+
timestamp: Date.now(),
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
return result;
|
|
1064
|
+
}
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
**Best Practices Applied:**
|
|
1068
|
+
|
|
1069
|
+
- Agent specialization for different domains
|
|
1070
|
+
- MCP integration for external tool access
|
|
1071
|
+
- Centralized orchestration through manager
|
|
1072
|
+
- Persistent memory for integration tracking
|
|
1073
|
+
|
|
1074
|
+
---
|
|
1075
|
+
|
|
1076
|
+
#### Case E: Educational Tutor (EdTech)
|
|
1077
|
+
|
|
1078
|
+
**Scenario:** An educational platform needs an AI tutor that can adapt to student learning styles, track progress, and provide personalized learning paths.
|
|
1079
|
+
|
|
1080
|
+
**Implementation:**
|
|
1081
|
+
|
|
1082
|
+
```typescript
|
|
1083
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
1084
|
+
|
|
1085
|
+
// Student progress tracker
|
|
1086
|
+
const progressTool = IgniterAgentTool.create("track_progress")
|
|
1087
|
+
.withInput(
|
|
1088
|
+
z.object({
|
|
1089
|
+
studentId: z.string(),
|
|
1090
|
+
subject: z.string(),
|
|
1091
|
+
topic: z.string(),
|
|
1092
|
+
score: z.number(),
|
|
1093
|
+
timeSpent: z.number(),
|
|
1094
|
+
}),
|
|
1095
|
+
)
|
|
1096
|
+
.withOutput(
|
|
1097
|
+
z.object({
|
|
1098
|
+
updatedProgress: z.record(z.unknown()),
|
|
1099
|
+
recommendations: z.array(z.string()),
|
|
1100
|
+
nextTopics: z.array(z.string()),
|
|
1101
|
+
}),
|
|
1102
|
+
)
|
|
1103
|
+
.withExecute(async ({ studentId, subject, topic, score, timeSpent }) => {
|
|
1104
|
+
const progress = await db.studentProgress.upsert({
|
|
1105
|
+
where: { studentId_subject_topic: { studentId, subject, topic } },
|
|
1106
|
+
update: { score, timeSpent: { increment: timeSpent } },
|
|
1107
|
+
create: { studentId, subject, topic, score, timeSpent },
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
const recommendations = await generateRecommendations(progress);
|
|
1111
|
+
const nextTopics = await suggestNextTopics(progress);
|
|
1112
|
+
|
|
1113
|
+
return {
|
|
1114
|
+
updatedProgress: progress,
|
|
1115
|
+
recommendations,
|
|
1116
|
+
nextTopics,
|
|
1117
|
+
};
|
|
1118
|
+
})
|
|
1119
|
+
.build();
|
|
1120
|
+
|
|
1121
|
+
// Learning style analyzer
|
|
1122
|
+
const styleTool = IgniterAgentTool.create("analyze_learning_style")
|
|
1123
|
+
.withInput(
|
|
1124
|
+
z.object({
|
|
1125
|
+
studentId: z.string(),
|
|
1126
|
+
responses: z.array(
|
|
1127
|
+
z.object({
|
|
1128
|
+
question: z.string(),
|
|
1129
|
+
answer: z.string(),
|
|
1130
|
+
timeToAnswer: z.number(),
|
|
1131
|
+
}),
|
|
1132
|
+
),
|
|
1133
|
+
}),
|
|
1134
|
+
)
|
|
1135
|
+
.withOutput(
|
|
1136
|
+
z.object({
|
|
1137
|
+
learningStyle: z.enum(["visual", "auditory", "kinesthetic", "reading"]),
|
|
1138
|
+
confidence: z.number(),
|
|
1139
|
+
explanation: z.string(),
|
|
1140
|
+
}),
|
|
1141
|
+
)
|
|
1142
|
+
.withExecute(async ({ studentId, responses }) => {
|
|
1143
|
+
const analysis = await analyzeLearningStyle(responses);
|
|
1144
|
+
return analysis;
|
|
1145
|
+
})
|
|
1146
|
+
.build();
|
|
1147
|
+
|
|
1148
|
+
// Personalized content generator
|
|
1149
|
+
const contentTool = IgniterAgentTool.create("generate_lesson")
|
|
1150
|
+
.withInput(
|
|
1151
|
+
z.object({
|
|
1152
|
+
topic: z.string(),
|
|
1153
|
+
learningStyle: z.enum(["visual", "auditory", "kinesthetic", "reading"]),
|
|
1154
|
+
difficulty: z.enum(["beginner", "intermediate", "advanced"]),
|
|
1155
|
+
studentProgress: z.record(z.unknown()),
|
|
1156
|
+
}),
|
|
1157
|
+
)
|
|
1158
|
+
.withOutput(
|
|
1159
|
+
z.object({
|
|
1160
|
+
lessonPlan: z.object({
|
|
1161
|
+
title: z.string(),
|
|
1162
|
+
objectives: z.array(z.string()),
|
|
1163
|
+
content: z.string(),
|
|
1164
|
+
exercises: z.array(z.string()),
|
|
1165
|
+
assessment: z.string(),
|
|
1166
|
+
}),
|
|
1167
|
+
estimatedTime: z.number(),
|
|
1168
|
+
resources: z.array(z.string()),
|
|
1169
|
+
}),
|
|
1170
|
+
)
|
|
1171
|
+
.withExecute(
|
|
1172
|
+
async ({ topic, learningStyle, difficulty, studentProgress }) => {
|
|
1173
|
+
const lesson = await generatePersonalizedLesson({
|
|
1174
|
+
topic,
|
|
1175
|
+
learningStyle,
|
|
1176
|
+
difficulty,
|
|
1177
|
+
studentProgress,
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
return lesson;
|
|
1181
|
+
},
|
|
1182
|
+
)
|
|
1183
|
+
.build();
|
|
1184
|
+
|
|
1185
|
+
// AI Tutor Agent
|
|
1186
|
+
const tutorAgent = IgniterAgent.create("ai-tutor")
|
|
1187
|
+
.withToolset(
|
|
1188
|
+
IgniterAgentToolset.create()
|
|
1189
|
+
.addTool(progressTool)
|
|
1190
|
+
.addTool(styleTool)
|
|
1191
|
+
.addTool(contentTool)
|
|
1192
|
+
.build(),
|
|
1193
|
+
)
|
|
1194
|
+
.withSystemPrompt(
|
|
1195
|
+
`
|
|
1196
|
+
You are an expert AI tutor who adapts to each student's unique learning style and pace.
|
|
1197
|
+
Use the available tools to:
|
|
1198
|
+
1. Track student progress and performance
|
|
1199
|
+
2. Analyze learning styles based on their interaction patterns
|
|
1200
|
+
3. Generate personalized lesson plans and content
|
|
1201
|
+
4. Provide encouragement and adapt difficulty as needed
|
|
1202
|
+
|
|
1203
|
+
Always maintain a supportive, patient, and encouraging tone.
|
|
1204
|
+
`,
|
|
1205
|
+
)
|
|
1206
|
+
.withMemory(MemoryAdapter.create())
|
|
1207
|
+
.onAgentStart(async (input, context) => {
|
|
1208
|
+
// Load student profile and learning history
|
|
1209
|
+
const studentData = await loadStudentProfile(context.userId);
|
|
1210
|
+
context.studentProfile = studentData;
|
|
1211
|
+
})
|
|
1212
|
+
.onToolCallEnd(async (result, context) => {
|
|
1213
|
+
// Update learning analytics
|
|
1214
|
+
await updateLearningAnalytics(context.userId, result);
|
|
1215
|
+
})
|
|
1216
|
+
.build();
|
|
1217
|
+
|
|
1218
|
+
// Conduct a tutoring session
|
|
1219
|
+
async function conductTutoringSession(studentId: string, topic: string) {
|
|
1220
|
+
const sessionPrompt = `
|
|
1221
|
+
Start a personalized tutoring session for student ${studentId} on the topic: "${topic}"
|
|
1222
|
+
|
|
1223
|
+
1. Review their learning progress and style preferences
|
|
1224
|
+
2. Assess their current knowledge level
|
|
1225
|
+
3. Create a customized lesson plan
|
|
1226
|
+
4. Guide them through the learning material
|
|
1227
|
+
5. Provide practice exercises and feedback
|
|
1228
|
+
6. Update their progress tracking
|
|
1229
|
+
|
|
1230
|
+
Make the session engaging and adapt to their learning style.
|
|
1231
|
+
`;
|
|
1232
|
+
|
|
1233
|
+
const session = await tutorAgent.generate({
|
|
1234
|
+
prompt: sessionPrompt,
|
|
1235
|
+
options: {
|
|
1236
|
+
userId: studentId,
|
|
1237
|
+
context: { type: "tutoring_session", topic },
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
return session;
|
|
1242
|
+
}
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
**Best Practices Applied:**
|
|
1246
|
+
|
|
1247
|
+
- Comprehensive student profiling and progress tracking
|
|
1248
|
+
- Adaptive content generation based on learning styles
|
|
1249
|
+
- Extensive memory usage for personalized interactions
|
|
1250
|
+
- Analytics integration for continuous improvement
|
|
1251
|
+
|
|
1252
|
+
---
|
|
1253
|
+
|
|
1254
|
+
### 11. Domain-Specific Guidance
|
|
1255
|
+
|
|
1256
|
+
#### Enterprise Integration Platforms
|
|
1257
|
+
|
|
1258
|
+
**Guidance:** Use multi-agent orchestration with specialized agents for different integration domains (CRM, ERP, HR, Finance).
|
|
1259
|
+
|
|
1260
|
+
```typescript
|
|
1261
|
+
const integrationManager = IgniterAgentManager.create()
|
|
1262
|
+
.addAgent(crmAgent)
|
|
1263
|
+
.addAgent(erpAgent)
|
|
1264
|
+
.addAgent(hrAgent)
|
|
1265
|
+
.addAgent(financeAgent)
|
|
1266
|
+
.build();
|
|
1267
|
+
|
|
1268
|
+
// Route requests to appropriate domain expert
|
|
1269
|
+
const agent = manager.getAgentget.domain);
|
|
1270
|
+
```
|
|
1271
|
+
|
|
1272
|
+
#### AI-Powered Development Tools
|
|
1273
|
+
|
|
1274
|
+
**Guidance:** Integrate with MCP servers for access to development tools, documentation, and code analysis.
|
|
1275
|
+
|
|
1276
|
+
```typescript
|
|
1277
|
+
const devAgent = IgniterAgent.create("dev-assistant")
|
|
1278
|
+
.withMCPClient(
|
|
1279
|
+
IgniterAgentMCPClient.create()
|
|
1280
|
+
.withServerUrl("http://localhost:3000/dev-tools")
|
|
1281
|
+
.withToolFilter(["include", ["code.analyze", "docs.search", "test.run"]])
|
|
1282
|
+
.build(),
|
|
1283
|
+
)
|
|
1284
|
+
.build();
|
|
1285
|
+
```
|
|
1286
|
+
|
|
1287
|
+
#### Customer Service Automation
|
|
1288
|
+
|
|
1289
|
+
**Guidance:** Combine memory persistence with tool-based actions for comprehensive customer support.
|
|
1290
|
+
|
|
1291
|
+
```typescript
|
|
1292
|
+
const supportAgent = IgniterAgent.create("customer-support")
|
|
1293
|
+
.withMemory(MemoryAdapter.create())
|
|
1294
|
+
.withToolset(customerSupportToolset)
|
|
1295
|
+
.withSystemPrompt(
|
|
1296
|
+
"Provide excellent customer support using available tools and context",
|
|
1297
|
+
)
|
|
1298
|
+
.onAgentComplete(async (result, context) => {
|
|
1299
|
+
await updateCustomerSatisfaction(context.customerId, result);
|
|
1300
|
+
})
|
|
1301
|
+
.build();
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
---
|
|
1305
|
+
|
|
1306
|
+
### 12. Best Practices & Anti-Patterns
|
|
1307
|
+
|
|
1308
|
+
| Practice | Why | Example |
|
|
1309
|
+
| ------------------------------------- | ---------------------------------------------------- | -------------------------------------------------- |
|
|
1310
|
+
| ✅ **Use typed tool schemas** | Prevents runtime errors and ensures data consistency | `withInput(z.object({ id: z.string() }))` |
|
|
1311
|
+
| ✅ **Implement memory persistence** | Maintains context across interactions | `withMemory(MemoryAdapter.create())` |
|
|
1312
|
+
| ✅ **Add comprehensive telemetry** | Enables observability and debugging | `withTelemetry(telemetryManager)` |
|
|
1313
|
+
| ✅ **Use agent hooks** | Enables custom logic and monitoring | `onToolCallEnd(handler)` |
|
|
1314
|
+
| ✅ **Validate all inputs/outputs** | Ensures data integrity | `withOutput(z.object({ result: z.string() }))` |
|
|
1315
|
+
| ❌ **Don't overuse memory** | Can impact performance and costs | Only store essential conversation data |
|
|
1316
|
+
| ❌ **Don't create monolithic agents** | Harder to maintain and test | Use specialized agents with clear responsibilities |
|
|
1317
|
+
| ❌ **Don't ignore telemetry** | Makes debugging production issues difficult | Always configure telemetry in production |
|
|
1318
|
+
| ❌ **Don't skip schema validation** | Leads to runtime errors | Always define input/output schemas |
|
|
1319
|
+
| ❌ **Don't block on tool calls** | Degrades user experience | Use async tool implementations |
|
|
1320
|
+
|
|
1321
|
+
---
|
|
1322
|
+
|
|
1323
|
+
## III. TECHNICAL REFERENCE & RESILIENCE
|
|
1324
|
+
|
|
1325
|
+
### 13. Exhaustive API Reference
|
|
1326
|
+
|
|
1327
|
+
#### Core Classes
|
|
1328
|
+
|
|
1329
|
+
| Class | Purpose | Key Methods |
|
|
1330
|
+
| ---------------------------- | --------------------- | ------------------------------------------------------------------------ |
|
|
1331
|
+
| `IgniterAgentBuilder` | Agent configuration | `withModel()`, `withToolset()`, `withMemory()`, `build()` |
|
|
1332
|
+
| `IgniterAgentCore` | Agent runtime | `start()`, `stop()`, `generate()`, `stream()` |
|
|
1333
|
+
| `IgniterAgentManagerBuilder` | Manager configuration | `addAgent()`, `withLogger()`, `withTelemetry()`, `build()` |
|
|
1334
|
+
| `IgniterAgentManagerCore` | Manager runtime | `start()`, `startAll()`, `get()`, `getStatus()` |
|
|
1335
|
+
| `IgniterAgentTool` | Tool definition | `withDescription()`, `withInput()`, `withExecute()`, `build()` |
|
|
1336
|
+
| `IgniterAgentToolset` | Tool composition | `addTool()`, `getName()`, `getTools()`, `build()` |
|
|
1337
|
+
| `IgniterAgentMCPClient` | MCP integration | `withType()`, `withCommand()`, `withURL()`, `build()` |
|
|
1338
|
+
| `IgniterAgentPrompt` | Prompt engineering | `withTemplate()`, `withVariables()`, `render()` |
|
|
1339
|
+
|
|
1340
|
+
#### Builder Pattern Methods
|
|
1341
|
+
|
|
1342
|
+
| Builder | Method | Purpose |
|
|
1343
|
+
| --------------------- | -------------------------- | -------------------------------- |
|
|
1344
|
+
| `IgniterAgentBuilder` | `withModel(model)` | Set AI model |
|
|
1345
|
+
| | `withInstructions(prompt)` | Configure AI system instructions |
|
|
1346
|
+
| | `withToolset(toolset)` | Add toolset |
|
|
1347
|
+
| | `withMCP(mcp)` | Add MCP configuration |
|
|
1348
|
+
| | `withMemory(adapter)` | Configure memory persistence |
|
|
1349
|
+
| | `withContextSchema(schema)`| Define context schema |
|
|
1350
|
+
| | `build()` | Create agent instance |
|
|
1351
|
+
|
|
1352
|
+
#### Runtime Methods
|
|
1353
|
+
|
|
1354
|
+
| Class | Method | Signature | Purpose |
|
|
1355
|
+
| ------------------ | ------------------- | ---------------------------------------------------------------- | ------------------------------ |
|
|
1356
|
+
| `IgniterAgentCore` | `start` | `start() => Promise<void>` | Start agent and initialize MCP |
|
|
1357
|
+
| | `stop` | `stop() => Promise<void>` | Stop agent and disconnect MCP |
|
|
1358
|
+
| | `generate` | `generate(input: AgentCallParameters) => Promise<any>` | Generate response from agent |
|
|
1359
|
+
| | `stream` | `stream(input: AgentStreamParameters) => Promise<any>` | Stream response from agent |
|
|
1360
|
+
| | `getName` | `getName() => string` | Get agent name |
|
|
1361
|
+
| | `getToolsets` | `getToolsets() => TAgentToolsets` | Get all registered toolsets |
|
|
1362
|
+
| | `getTools` | `getTools() => ToolSet` | Get all tools |
|
|
1363
|
+
| | `getModel` | `getModel() => TAgentModel` | Get configured model |
|
|
1364
|
+
| | `getInstructions` | `getInstructions() => TAgentInstructions` | Get configured instructions |
|
|
1365
|
+
| | `getContextSchema` | `getContextSchema() => TAgentContextSchema` | Get context schema |
|
|
1366
|
+
| | `attachLogger` | `attachLogger(logger?) => void` | Attach logger instance |
|
|
1367
|
+
| | `attachTelemetry` | `attachTelemetry(telemetry?) => void` | Attach telemetry manager |
|
|
1368
|
+
| | `attachHooks` | `attachHooks(hooks?) => void` | Attach hook callbacks |
|
|
1369
|
+
| | `memory` | `IgniterAgentMemoryCore \| undefined` | Memory instance property |
|
|
1370
|
+
|
|
1371
|
+
### 14. Telemetry & Observability Registry
|
|
1372
|
+
|
|
1373
|
+
#### Agent Lifecycle Events
|
|
1374
|
+
|
|
1375
|
+
| Event Key | Attributes | Context |
|
|
1376
|
+
| -------------------------------- | -------------------------------------------------------- | -------------------------------------- |
|
|
1377
|
+
| `igniter.agents.agent.started` | `agent.name`, `agent.input_length` | Agent execution begins |
|
|
1378
|
+
| `igniter.agents.agent.completed` | `agent.name`, `agent.output_length`, `agent.duration_ms` | Agent execution completes successfully |
|
|
1379
|
+
| `igniter.agents.agent.error` | `agent.name`, `agent.error.code`, `agent.error.message` | Agent execution fails |
|
|
1380
|
+
|
|
1381
|
+
#### Tool Execution Events
|
|
1382
|
+
|
|
1383
|
+
| Event Key | Attributes | Context |
|
|
1384
|
+
| ------------------------------- | ------------------------------------------------------------------ | ------------------------ |
|
|
1385
|
+
| `igniter.agents.tool.called` | `tool.name`, `agent.name`, `tool.input_size` | Tool execution begins |
|
|
1386
|
+
| `igniter.agents.tool.completed` | `tool.name`, `agent.name`, `tool.output_size`, `tool.duration_ms` | Tool execution completes |
|
|
1387
|
+
| `igniter.agents.tool.error` | `tool.name`, `agent.name`, `tool.error.code`, `tool.error.message` | Tool execution fails |
|
|
1388
|
+
|
|
1389
|
+
#### Memory Events
|
|
1390
|
+
|
|
1391
|
+
| Event Key | Attributes | Context |
|
|
1392
|
+
| --------------------------------- | ------------------------------------------------- | -------------------------- |
|
|
1393
|
+
| `igniter.agents.memory.stored` | `memory.key`, `memory.size_bytes` | Data stored in memory |
|
|
1394
|
+
| `igniter.agents.memory.retrieved` | `memory.key`, `memory.size_bytes`, `memory.found` | Data retrieved from memory |
|
|
1395
|
+
| `igniter.agents.memory.error` | `memory.operation`, `memory.error.code` | Memory operation fails |
|
|
1396
|
+
|
|
1397
|
+
#### MCP Events
|
|
1398
|
+
|
|
1399
|
+
| Event Key | Attributes | Context |
|
|
1400
|
+
| ------------------------------------- | -------------------------------------- | -------------------------------- |
|
|
1401
|
+
| `igniter.agents.mcp.connected` | `mcp.server_url`, `mcp.tools_count` | MCP connection established |
|
|
1402
|
+
| `igniter.agents.mcp.message.sent` | `mcp.message_type`, `mcp.message_size` | Message sent to MCP server |
|
|
1403
|
+
| `igniter.agents.mcp.message.received` | `mcp.message_type`, `mcp.message_size` | Message received from MCP server |
|
|
1404
|
+
| `igniter.agents.mcp.error` | `mcp.operation`, `mcp.error.code` | MCP operation fails |
|
|
1405
|
+
|
|
1406
|
+
#### Manager Events
|
|
1407
|
+
|
|
1408
|
+
| Event Key | Attributes | Context |
|
|
1409
|
+
| --------------------------------------- | --------------------------------------------------------------------- | ----------------------------- |
|
|
1410
|
+
| `igniter.agents.manager.created` | `manager.agents_count`, `manager.has_memory`, `manager.has_telemetry` | Manager instance created |
|
|
1411
|
+
| `igniter.agents.manager.agents.started` | `manager.started_count`, `manager.failed_count` | Batch agent startup completed |
|
|
1412
|
+
|
|
1413
|
+
### 14.5 Error Classes Reference
|
|
1414
|
+
|
|
1415
|
+
The `@igniter-js/agents` package provides a comprehensive error hierarchy for precise error handling and debugging.
|
|
1416
|
+
|
|
1417
|
+
#### Base Error Class
|
|
1418
|
+
|
|
1419
|
+
**`IgniterAgentError`**
|
|
1420
|
+
|
|
1421
|
+
Base error class that extends `IgniterError` from `@igniter-js/core`. All agent-related errors inherit from this class.
|
|
1422
|
+
|
|
1423
|
+
```typescript
|
|
1424
|
+
import { IgniterAgentError, IgniterAgentErrorCode } from '@igniter-js/agents';
|
|
1425
|
+
|
|
1426
|
+
throw new IgniterAgentError({
|
|
1427
|
+
message: 'Something went wrong',
|
|
1428
|
+
code: IgniterAgentErrorCode.UNKNOWN,
|
|
1429
|
+
causer: 'Agent',
|
|
1430
|
+
metadata: { operation: 'generate' },
|
|
1431
|
+
details: { attemptedAction: 'startAgent' }
|
|
1432
|
+
});
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
**Properties:**
|
|
1436
|
+
- `code`: `IgniterAgentErrorCode` - Error classification code
|
|
1437
|
+
- `message`: `string` - Human-readable error description
|
|
1438
|
+
- `statusCode`: `number` - HTTP status code (defaults to 500)
|
|
1439
|
+
- `causer`: `string` - Component that threw the error
|
|
1440
|
+
- `details`: `unknown` - Additional error context
|
|
1441
|
+
- `metadata`: `Record<string, unknown>` - Extended metadata
|
|
1442
|
+
- `cause`: `Error` - Original error if wrapping another error
|
|
1443
|
+
|
|
1444
|
+
---
|
|
1445
|
+
|
|
1446
|
+
#### Specialized Error Classes
|
|
1447
|
+
|
|
1448
|
+
**`IgniterAgentConfigError`**
|
|
1449
|
+
|
|
1450
|
+
Thrown when agent/tool/manager configuration is invalid.
|
|
1451
|
+
|
|
1452
|
+
```typescript
|
|
1453
|
+
import { IgniterAgentConfigError } from '@igniter-js/agents';
|
|
1454
|
+
|
|
1455
|
+
throw new IgniterAgentConfigError({
|
|
1456
|
+
message: 'Model is required but was not provided',
|
|
1457
|
+
field: 'model' // Specific config field that failed
|
|
1458
|
+
});
|
|
1459
|
+
```
|
|
1460
|
+
|
|
1461
|
+
**Unique Properties:**
|
|
1462
|
+
- `field`: `string` - The configuration field causing the error
|
|
1463
|
+
|
|
1464
|
+
---
|
|
1465
|
+
|
|
1466
|
+
**`IgniterAgentMCPError`**
|
|
1467
|
+
|
|
1468
|
+
Thrown when MCP connection, configuration, or tool execution fails.
|
|
1469
|
+
|
|
1470
|
+
```typescript
|
|
1471
|
+
import { IgniterAgentMCPError, IgniterAgentErrorCode } from '@igniter-js/agents';
|
|
1472
|
+
|
|
1473
|
+
throw new IgniterAgentMCPError({
|
|
1474
|
+
message: 'Failed to connect to MCP server',
|
|
1475
|
+
code: IgniterAgentErrorCode.MCP_CONNECTION_FAILED,
|
|
1476
|
+
mcpName: 'filesystem' // Name of the MCP config
|
|
1477
|
+
});
|
|
1478
|
+
```
|
|
1479
|
+
|
|
1480
|
+
**Unique Properties:**
|
|
1481
|
+
- `mcpName`: `string` - Name of the MCP configuration
|
|
1482
|
+
|
|
1483
|
+
---
|
|
1484
|
+
|
|
1485
|
+
**`IgniterAgentToolError`**
|
|
1486
|
+
|
|
1487
|
+
Thrown when tool definition validation or execution fails.
|
|
1488
|
+
|
|
1489
|
+
```typescript
|
|
1490
|
+
import { IgniterAgentToolError, IgniterAgentErrorCode } from '@igniter-js/agents';
|
|
1491
|
+
|
|
1492
|
+
throw new IgniterAgentToolError({
|
|
1493
|
+
message: 'Tool execution timed out after 30 seconds',
|
|
1494
|
+
code: IgniterAgentErrorCode.TOOL_EXECUTION_FAILED,
|
|
1495
|
+
toolName: 'github_createIssue' // Name of the tool
|
|
1496
|
+
});
|
|
1497
|
+
```
|
|
1498
|
+
|
|
1499
|
+
**Unique Properties:**
|
|
1500
|
+
- `toolName`: `string` - Name of the tool that failed
|
|
1501
|
+
|
|
1502
|
+
---
|
|
1503
|
+
|
|
1504
|
+
**`IgniterAgentMemoryError`**
|
|
1505
|
+
|
|
1506
|
+
Thrown when memory adapter operations fail.
|
|
1507
|
+
|
|
1508
|
+
```typescript
|
|
1509
|
+
import { IgniterAgentMemoryError, IgniterAgentErrorCode } from '@igniter-js/agents';
|
|
1510
|
+
|
|
1511
|
+
throw new IgniterAgentMemoryError({
|
|
1512
|
+
message: 'Failed to save conversation to memory',
|
|
1513
|
+
code: IgniterAgentErrorCode.MEMORY_UPDATE_FAILED,
|
|
1514
|
+
metadata: { chatId: 'chat_123', size: 5242880 }
|
|
1515
|
+
});
|
|
1516
|
+
```
|
|
1517
|
+
|
|
1518
|
+
---
|
|
1519
|
+
|
|
1520
|
+
**`IgniterAgentAdapterError`**
|
|
1521
|
+
|
|
1522
|
+
Thrown when custom adapter (memory, storage, etc.) operations fail.
|
|
1523
|
+
|
|
1524
|
+
```typescript
|
|
1525
|
+
import { IgniterAgentAdapterError, IgniterAgentErrorCode } from '@igniter-js/agents';
|
|
1526
|
+
|
|
1527
|
+
throw new IgniterAgentAdapterError({
|
|
1528
|
+
message: 'Redis connection lost',
|
|
1529
|
+
code: IgniterAgentErrorCode.ADAPTER_CONNECTION_FAILED,
|
|
1530
|
+
adapterName: 'redis' // Name of the adapter
|
|
1531
|
+
});
|
|
1532
|
+
```
|
|
1533
|
+
|
|
1534
|
+
**Unique Properties:**
|
|
1535
|
+
- `adapterName`: `string` - Name of the adapter implementation
|
|
1536
|
+
|
|
1537
|
+
---
|
|
1538
|
+
|
|
1539
|
+
#### Type Guards for Error Handling
|
|
1540
|
+
|
|
1541
|
+
Use type guards to safely narrow error types in catch blocks:
|
|
1542
|
+
|
|
1543
|
+
```typescript
|
|
1544
|
+
import {
|
|
1545
|
+
isIgniterAgentError,
|
|
1546
|
+
isIgniterAgentMCPError,
|
|
1547
|
+
isIgniterAgentToolError,
|
|
1548
|
+
IgniterAgentErrorCode
|
|
1549
|
+
} from '@igniter-js/agents';
|
|
1550
|
+
|
|
1551
|
+
try {
|
|
1552
|
+
await agent.generate({ messages: [...] });
|
|
1553
|
+
} catch (error) {
|
|
1554
|
+
// Safe type narrowing
|
|
1555
|
+
if (isIgniterAgentMCPError(error)) {
|
|
1556
|
+
console.error(`MCP Error [${error.mcpName}]:`, error.message);
|
|
1557
|
+
} else if (isIgniterAgentToolError(error)) {
|
|
1558
|
+
console.error(`Tool Error [${error.toolName}]:`, error.message);
|
|
1559
|
+
} else if (isIgniterAgentError(error)) {
|
|
1560
|
+
console.error(`Agent Error [${error.code}]:`, error.message);
|
|
1561
|
+
} else {
|
|
1562
|
+
console.error('Unknown error:', error);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
```
|
|
1566
|
+
|
|
1567
|
+
**Available Type Guards:**
|
|
1568
|
+
- `isIgniterAgentError(error)` - Check if error is any agent error
|
|
1569
|
+
- `isIgniterAgentMCPError(error)` - Check if error is MCP-related
|
|
1570
|
+
- `isIgniterAgentToolError(error)` - Check if error is tool-related
|
|
1571
|
+
|
|
1572
|
+
---
|
|
1573
|
+
|
|
1574
|
+
#### Error Code Hierarchy
|
|
1575
|
+
|
|
1576
|
+
All errors use standardized error codes from `IgniterAgentErrorCode` enum:
|
|
1577
|
+
|
|
1578
|
+
| Range | Category | Codes |
|
|
1579
|
+
|-------|----------|-------|
|
|
1580
|
+
| 1xx | General | `UNKNOWN`, `INVALID_CONFIG`, `MISSING_REQUIRED` |
|
|
1581
|
+
| 2xx | Agent | `AGENT_NOT_INITIALIZED`, `AGENT_MODEL_MISSING`, `AGENT_BUILD_FAILED`, `AGENT_CONTEXT_SCHEMA_INVALID` |
|
|
1582
|
+
| 3xx | MCP | `MCP_CONNECTION_FAILED`, `MCP_CLIENT_NOT_FOUND`, `MCP_TOOL_ERROR`, `MCP_INVALID_CONFIG` |
|
|
1583
|
+
| 4xx | Tool | `TOOL_EXECUTION_FAILED`, `TOOL_NOT_FOUND`, `TOOL_VALIDATION_FAILED` |
|
|
1584
|
+
| 5xx | Memory | `MEMORY_PROVIDER_ERROR`, `MEMORY_NOT_FOUND`, `MEMORY_UPDATE_FAILED` |
|
|
1585
|
+
| 6xx | Adapter | `ADAPTER_CONNECTION_FAILED`, `ADAPTER_OPERATION_FAILED`, `ADAPTER_NOT_INITIALIZED` |
|
|
1586
|
+
|
|
1587
|
+
---
|
|
1588
|
+
|
|
1589
|
+
### 15. Exhaustive Error & Troubleshooting Library
|
|
1590
|
+
|
|
1591
|
+
#### General Errors (1xx)
|
|
1592
|
+
|
|
1593
|
+
##### `IGNITER_AGENT_UNKNOWN_ERROR`
|
|
1594
|
+
|
|
1595
|
+
- **Context:** Unclassified or unexpected error occurs
|
|
1596
|
+
- **Cause:** Generic error that doesn't fit other categories
|
|
1597
|
+
- **Mitigation:** Add logging and monitoring to identify specific failures
|
|
1598
|
+
- **Solution:** Wrap external service calls with try-catch blocks
|
|
1599
|
+
- **Example:**
|
|
1600
|
+
```typescript
|
|
1601
|
+
try {
|
|
1602
|
+
await agent.generate({ messages: [] });
|
|
1603
|
+
} catch (error) {
|
|
1604
|
+
if (error.code === IgniterAgentErrorCode.UNKNOWN) {
|
|
1605
|
+
logger.error('Unexpected error:', error.cause);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
```
|
|
1609
|
+
|
|
1610
|
+
##### `IGNITER_AGENT_INVALID_CONFIG`
|
|
1611
|
+
|
|
1612
|
+
- **Context:** Configuration validation during builder chain or initialization
|
|
1613
|
+
- **Cause:** Missing or invalid configuration option (e.g., missing model, invalid field value)
|
|
1614
|
+
- **Mitigation:** Validate all required fields before calling `.build()`
|
|
1615
|
+
- **Solution:** Check builder chain for missing required methods
|
|
1616
|
+
- **Example:**
|
|
1617
|
+
```typescript
|
|
1618
|
+
// ❌ FAILS - No model configured
|
|
1619
|
+
const agent = IgniterAgent.create('test').build();
|
|
1620
|
+
|
|
1621
|
+
// ✅ WORKS - Model is configured
|
|
1622
|
+
const agent = IgniterAgent.create('test')
|
|
1623
|
+
.withModel(openai('gpt-4'))
|
|
1624
|
+
.build();
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1627
|
+
##### `IGNITER_AGENT_MISSING_REQUIRED`
|
|
1628
|
+
|
|
1629
|
+
- **Context:** Required dependency is missing when needed
|
|
1630
|
+
- **Cause:** A required component (logger, telemetry, memory) is not configured
|
|
1631
|
+
- **Mitigation:** Ensure all dependencies are configured before operations
|
|
1632
|
+
- **Solution:** Add missing dependencies to builder chain
|
|
1633
|
+
- **Example:**
|
|
1634
|
+
```typescript
|
|
1635
|
+
const agent = IgniterAgent.create('test')
|
|
1636
|
+
.withModel(model)
|
|
1637
|
+
.withLogger(logger) // Required for production
|
|
1638
|
+
.withTelemetry(telemetry) // Recommended
|
|
1639
|
+
.build();
|
|
1640
|
+
```
|
|
1641
|
+
|
|
1642
|
+
---
|
|
1643
|
+
|
|
1644
|
+
#### Agent Errors (2xx)
|
|
1645
|
+
|
|
1646
|
+
##### `IGNITER_AGENT_NOT_INITIALIZED`
|
|
1647
|
+
|
|
1648
|
+
- **Context:** Attempting to use agent before calling `.start()`
|
|
1649
|
+
- **Cause:** MCP connections or agent initialization not completed
|
|
1650
|
+
- **Mitigation:** Always call `await agent.start()` before using the agent
|
|
1651
|
+
- **Solution:** Initialize agent lifecycle properly
|
|
1652
|
+
- **Example:**
|
|
1653
|
+
```typescript
|
|
1654
|
+
const agent = IgniterAgent.create('test')
|
|
1655
|
+
.addMCP(mcpConfig)
|
|
1656
|
+
.build();
|
|
1657
|
+
|
|
1658
|
+
await agent.start(); // Required before generate()
|
|
1659
|
+
const result = await agent.generate({ messages: [...] });
|
|
1660
|
+
```
|
|
1661
|
+
|
|
1662
|
+
##### `IGNITER_AGENT_MODEL_MISSING`
|
|
1663
|
+
|
|
1664
|
+
- **Context:** `generate()` or `stream()` called without a model configured
|
|
1665
|
+
- **Cause:** `.withModel()` was not called on the builder
|
|
1666
|
+
- **Mitigation:** Configure model during builder setup
|
|
1667
|
+
- **Solution:** Add `.withModel()` to builder chain
|
|
1668
|
+
- **Example:**
|
|
1669
|
+
```typescript
|
|
1670
|
+
const agent = IgniterAgent.create('test')
|
|
1671
|
+
.withModel(openai('gpt-4')) // ✅ Required
|
|
1672
|
+
.build();
|
|
1673
|
+
```
|
|
1674
|
+
|
|
1675
|
+
##### `IGNITER_AGENT_BUILD_FAILED`
|
|
1676
|
+
|
|
1677
|
+
- **Context:** Agent construction fails during `.build()`
|
|
1678
|
+
- **Cause:** Invalid configuration detected during validation
|
|
1679
|
+
- **Mitigation:** Validate all config before building
|
|
1680
|
+
- **Solution:** Check error details for specific failures
|
|
1681
|
+
- **Example:**
|
|
1682
|
+
```typescript
|
|
1683
|
+
try {
|
|
1684
|
+
const agent = IgniterAgent.create('test').build();
|
|
1685
|
+
} catch (error) {
|
|
1686
|
+
if (error.code === IgniterAgentErrorCode.AGENT_BUILD_FAILED) {
|
|
1687
|
+
console.error('Config error:', error.details);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
```
|
|
1691
|
+
|
|
1692
|
+
##### `IGNITER_AGENT_CONTEXT_SCHEMA_INVALID`
|
|
1693
|
+
|
|
1694
|
+
- **Context:** Context passed to `generate()` or `stream()` doesn't match schema
|
|
1695
|
+
- **Cause:** Options data doesn't conform to declared context schema
|
|
1696
|
+
- **Mitigation:** Ensure context data matches schema definition
|
|
1697
|
+
- **Solution:** Validate context before passing to agent
|
|
1698
|
+
- **Example:**
|
|
1699
|
+
```typescript
|
|
1700
|
+
const contextSchema = z.object({
|
|
1701
|
+
userId: z.string(),
|
|
1702
|
+
chatId: z.string()
|
|
1703
|
+
});
|
|
1704
|
+
|
|
1705
|
+
const agent = IgniterAgent.create('test')
|
|
1706
|
+
.withContextSchema(contextSchema)
|
|
1707
|
+
.build();
|
|
1708
|
+
|
|
1709
|
+
// ✅ WORKS
|
|
1710
|
+
await agent.generate({
|
|
1711
|
+
messages: [...],
|
|
1712
|
+
options: { userId: 'user_123', chatId: 'chat_456' }
|
|
1713
|
+
});
|
|
1714
|
+
|
|
1715
|
+
// ❌ FAILS - Missing chatId
|
|
1716
|
+
await agent.generate({
|
|
1717
|
+
messages: [...],
|
|
1718
|
+
options: { userId: 'user_123' }
|
|
1719
|
+
});
|
|
1720
|
+
```
|
|
1721
|
+
|
|
1722
|
+
---
|
|
1723
|
+
|
|
1724
|
+
#### MCP Errors (3xx)
|
|
1725
|
+
|
|
1726
|
+
##### `IGNITER_AGENT_MCP_CONNECTION_FAILED`
|
|
1727
|
+
|
|
1728
|
+
- **Context:** MCP client fails to connect during `agent.start()`
|
|
1729
|
+
- **Cause:** Server unreachable, invalid URL, network error, or auth failure
|
|
1730
|
+
- **Mitigation:** Verify MCP server is running and accessible
|
|
1731
|
+
- **Solution:** Check server URL, network connectivity, and credentials
|
|
1732
|
+
- **Example:**
|
|
1733
|
+
```typescript
|
|
1734
|
+
const agent = IgniterAgent.create('test')
|
|
1735
|
+
.addMCP(
|
|
1736
|
+
IgniterAgentMCPClient.create('filesystem')
|
|
1737
|
+
.withType('stdio')
|
|
1738
|
+
.withCommand('npx')
|
|
1739
|
+
.withArgs(['-y', '@mcp/server-filesystem'])
|
|
1740
|
+
.build()
|
|
1741
|
+
)
|
|
1742
|
+
.build();
|
|
1743
|
+
|
|
1744
|
+
try {
|
|
1745
|
+
await agent.start(); // May throw MCP_CONNECTION_FAILED
|
|
1746
|
+
} catch (error) {
|
|
1747
|
+
if (isIgniterAgentMCPError(error)) {
|
|
1748
|
+
console.error(`MCP ${error.mcpName} failed:`, error.message);
|
|
1749
|
+
// Retry with exponential backoff
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
```
|
|
1753
|
+
|
|
1754
|
+
##### `IGNITER_AGENT_MCP_CLIENT_NOT_FOUND`
|
|
1755
|
+
|
|
1756
|
+
- **Context:** Attempting to use MCP that wasn't registered
|
|
1757
|
+
- **Cause:** MCP name doesn't match any registered config
|
|
1758
|
+
- **Mitigation:** Check MCP name spelling in agent config
|
|
1759
|
+
- **Solution:** Register MCP with `.addMCP()` before using
|
|
1760
|
+
- **Example:**
|
|
1761
|
+
```typescript
|
|
1762
|
+
const agent = IgniterAgent.create('test')
|
|
1763
|
+
.addMCP(filesystemMCP) // name = 'filesystem'
|
|
1764
|
+
.build();
|
|
1765
|
+
|
|
1766
|
+
// ✅ Correct
|
|
1767
|
+
const toolset = agent.getToolsets()['filesystem'];
|
|
1768
|
+
|
|
1769
|
+
// ❌ Wrong
|
|
1770
|
+
const toolset = agent.getToolsets()['file']; // Not found
|
|
1771
|
+
```
|
|
1772
|
+
|
|
1773
|
+
##### `IGNITER_AGENT_MCP_TOOL_ERROR`
|
|
1774
|
+
|
|
1775
|
+
- **Context:** MCP tool execution fails
|
|
1776
|
+
- **Cause:** Tool handler in MCP server throws error
|
|
1777
|
+
- **Mitigation:** Implement error handling in MCP server
|
|
1778
|
+
- **Solution:** Check MCP server logs for detailed error
|
|
1779
|
+
- **Example:**
|
|
1780
|
+
```typescript
|
|
1781
|
+
const result = await agent.generate({
|
|
1782
|
+
messages: [{
|
|
1783
|
+
role: 'user',
|
|
1784
|
+
content: 'Use filesystem tool to read /invalid/path'
|
|
1785
|
+
}]
|
|
1786
|
+
});
|
|
1787
|
+
// May throw MCP_TOOL_ERROR if filesystem server fails
|
|
1788
|
+
```
|
|
1789
|
+
|
|
1790
|
+
##### `IGNITER_AGENT_MCP_INVALID_CONFIG`
|
|
1791
|
+
|
|
1792
|
+
- **Context:** MCP configuration validation fails
|
|
1793
|
+
- **Cause:** Invalid URL format, missing required fields, invalid transport type
|
|
1794
|
+
- **Mitigation:** Validate MCP config before building
|
|
1795
|
+
- **Solution:** Check config against MCP type requirements
|
|
1796
|
+
- **Example:**
|
|
1797
|
+
```typescript
|
|
1798
|
+
// ❌ FAILS - Invalid URL
|
|
1799
|
+
IgniterAgentMCPClient.create('api')
|
|
1800
|
+
.withType('http')
|
|
1801
|
+
.withURL('not-a-url') // Invalid
|
|
1802
|
+
.build();
|
|
1803
|
+
|
|
1804
|
+
// ✅ WORKS
|
|
1805
|
+
IgniterAgentMCPClient.create('api')
|
|
1806
|
+
.withType('http')
|
|
1807
|
+
.withURL('https://api.example.com/mcp')
|
|
1808
|
+
.build();
|
|
1809
|
+
```
|
|
1810
|
+
|
|
1811
|
+
---
|
|
1812
|
+
|
|
1813
|
+
#### Tool Errors (4xx)
|
|
1814
|
+
|
|
1815
|
+
##### `IGNITER_AGENT_TOOL_EXECUTION_FAILED`
|
|
1816
|
+
|
|
1817
|
+
- **Context:** Custom tool handler throws error during execution
|
|
1818
|
+
- **Cause:** Tool handler logic fails (exception, validation error, external service failure)
|
|
1819
|
+
- **Mitigation:** Implement comprehensive error handling in tool handlers
|
|
1820
|
+
- **Solution:** Wrap tool handler in try-catch with proper error recovery
|
|
1821
|
+
- **Example:**
|
|
1822
|
+
```typescript
|
|
1823
|
+
const queryTool = IgniterAgentTool.create('database_query')
|
|
1824
|
+
.withDescription('Query the database')
|
|
1825
|
+
.withInput(z.object({ query: z.string() }))
|
|
1826
|
+
.withExecute(async ({ query }) => {
|
|
1827
|
+
try {
|
|
1828
|
+
const result = await database.query(query);
|
|
1829
|
+
return { success: true, data: result };
|
|
1830
|
+
} catch (error) {
|
|
1831
|
+
// Wrap in IgniterAgentToolError for consistency
|
|
1832
|
+
throw new IgniterAgentToolError({
|
|
1833
|
+
message: `Query failed: ${error.message}`,
|
|
1834
|
+
toolName: 'database_query',
|
|
1835
|
+
code: IgniterAgentErrorCode.TOOL_EXECUTION_FAILED,
|
|
1836
|
+
cause: error as Error
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
})
|
|
1840
|
+
.build();
|
|
1841
|
+
```
|
|
1842
|
+
|
|
1843
|
+
##### `IGNITER_AGENT_TOOL_NOT_FOUND`
|
|
1844
|
+
|
|
1845
|
+
- **Context:** Agent attempts to use tool that doesn't exist
|
|
1846
|
+
- **Cause:** Tool name not registered in any toolset
|
|
1847
|
+
- **Mitigation:** Ensure all tools are added to toolsets before building
|
|
1848
|
+
- **Solution:** Register tool with `.addTool()` to a toolset
|
|
1849
|
+
- **Example:**
|
|
1850
|
+
```typescript
|
|
1851
|
+
const toolset = IgniterAgentToolset.create('utils')
|
|
1852
|
+
.addTool(helperTool)
|
|
1853
|
+
.build();
|
|
1854
|
+
|
|
1855
|
+
const agent = IgniterAgent.create('test')
|
|
1856
|
+
.addToolset(toolset) // Tool is now available as 'utils.helperTool'
|
|
1857
|
+
.build();
|
|
1858
|
+
```
|
|
1859
|
+
|
|
1860
|
+
##### `IGNITER_AGENT_TOOL_VALIDATION_FAILED`
|
|
1861
|
+
|
|
1862
|
+
- **Context:** Tool input validation fails before execution
|
|
1863
|
+
- **Cause:** Input data doesn't match tool's input schema
|
|
1864
|
+
- **Mitigation:** Ensure tool input schema is accurate and complete
|
|
1865
|
+
- **Solution:** Validate data against schema before tool use
|
|
1866
|
+
- **Example:**
|
|
1867
|
+
```typescript
|
|
1868
|
+
const addTool = IgniterAgentTool.create('add_numbers')
|
|
1869
|
+
.withInput(z.object({
|
|
1870
|
+
a: z.number(),
|
|
1871
|
+
b: z.number()
|
|
1872
|
+
}))
|
|
1873
|
+
.withExecute(async ({ a, b }) => a + b)
|
|
1874
|
+
.build();
|
|
1875
|
+
|
|
1876
|
+
// ❌ FAILS - 'a' should be number, not string
|
|
1877
|
+
try {
|
|
1878
|
+
await addTool.execute({ a: '5', b: 10 }); // Throws TOOL_VALIDATION_FAILED
|
|
1879
|
+
} catch (error) {
|
|
1880
|
+
if (isIgniterAgentToolError(error)) {
|
|
1881
|
+
console.error('Tool validation failed:', error.message);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
```
|
|
1885
|
+
|
|
1886
|
+
---
|
|
1887
|
+
|
|
1888
|
+
#### Memory Errors (5xx)
|
|
1889
|
+
|
|
1890
|
+
##### `IGNITER_AGENT_MEMORY_PROVIDER_ERROR`
|
|
1891
|
+
|
|
1892
|
+
- **Context:** Memory adapter implementation fails
|
|
1893
|
+
- **Cause:** Adapter connection lost, storage backend failure, permission denied
|
|
1894
|
+
- **Mitigation:** Implement retry logic in adapter
|
|
1895
|
+
- **Solution:** Check adapter connectivity and permissions
|
|
1896
|
+
- **Example:**
|
|
1897
|
+
```typescript
|
|
1898
|
+
const agent = IgniterAgent.create('test')
|
|
1899
|
+
.withMemory(
|
|
1900
|
+
new CustomMemoryAdapter({
|
|
1901
|
+
url: process.env.MEMORY_URL,
|
|
1902
|
+
retryPolicy: { maxRetries: 3, backoffMs: 1000 }
|
|
1903
|
+
})
|
|
1904
|
+
)
|
|
1905
|
+
.build();
|
|
1906
|
+
|
|
1907
|
+
try {
|
|
1908
|
+
await agent.start();
|
|
1909
|
+
} catch (error) {
|
|
1910
|
+
if (error.code === IgniterAgentErrorCode.MEMORY_PROVIDER_ERROR) {
|
|
1911
|
+
console.error('Memory adapter failed:', error.message);
|
|
1912
|
+
// Implement fallback to in-memory storage
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
```
|
|
1916
|
+
|
|
1917
|
+
##### `IGNITER_AGENT_MEMORY_NOT_FOUND`
|
|
1918
|
+
|
|
1919
|
+
- **Context:** Requested memory key doesn't exist
|
|
1920
|
+
- **Cause:** Conversation history or data key was not stored
|
|
1921
|
+
- **Mitigation:** Check key naming and storage operations
|
|
1922
|
+
- **Solution:** Verify key exists before retrieval
|
|
1923
|
+
- **Example:**
|
|
1924
|
+
```typescript
|
|
1925
|
+
// ✅ WORKS - Check before access
|
|
1926
|
+
const messages = await agent.memory?.retrieve('chat_123');
|
|
1927
|
+
if (!messages) {
|
|
1928
|
+
console.log('No history for this chat');
|
|
1929
|
+
return [];
|
|
1930
|
+
}
|
|
1931
|
+
```
|
|
1932
|
+
|
|
1933
|
+
##### `IGNITER_AGENT_MEMORY_UPDATE_FAILED`
|
|
1934
|
+
|
|
1935
|
+
- **Context:** Writing to memory fails
|
|
1936
|
+
- **Cause:** Storage quota exceeded, permission denied, serialization error
|
|
1937
|
+
- **Mitigation:** Implement size limits and serialization checks
|
|
1938
|
+
- **Solution:** Compress or clean old data before storing
|
|
1939
|
+
- **Example:**
|
|
1940
|
+
```typescript
|
|
1941
|
+
// Implement memory rotation
|
|
1942
|
+
async function storeMessage(chatId: string, message: Message) {
|
|
1943
|
+
try {
|
|
1944
|
+
await agent.memory?.store(`chat:${chatId}`, message);
|
|
1945
|
+
} catch (error) {
|
|
1946
|
+
if (error.code === IgniterAgentErrorCode.MEMORY_UPDATE_FAILED) {
|
|
1947
|
+
// Clean old messages and retry
|
|
1948
|
+
await agent.memory?.delete(`chat:${chatId}`);
|
|
1949
|
+
await agent.memory?.store(`chat:${chatId}`, message);
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
```
|
|
1954
|
+
|
|
1955
|
+
---
|
|
1956
|
+
|
|
1957
|
+
#### Adapter Errors (6xx)
|
|
1958
|
+
|
|
1959
|
+
##### `IGNITER_AGENT_ADAPTER_CONNECTION_FAILED`
|
|
1960
|
+
|
|
1961
|
+
- **Context:** Custom adapter fails to connect to its backend
|
|
1962
|
+
- **Cause:** Network error, invalid credentials, backend unavailable
|
|
1963
|
+
- **Mitigation:** Verify backend is accessible before creating adapter
|
|
1964
|
+
- **Solution:** Check network, credentials, and backend status
|
|
1965
|
+
- **Example:**
|
|
1966
|
+
```typescript
|
|
1967
|
+
const redisAdapter = new RedisMemoryAdapter({
|
|
1968
|
+
host: process.env.REDIS_HOST,
|
|
1969
|
+
port: parseInt(process.env.REDIS_PORT || '6379'),
|
|
1970
|
+
retry: { maxRetries: 3 }
|
|
1971
|
+
});
|
|
1972
|
+
|
|
1973
|
+
try {
|
|
1974
|
+
await redisAdapter.connect();
|
|
1975
|
+
} catch (error) {
|
|
1976
|
+
if (error.code === IgniterAgentErrorCode.ADAPTER_CONNECTION_FAILED) {
|
|
1977
|
+
console.error('Redis connection failed:', error.adapterName);
|
|
1978
|
+
// Fall back to memory adapter
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
```
|
|
1982
|
+
|
|
1983
|
+
##### `IGNITER_AGENT_ADAPTER_OPERATION_FAILED`
|
|
1984
|
+
|
|
1985
|
+
- **Context:** Adapter operation (get, set, delete) fails
|
|
1986
|
+
- **Cause:** Backend error, corrupted data, serialization failure
|
|
1987
|
+
- **Mitigation:** Validate data before operations
|
|
1988
|
+
- **Solution:** Check adapter logs and data integrity
|
|
1989
|
+
- **Example:**
|
|
1990
|
+
```typescript
|
|
1991
|
+
try {
|
|
1992
|
+
await adapter.set('key', circularReferenceObject);
|
|
1993
|
+
} catch (error) {
|
|
1994
|
+
if (error.code === IgniterAgentErrorCode.ADAPTER_OPERATION_FAILED) {
|
|
1995
|
+
// Data not serializable
|
|
1996
|
+
console.error('Failed to store:', error.message);
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
```
|
|
2000
|
+
|
|
2001
|
+
##### `IGNITER_AGENT_ADAPTER_NOT_INITIALIZED`
|
|
2002
|
+
|
|
2003
|
+
- **Context:** Using adapter before initialization
|
|
2004
|
+
- **Cause:** Adapter.connect() or .initialize() not called
|
|
2005
|
+
- **Mitigation:** Always initialize adapters before use
|
|
2006
|
+
- **Solution:** Call initialization method and await completion
|
|
2007
|
+
- **Example:**
|
|
2008
|
+
```typescript
|
|
2009
|
+
const adapter = new CustomAdapter();
|
|
2010
|
+
|
|
2011
|
+
// ❌ FAILS - Not initialized
|
|
2012
|
+
await adapter.get('key');
|
|
2013
|
+
|
|
2014
|
+
// ✅ WORKS - Initialize first
|
|
2015
|
+
await adapter.initialize();
|
|
2016
|
+
const value = await adapter.get('key');
|
|
2017
|
+
```
|
|
2018
|
+
|
|
2019
|
+
---
|
|
2020
|
+
|
|
2021
|
+
### Error Handling Best Practices
|
|
2022
|
+
|
|
2023
|
+
#### Type-Safe Error Handling
|
|
2024
|
+
|
|
2025
|
+
Always use type guards to safely handle errors:
|
|
2026
|
+
|
|
2027
|
+
```typescript
|
|
2028
|
+
import {
|
|
2029
|
+
isIgniterAgentError,
|
|
2030
|
+
isIgniterAgentMCPError,
|
|
2031
|
+
isIgniterAgentToolError,
|
|
2032
|
+
IgniterAgentErrorCode
|
|
2033
|
+
} from '@igniter-js/agents';
|
|
2034
|
+
|
|
2035
|
+
try {
|
|
2036
|
+
await agent.generate({ messages: [...] });
|
|
2037
|
+
} catch (error) {
|
|
2038
|
+
if (isIgniterAgentMCPError(error)) {
|
|
2039
|
+
console.error(`MCP error in ${error.mcpName}:`, error.message);
|
|
2040
|
+
} else if (isIgniterAgentToolError(error)) {
|
|
2041
|
+
console.error(`Tool ${error.toolName} failed:`, error.message);
|
|
2042
|
+
} else if (isIgniterAgentError(error)) {
|
|
2043
|
+
console.error(`Agent error [${error.code}]:`, error.message);
|
|
2044
|
+
} else {
|
|
2045
|
+
console.error('Unknown error:', error);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
```
|
|
2049
|
+
|
|
2050
|
+
#### Error Recovery Patterns
|
|
2051
|
+
|
|
2052
|
+
Implement resilience with error-aware retry logic:
|
|
2053
|
+
|
|
2054
|
+
```typescript
|
|
2055
|
+
async function generateWithRetry(
|
|
2056
|
+
agent: IgniterAgentCore,
|
|
2057
|
+
input: AgentCallParameters,
|
|
2058
|
+
maxRetries = 3
|
|
2059
|
+
) {
|
|
2060
|
+
let lastError;
|
|
2061
|
+
|
|
2062
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
2063
|
+
try {
|
|
2064
|
+
return await agent.generate(input);
|
|
2065
|
+
} catch (error) {
|
|
2066
|
+
lastError = error;
|
|
2067
|
+
|
|
2068
|
+
// Retryable errors
|
|
2069
|
+
if (
|
|
2070
|
+
error.code === IgniterAgentErrorCode.MCP_CONNECTION_FAILED ||
|
|
2071
|
+
error.code === IgniterAgentErrorCode.MEMORY_PROVIDER_ERROR
|
|
2072
|
+
) {
|
|
2073
|
+
const backoff = Math.pow(2, attempt - 1) * 1000;
|
|
2074
|
+
console.warn(`Attempt ${attempt} failed, retrying in ${backoff}ms...`);
|
|
2075
|
+
await new Promise(resolve => setTimeout(resolve, backoff));
|
|
2076
|
+
continue;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
// Non-retryable errors
|
|
2080
|
+
throw error;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
throw lastError;
|
|
2085
|
+
}
|
|
2086
|
+
```
|
|
2087
|
+
|
|
2088
|
+
#### Error Wrapping and Normalization
|
|
2089
|
+
|
|
2090
|
+
Use the `wrapError` helper to normalize external errors:
|
|
2091
|
+
|
|
2092
|
+
```typescript
|
|
2093
|
+
import { wrapError, IgniterAgentErrorCode } from '@igniter-js/agents';
|
|
2094
|
+
|
|
2095
|
+
async function callExternalService(input: string) {
|
|
2096
|
+
try {
|
|
2097
|
+
return await externalService.process(input);
|
|
2098
|
+
} catch (error) {
|
|
2099
|
+
// Normalize error into IgniterAgentError
|
|
2100
|
+
throw wrapError(error, {
|
|
2101
|
+
message: 'External service call failed',
|
|
2102
|
+
code: IgniterAgentErrorCode.ADAPTER_OPERATION_FAILED,
|
|
2103
|
+
causer: 'ExternalService',
|
|
2104
|
+
metadata: { service: 'payment-processor', input }
|
|
2105
|
+
});
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
```
|
|
2109
|
+
|
|
2110
|
+
#### Custom Error Logging Pattern
|
|
2111
|
+
|
|
2112
|
+
Implement structured error logging for observability:
|
|
2113
|
+
|
|
2114
|
+
```typescript
|
|
2115
|
+
import { isIgniterAgentError } from '@igniter-js/agents';
|
|
2116
|
+
|
|
2117
|
+
function logAgentError(error: unknown, context: Record<string, unknown>) {
|
|
2118
|
+
if (isIgniterAgentError(error)) {
|
|
2119
|
+
const errorLog = {
|
|
2120
|
+
timestamp: new Date().toISOString(),
|
|
2121
|
+
code: error.code,
|
|
2122
|
+
message: error.message,
|
|
2123
|
+
causer: error.causer,
|
|
2124
|
+
details: error.details,
|
|
2125
|
+
metadata: { ...error.metadata, ...context },
|
|
2126
|
+
cause: error.cause?.message,
|
|
2127
|
+
stack: error.stack
|
|
2128
|
+
};
|
|
2129
|
+
|
|
2130
|
+
// Send to logging service
|
|
2131
|
+
logger.error('Agent Error', errorLog);
|
|
2132
|
+
|
|
2133
|
+
// Send to observability platform
|
|
2134
|
+
telemetry.emit('agent.error', {
|
|
2135
|
+
attributes: {
|
|
2136
|
+
'ctx.error.code': error.code,
|
|
2137
|
+
'ctx.error.message': error.message,
|
|
2138
|
+
'ctx.causer': error.causer,
|
|
2139
|
+
...context
|
|
2140
|
+
}
|
|
2141
|
+
});
|
|
2142
|
+
} else {
|
|
2143
|
+
logger.error('Unknown error in agent context', { error, context });
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
// Usage
|
|
2148
|
+
try {
|
|
2149
|
+
await agent.generate({ messages: [...] });
|
|
2150
|
+
} catch (error) {
|
|
2151
|
+
logAgentError(error, { operation: 'generate', agentName: 'assistant' });
|
|
2152
|
+
}
|
|
2153
|
+
```
|
|
2154
|
+
|
|
2155
|
+
---
|
|
2156
|
+
|
|
2157
|
+
---
|
|
2158
|
+
|
|
2159
|
+
### 16. Advanced Configuration Patterns
|
|
2160
|
+
|
|
2161
|
+
#### Custom Context Types
|
|
2162
|
+
|
|
2163
|
+
For complex applications requiring strongly-typed context throughout the agent lifecycle:
|
|
2164
|
+
|
|
2165
|
+
```typescript
|
|
2166
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
2167
|
+
import { z } from "zod";
|
|
2168
|
+
|
|
2169
|
+
// Define application-specific context type
|
|
2170
|
+
interface MyAppContext {
|
|
2171
|
+
userId: string;
|
|
2172
|
+
tenantId: string;
|
|
2173
|
+
permissions: string[];
|
|
2174
|
+
database: PrismaClient;
|
|
2175
|
+
cache: RedisClient;
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
// Create agent with custom context inference
|
|
2179
|
+
const agent = IgniterAgent.create("advanced-agent")
|
|
2180
|
+
.withToolset(
|
|
2181
|
+
IgniterAgentToolset.create()
|
|
2182
|
+
.addTool(
|
|
2183
|
+
IgniterAgentTool.create("admin_action")
|
|
2184
|
+
.withInput(z.object({ action: z.string() }))
|
|
2185
|
+
.withExecute(async ({ action }, context: MyAppContext) => {
|
|
2186
|
+
// Context is fully typed
|
|
2187
|
+
if (!context.permissions.includes("admin")) {
|
|
2188
|
+
throw new Error("Insufficient permissions");
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
// Use typed database and cache
|
|
2192
|
+
await context.database.adminAction.create({
|
|
2193
|
+
data: { action, userId: context.userId },
|
|
2194
|
+
});
|
|
2195
|
+
await context.cache.invalidate(
|
|
2196
|
+
`tenant:${context.tenantId}:actions`,
|
|
2197
|
+
);
|
|
2198
|
+
|
|
2199
|
+
return { success: true };
|
|
2200
|
+
})
|
|
2201
|
+
.build(),
|
|
2202
|
+
)
|
|
2203
|
+
.build(),
|
|
2204
|
+
)
|
|
2205
|
+
.withSystemPrompt(
|
|
2206
|
+
"You are an advanced agent with full application context access.",
|
|
2207
|
+
)
|
|
2208
|
+
.build();
|
|
2209
|
+
|
|
2210
|
+
// Usage with typed context
|
|
2211
|
+
const result = await agent.generate({
|
|
2212
|
+
prompt: "perform admin cleanup",
|
|
2213
|
+
options: {
|
|
2214
|
+
userId: "user123",
|
|
2215
|
+
tenantId: "tenant456",
|
|
2216
|
+
permissions: ["admin", "write"],
|
|
2217
|
+
database: prismaClient,
|
|
2218
|
+
cache: redisClient,
|
|
2219
|
+
}
|
|
2220
|
+
});
|
|
2221
|
+
```
|
|
2222
|
+
|
|
2223
|
+
#### Dynamic Tool Registration
|
|
2224
|
+
|
|
2225
|
+
For agents that need to register tools based on runtime conditions:
|
|
2226
|
+
|
|
2227
|
+
```typescript
|
|
2228
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
2229
|
+
|
|
2230
|
+
class DynamicToolRegistry {
|
|
2231
|
+
private tools = new Map<string, IgniterAgentTool>();
|
|
2232
|
+
|
|
2233
|
+
registerTool(
|
|
2234
|
+
name: string,
|
|
2235
|
+
config: { schema: z.ZodSchema; handler: Function },
|
|
2236
|
+
) {
|
|
2237
|
+
const tool = IgniterAgentTool.create()
|
|
2238
|
+
.withName(name)
|
|
2239
|
+
.withInput(config.schema)
|
|
2240
|
+
.withExecute(config.handler)
|
|
2241
|
+
.build();
|
|
2242
|
+
|
|
2243
|
+
this.tools.set(name, tool);
|
|
2244
|
+
return this;
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
buildToolset(): IgniterAgentToolset {
|
|
2248
|
+
const toolset = IgniterAgentToolset.create();
|
|
2249
|
+
for (const tool of this.tools.values()) {
|
|
2250
|
+
toolset.addTool(tool);
|
|
2251
|
+
}
|
|
2252
|
+
return toolset.build();
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// Usage
|
|
2257
|
+
const registry = new DynamicToolRegistry()
|
|
2258
|
+
.registerTool("user_lookup", {
|
|
2259
|
+
schema: z.object({ userId: z.string() }),
|
|
2260
|
+
handler: async ({ userId }) =>
|
|
2261
|
+
await db.users.findUnique({ where: { id: userId } }),
|
|
2262
|
+
})
|
|
2263
|
+
.registerTool("order_create", {
|
|
2264
|
+
schema: z.object({ userId: z.string(), items: z.array(z.string()) }),
|
|
2265
|
+
handler: async ({ userId, items }) => await createOrder(userId, items),
|
|
2266
|
+
});
|
|
2267
|
+
|
|
2268
|
+
const agent = IgniterAgent.create("dynamic-agent")
|
|
2269
|
+
.withToolset(registry.buildToolset())
|
|
2270
|
+
.build();
|
|
2271
|
+
```
|
|
2272
|
+
|
|
2273
|
+
#### Environment-Specific Configuration
|
|
2274
|
+
|
|
2275
|
+
Different configurations for development, staging, and production:
|
|
2276
|
+
|
|
2277
|
+
```typescript
|
|
2278
|
+
import {
|
|
2279
|
+
IgniterAgentManager,
|
|
2280
|
+
MemoryAdapter,
|
|
2281
|
+
IgniterAgentMCPClient,
|
|
2282
|
+
} from "@igniter-js/agents";
|
|
2283
|
+
|
|
2284
|
+
function createAgentManager(env: "development" | "staging" | "production") {
|
|
2285
|
+
const baseConfig = IgniterAgentManager.create()
|
|
2286
|
+
.withLogger(logger)
|
|
2287
|
+
.withTelemetry(telemetry);
|
|
2288
|
+
|
|
2289
|
+
switch (env) {
|
|
2290
|
+
case "development":
|
|
2291
|
+
return baseConfig
|
|
2292
|
+
.withMemory(MemoryAdapter.create()) // Simple in-memory for dev
|
|
2293
|
+
.addAgent(createDevAgent())
|
|
2294
|
+
.build();
|
|
2295
|
+
|
|
2296
|
+
case "staging":
|
|
2297
|
+
return baseConfig
|
|
2298
|
+
.withMemory(createRedisAdapter()) // Redis for staging
|
|
2299
|
+
.addAgent(createStagingAgent())
|
|
2300
|
+
.addAgent(createMonitoringAgent())
|
|
2301
|
+
.build();
|
|
2302
|
+
|
|
2303
|
+
case "production":
|
|
2304
|
+
return baseConfig
|
|
2305
|
+
.withMemory(createRedisClusterAdapter()) // Redis cluster for prod
|
|
2306
|
+
.addAgent(createProdAgent())
|
|
2307
|
+
.addAgent(createMonitoringAgent())
|
|
2308
|
+
.addAgent(createAnalyticsAgent())
|
|
2309
|
+
.build();
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
// Environment-specific agent creation
|
|
2314
|
+
function createProdAgent() {
|
|
2315
|
+
const myAppMCPClient = IgniterAgentMCPClient.create()
|
|
2316
|
+
.withServerUrl(process.env.MCP_SERVER_URL!)
|
|
2317
|
+
.withToolFilter(["include", ["prod.*"]]) // Only production tools
|
|
2318
|
+
.build(),
|
|
2319
|
+
|
|
2320
|
+
return IgniterAgent.create("production-agent")
|
|
2321
|
+
.withToolset(productionToolset)
|
|
2322
|
+
.withMCPClient(myAppMCPClient)
|
|
2323
|
+
.withSystemPrompt("Production-ready agent with full MCP integration.")
|
|
2324
|
+
.build();
|
|
2325
|
+
}
|
|
2326
|
+
```
|
|
2327
|
+
|
|
2328
|
+
#### Agent Communication Patterns
|
|
2329
|
+
|
|
2330
|
+
Implementing inter-agent communication:
|
|
2331
|
+
|
|
2332
|
+
```typescript
|
|
2333
|
+
import { IgniterAgentManager, IgniterAgentToolset } from "@igniter-js/agents";
|
|
2334
|
+
|
|
2335
|
+
// Create communication tools
|
|
2336
|
+
const communicationTools = IgniterAgentToolset.create()
|
|
2337
|
+
.addTool(
|
|
2338
|
+
IgniterAgentTool.create()
|
|
2339
|
+
.withName("send_message")
|
|
2340
|
+
.withInput(
|
|
2341
|
+
z.object({
|
|
2342
|
+
targetAgent: z.string(),
|
|
2343
|
+
message: z.string(),
|
|
2344
|
+
priority: z.enum(["low", "normal", "high"]).optional(),
|
|
2345
|
+
}),
|
|
2346
|
+
)
|
|
2347
|
+
.withExecute(async ({ targetAgent, message, priority }, context) => {
|
|
2348
|
+
// Send message to another agent via manager
|
|
2349
|
+
const manager = context.manager;
|
|
2350
|
+
|
|
2351
|
+
const targetAgentInstance = manager.get(targetAgent);
|
|
2352
|
+
|
|
2353
|
+
if (!targetAgentInstance) {
|
|
2354
|
+
throw new Error(`Agent ${targetAgent} not found`);
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
// Queue message for target agent
|
|
2358
|
+
await manager.memory.store(`messages:${targetAgent}`, {
|
|
2359
|
+
from: context.agentName,
|
|
2360
|
+
message,
|
|
2361
|
+
priority,
|
|
2362
|
+
timestamp: Date.now(),
|
|
2363
|
+
});
|
|
2364
|
+
|
|
2365
|
+
return { delivered: true };
|
|
2366
|
+
})
|
|
2367
|
+
.build(),
|
|
2368
|
+
)
|
|
2369
|
+
.build();
|
|
2370
|
+
|
|
2371
|
+
// Create communicating agents
|
|
2372
|
+
const manager = IgniterAgentManager.create()
|
|
2373
|
+
.addAgent(
|
|
2374
|
+
IgniterAgent.create("agent-a")
|
|
2375
|
+
.withToolset(communicationTools)
|
|
2376
|
+
.withSystemPrompt("Agent A can communicate with other agents.")
|
|
2377
|
+
.build(),
|
|
2378
|
+
)
|
|
2379
|
+
.addAgent(
|
|
2380
|
+
IgniterAgent.create("agent-b")
|
|
2381
|
+
.withToolset(communicationTools)
|
|
2382
|
+
.withSystemPrompt("Agent B can receive and respond to messages.")
|
|
2383
|
+
.build(),
|
|
2384
|
+
)
|
|
2385
|
+
.build();
|
|
2386
|
+
|
|
2387
|
+
// Agents can now communicate with each other
|
|
2388
|
+
await manager.get("agent-a").generate({
|
|
2389
|
+
messages: [{ role: 'user', content: 'send message to Bob: hello!' }]
|
|
2390
|
+
});
|
|
2391
|
+
const response = await manager
|
|
2392
|
+
.get("agent-b")
|
|
2393
|
+
.generate({
|
|
2394
|
+
messages: [{ role: 'user', content: 'check for new messages' }]
|
|
2395
|
+
});
|
|
2396
|
+
```
|
|
2397
|
+
|
|
2398
|
+
### 17. Performance Optimization
|
|
2399
|
+
|
|
2400
|
+
#### Memory Management
|
|
2401
|
+
|
|
2402
|
+
Optimizing memory usage for high-throughput agents:
|
|
2403
|
+
|
|
2404
|
+
```typescript
|
|
2405
|
+
import { IgniterAgent, MemoryAdapter } from "@igniter-js/agents";
|
|
2406
|
+
|
|
2407
|
+
// Configure memory with TTL and size limits
|
|
2408
|
+
const optimizedMemory = MemoryAdapter.create({
|
|
2409
|
+
maxSize: 1000, // Maximum number of conversation entries
|
|
2410
|
+
ttl: 24 * 60 * 60 * 1000, // 24 hours TTL
|
|
2411
|
+
cleanupInterval: 60 * 60 * 1000, // Cleanup every hour
|
|
2412
|
+
});
|
|
2413
|
+
|
|
2414
|
+
const agent = IgniterAgent.create("optimized-agent")
|
|
2415
|
+
.withMemory(optimizedMemory)
|
|
2416
|
+
.withSystemPrompt("High-performance agent with optimized memory.")
|
|
2417
|
+
.build();
|
|
2418
|
+
|
|
2419
|
+
// Manual memory cleanup
|
|
2420
|
+
await agent.memory.clearExpired();
|
|
2421
|
+
await agent.memory.optimize(); // Remove duplicate/old entries
|
|
2422
|
+
```
|
|
2423
|
+
|
|
2424
|
+
#### Tool Execution Optimization
|
|
2425
|
+
|
|
2426
|
+
Caching expensive tool results:
|
|
2427
|
+
|
|
2428
|
+
```typescript
|
|
2429
|
+
import { IgniterAgentTool } from "@igniter-js/agents";
|
|
2430
|
+
|
|
2431
|
+
const cachedTool = IgniterAgentTool.create("expensive_calculation")
|
|
2432
|
+
.withDescription("Performs expensive calculation with caching")
|
|
2433
|
+
.withInput(z.object({ input: z.string() }))
|
|
2434
|
+
.withExecute(async ({ input }, context) => {
|
|
2435
|
+
const cacheKey = `calc:${input}`;
|
|
2436
|
+
|
|
2437
|
+
// Check memory cache first
|
|
2438
|
+
const cached = await context.memory.retrieve(cacheKey);
|
|
2439
|
+
if (cached && Date.now() - cached.timestamp < 3600000) {
|
|
2440
|
+
// 1 hour
|
|
2441
|
+
return cached.result;
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
// Perform expensive calculation
|
|
2445
|
+
const result = await performExpensiveCalculation(input);
|
|
2446
|
+
|
|
2447
|
+
// Cache result
|
|
2448
|
+
await context.memory.store(cacheKey, {
|
|
2449
|
+
result,
|
|
2450
|
+
timestamp: Date.now(),
|
|
2451
|
+
});
|
|
2452
|
+
|
|
2453
|
+
return result;
|
|
2454
|
+
})
|
|
2455
|
+
.build();
|
|
2456
|
+
```
|
|
2457
|
+
|
|
2458
|
+
#### Agent Pool Management
|
|
2459
|
+
|
|
2460
|
+
Managing multiple agent instances for load balancing:
|
|
2461
|
+
|
|
2462
|
+
```typescript
|
|
2463
|
+
class AgentPool {
|
|
2464
|
+
private agents: IgniterAgentCore[] = [];
|
|
2465
|
+
private currentIndex = 0;
|
|
2466
|
+
|
|
2467
|
+
constructor(
|
|
2468
|
+
private manager: IgniterAgentManagerCore,
|
|
2469
|
+
agentName: string,
|
|
2470
|
+
poolSize: number,
|
|
2471
|
+
) {
|
|
2472
|
+
for (let i = 0; i < poolSize; i++) {
|
|
2473
|
+
this.agents.push(manager.getAgent(`${aget}-${i}`));
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
async run(input: string, context?: any): Promise<any> {
|
|
2478
|
+
// Round-robin load balancing
|
|
2479
|
+
const agent = this.agents[this.currentIndex];
|
|
2480
|
+
this.currentIndex = (this.currentIndex + 1) % this.agents.length;
|
|
2481
|
+
|
|
2482
|
+
return agent.generate({
|
|
2483
|
+
messages: [{ role: 'user', content: input }],
|
|
2484
|
+
options: context
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
async getStats() {
|
|
2489
|
+
const stats = await Promise.all(
|
|
2490
|
+
this.agents.map(async (agent, index) => ({
|
|
2491
|
+
id: index,
|
|
2492
|
+
status: await agent.getStatus(),
|
|
2493
|
+
memoryUsage: await agent.memory.getStats(),
|
|
2494
|
+
})),
|
|
2495
|
+
);
|
|
2496
|
+
|
|
2497
|
+
return stats;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
// Usage
|
|
2502
|
+
const agentPool = new AgentPool(manager, "worker", 5);
|
|
2503
|
+
const result = await agentPool.run("process this task");
|
|
2504
|
+
```
|
|
2505
|
+
|
|
2506
|
+
### 18. Security Considerations
|
|
2507
|
+
|
|
2508
|
+
#### Input Validation and Sanitization
|
|
2509
|
+
|
|
2510
|
+
Implementing comprehensive input validation:
|
|
2511
|
+
|
|
2512
|
+
```typescript
|
|
2513
|
+
import { IgniterAgentTool } from "@igniter-js/agents";
|
|
2514
|
+
|
|
2515
|
+
// Secure tool with input sanitization
|
|
2516
|
+
const secureTool = IgniterAgentTool.create()
|
|
2517
|
+
.withName("user_profile_update")
|
|
2518
|
+
.withInput(
|
|
2519
|
+
z.object({
|
|
2520
|
+
userId: z.string().uuid("Invalid user ID format"),
|
|
2521
|
+
email: z
|
|
2522
|
+
.string()
|
|
2523
|
+
.email("Invalid email format")
|
|
2524
|
+
.max(254, "Email too long"),
|
|
2525
|
+
name: z
|
|
2526
|
+
.string()
|
|
2527
|
+
.min(1, "Name required")
|
|
2528
|
+
.max(100, "Name too long")
|
|
2529
|
+
.regex(/^[a-zA-Z\s'-]+$/, "Name contains invalid characters"),
|
|
2530
|
+
bio: z.string().max(500, "Bio too long").optional(),
|
|
2531
|
+
}),
|
|
2532
|
+
)
|
|
2533
|
+
.withExecute(async ({ userId, email, name, bio }, context) => {
|
|
2534
|
+
// Additional runtime validation
|
|
2535
|
+
if (context.userId !== userId && !context.permissions.includes("admin")) {
|
|
2536
|
+
throw new Error("Cannot update other users' profiles");
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
// Sanitize HTML in bio
|
|
2540
|
+
const sanitizedBio = bio ? sanitizeHtml(bio) : undefined;
|
|
2541
|
+
|
|
2542
|
+
// Update user with validated data
|
|
2543
|
+
return await updateUserProfile(userId, {
|
|
2544
|
+
email: email.toLowerCase().trim(),
|
|
2545
|
+
name: name.trim(),
|
|
2546
|
+
bio: sanitizedBio,
|
|
2547
|
+
});
|
|
2548
|
+
})
|
|
2549
|
+
.build();
|
|
2550
|
+
```
|
|
2551
|
+
|
|
2552
|
+
#### Authentication and Authorization
|
|
2553
|
+
|
|
2554
|
+
Implementing secure agent access controls:
|
|
2555
|
+
|
|
2556
|
+
```typescript
|
|
2557
|
+
import { IgniterAgent, IgniterAgentToolset } from "@igniter-js/agents";
|
|
2558
|
+
|
|
2559
|
+
// Authentication middleware tool
|
|
2560
|
+
const authTool = IgniterAgentTool.create()
|
|
2561
|
+
.withName("authenticate")
|
|
2562
|
+
.withInput(z.object({ token: z.string() }))
|
|
2563
|
+
.withExecute(async ({ token }, context) => {
|
|
2564
|
+
try {
|
|
2565
|
+
const payload = verifyJWT(token);
|
|
2566
|
+
context.userId = payload.userId;
|
|
2567
|
+
context.permissions = payload.permissions;
|
|
2568
|
+
context.authenticated = true;
|
|
2569
|
+
return { authenticated: true, userId: payload.userId };
|
|
2570
|
+
} catch (error) {
|
|
2571
|
+
throw new Error("Invalid authentication token");
|
|
2572
|
+
}
|
|
2573
|
+
})
|
|
2574
|
+
.build();
|
|
2575
|
+
|
|
2576
|
+
// Authorized agent
|
|
2577
|
+
const secureAgent = IgniterAgent.create("secure-agent")
|
|
2578
|
+
.withToolset(
|
|
2579
|
+
IgniterAgentToolset.create()
|
|
2580
|
+
.addTool(authTool)
|
|
2581
|
+
.addTool(secureTool) // Requires authentication
|
|
2582
|
+
.build(),
|
|
2583
|
+
)
|
|
2584
|
+
.withSystemPrompt(
|
|
2585
|
+
`
|
|
2586
|
+
You are a secure agent that requires authentication.
|
|
2587
|
+
Always authenticate users before performing sensitive operations.
|
|
2588
|
+
`,
|
|
2589
|
+
)
|
|
2590
|
+
.onAgentStart(async (input, context) => {
|
|
2591
|
+
// Require authentication for all interactions
|
|
2592
|
+
if (!context.authenticated) {
|
|
2593
|
+
await context.agent.generate({
|
|
2594
|
+
messages: [{ role: 'user', content: 'authenticate with provided token first' }]
|
|
2595
|
+
});
|
|
2596
|
+
throw new Error("Authentication required");
|
|
2597
|
+
}
|
|
2598
|
+
})
|
|
2599
|
+
.build();
|
|
2600
|
+
```
|
|
2601
|
+
|
|
2602
|
+
#### Rate Limiting and Abuse Prevention
|
|
2603
|
+
|
|
2604
|
+
Implementing rate limiting for agent interactions:
|
|
2605
|
+
|
|
2606
|
+
```typescript
|
|
2607
|
+
import { IgniterAgent } from "@igniter-js/agents";
|
|
2608
|
+
|
|
2609
|
+
class RateLimiter {
|
|
2610
|
+
private requests = new Map<string, number[]>();
|
|
2611
|
+
|
|
2612
|
+
checkLimit(userId: string, maxRequests: number, windowMs: number): boolean {
|
|
2613
|
+
const now = Date.now();
|
|
2614
|
+
const userRequests = this.requests.get(userId) || [];
|
|
2615
|
+
|
|
2616
|
+
// Remove old requests outside the window
|
|
2617
|
+
const validRequests = userRequests.filter((time) => now - time < windowMs);
|
|
2618
|
+
this.requests.set(userId, validRequests);
|
|
2619
|
+
|
|
2620
|
+
if (validRequests.length >= maxRequests) {
|
|
2621
|
+
return false; // Rate limit exceeded
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
validRequests.push(now);
|
|
2625
|
+
return true;
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
const rateLimiter = new RateLimiter();
|
|
2630
|
+
|
|
2631
|
+
const rateLimitedAgent = IgniterAgent.create("rate-limited-agent")
|
|
2632
|
+
.onAgentStart(async (input, context) => {
|
|
2633
|
+
const allowed = rateLimiter.checkLimit(
|
|
2634
|
+
context.userId,
|
|
2635
|
+
10, // 10 requests
|
|
2636
|
+
60000, // per minute
|
|
2637
|
+
);
|
|
2638
|
+
|
|
2639
|
+
if (!allowed) {
|
|
2640
|
+
throw new Error("Rate limit exceeded. Please try again later.");
|
|
2641
|
+
}
|
|
2642
|
+
})
|
|
2643
|
+
.build();
|
|
2644
|
+
```
|
|
2645
|
+
|
|
2646
|
+
### 19. API Reference (Complete)
|
|
2647
|
+
|
|
2648
|
+
#### IgniterAgentManager
|
|
2649
|
+
|
|
2650
|
+
| Method | Signature | Description |
|
|
2651
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------- |
|
|
2652
|
+
| `create()` | `static create(): IgniterAgentManagerBuilder<{}>` | Create manager builder |
|
|
2653
|
+
| `addAgent()` | `(name: string, agent: IgniterAgentBuiltAgent) => IgniterAgentManagerBuilder` | Add agent to manager with name |
|
|
2654
|
+
| `withLogger()` | `(logger: IgniterLogger) => IgniterAgentManagerBuilder` | Set logger |
|
|
2655
|
+
| `withTelemetry()` | `(telemetry: IgniterTelemetryManager) => IgniterAgentManagerBuilder` | Set telemetry |
|
|
2656
|
+
| `withAutoStart()` | `(autoStart: boolean) => IgniterAgentManagerBuilder` | Enable/disable auto-start |
|
|
2657
|
+
| `withContinueOnError()`| `(continueOnError: boolean) => IgniterAgentManagerBuilder` | Continue on agent errors |
|
|
2658
|
+
| `onAgentStart()` | `(callback: IgniterAgentHooks["onAgentStart"]) => IgniterAgentManagerBuilder` | Add agent start hook |
|
|
2659
|
+
| `onAgentError()` | `(callback: IgniterAgentHooks["onAgentError"]) => IgniterAgentManagerBuilder` | Add agent error hook |
|
|
2660
|
+
| `onToolCallStart()` | `(callback: (agentName, toolName, input) => void) => IgniterAgentManagerBuilder` | Add tool call start hook |
|
|
2661
|
+
| `onToolCallEnd()` | `(callback: (agentName, toolName, output) => void) => IgniterAgentManagerBuilder` | Add tool call end hook |
|
|
2662
|
+
| `onToolCallError()` | `(callback: (agentName, toolName, error) => void) => IgniterAgentManagerBuilder` | Add tool call error hook |
|
|
2663
|
+
| `onMCPStart()` | `(callback: (agentName, mcpName) => void) => IgniterAgentManagerBuilder` | Add MCP start hook |
|
|
2664
|
+
| `onMCPError()` | `(callback: (agentName, mcpName, error) => void) => IgniterAgentManagerBuilder` | Add MCP error hook |
|
|
2665
|
+
| `build()` | `() => IgniterAgentManagerCore<TAgentRegistry>` | Build manager instance |
|
|
2666
|
+
|
|
2667
|
+
#### IgniterAgentManagerCore
|
|
2668
|
+
|
|
2669
|
+
| Method | Signature | Description |
|
|
2670
|
+
| ------------------- | ------------------------------------------------------------------------------ | ---------------------------------------- |
|
|
2671
|
+
| `create()` | `static create(): IgniterAgentManagerCore` | Create manager with default options |
|
|
2672
|
+
| `register()` | `(name: string, agent: IgniterAgentBuiltAgent) => this` | Register an agent with the manager |
|
|
2673
|
+
| `unregister()` | `(name: string) => boolean` | Unregister an agent from the manager |
|
|
2674
|
+
| `has()` | `(name: string) => boolean` | Check if an agent is registered |
|
|
2675
|
+
| `start()` | `(name: string) => Promise<IgniterAgentBuiltAgent>` | Start a specific agent |
|
|
2676
|
+
| `startAll()` | `() => Promise<Map<string, Record<string, IgniterAgentToolset> \| Error>>` | Start all registered agents |
|
|
2677
|
+
| `get()` | `<TName extends string>(name: TName) => TAgentRegistry[TName]` | Get agent by name (throws if not found) |
|
|
2678
|
+
| `tryGet()` | `<TName extends string>(name: TName) => TAgentRegistry[TName] \| undefined` | Get agent if exists, undefined otherwise |
|
|
2679
|
+
| `getNames()` | `() => string[]` | Get all registered agent names |
|
|
2680
|
+
| `size` | `number` | Get the number of registered agents |
|
|
2681
|
+
| `getInfo()` | `(name: string) => IgniterAgentInfo \| undefined` | Get information about a specific agent |
|
|
2682
|
+
| `getStatus()` | `() => IgniterAgentInfo[]` | Get status information for all agents |
|
|
2683
|
+
| `isAllRunning()` | `() => boolean` | Check if all agents are running |
|
|
2684
|
+
| `getFailedAgents()` | `() => IgniterAgentInfo[]` | Get agents that are in error state |
|
|
2685
|
+
|
|
2686
|
+
#### IgniterAgent
|
|
2687
|
+
|
|
2688
|
+
| Method | Signature | Description |
|
|
2689
|
+
| ---------------------- | ------------------------------------------------------------- | --------------------------- |
|
|
2690
|
+
| `create()` | `(name: string) => IgniterAgentBuilder` | Create agent builder |
|
|
2691
|
+
| `withSystemPrompt()` | `(prompt: string) => IgniterAgentBuilder` | Set system prompt |
|
|
2692
|
+
| `withTool()` | `(tool: IgniterAgentTool) => IgniterAgentBuilder` | Add single tool |
|
|
2693
|
+
| `withToolset()` | `(toolset: IgniterAgentToolset) => IgniterAgentBuilder` | Add toolset |
|
|
2694
|
+
| `withMemory()` | `(memory: IgniterAgentMemory) => IgniterAgentBuilder` | Set memory |
|
|
2695
|
+
| `withMCPClient()` | `(client: IgniterAgentMCPClient) => IgniterAgentBuilder` | Set MCP client |
|
|
2696
|
+
| `withLogger()` | `(logger: IgniterLogger) => IgniterAgentBuilder` | Set logger |
|
|
2697
|
+
| `withTelemetry()` | `(telemetry: IgniterTelemetryManager) => IgniterAgentBuilder` | Set telemetry |
|
|
2698
|
+
| `onAgentStart()` | `(hook: AgentHook) => IgniterAgentBuilder` | Add start hook |
|
|
2699
|
+
| `onAgentComplete()` | `(hook: AgentHook) => IgniterAgentBuilder` | Add complete hook |
|
|
2700
|
+
| `onAgentError()` | `(hook: AgentHook) => IgniterAgentBuilder` | Add error hook |
|
|
2701
|
+
| `onToolCallStart()` | `(hook: ToolHook) => IgniterAgentBuilder` | Add tool call start hook |
|
|
2702
|
+
| `onToolCallEnd()` | `(hook: ToolHook) => IgniterAgentBuilder` | Add tool call complete hook |
|
|
2703
|
+
| `build()` | `() => IgniterAgentCore` | Build agent instance |
|
|
2704
|
+
|
|
2705
|
+
#### IgniterAgentCore
|
|
2706
|
+
|
|
2707
|
+
| Method | Signature | Description |
|
|
2708
|
+
| ------------------- | -------------------------------------------------------------------------- | ---------------------------------- |
|
|
2709
|
+
| `start()` | `() => Promise<void>` | Start agent and initialize MCP |
|
|
2710
|
+
| `stop()` | `() => Promise<void>` | Stop agent and disconnect MCP |
|
|
2711
|
+
| `generate()` | `(input: AgentCallParameters<TContext>) => Promise<any>` | Generate a response from the agent |
|
|
2712
|
+
| `stream()` | `(input: AgentStreamParameters<TContext, ToolSet>) => Promise<any>` | Stream a response from the agent |
|
|
2713
|
+
| `getName()` | `() => string` | Get the agent name |
|
|
2714
|
+
| `getToolsets()` | `() => TAgentToolsets` | Get all registered toolsets |
|
|
2715
|
+
| `getTools()` | `() => ToolSet` | Get all tools from all toolsets |
|
|
2716
|
+
| `getModel()` | `() => TAgentModel` | Get the configured model |
|
|
2717
|
+
| `getInstructions()` | `() => TAgentInstructions` | Get the configured instructions |
|
|
2718
|
+
| `getContextSchema()`| `() => TAgentContextSchema` | Get the context schema |
|
|
2719
|
+
| `attachLogger()` | `(logger?: IgniterLogger) => void` | Attach a logger instance |
|
|
2720
|
+
| `attachTelemetry()` | `(telemetry?: IgniterTelemetryManager) => void` | Attach a telemetry manager |
|
|
2721
|
+
| `attachHooks()` | `(hooks?: IgniterAgentHooks) => void` | Attach hook callbacks |
|
|
2722
|
+
| `memory` | `IgniterAgentMemoryCore \| undefined` | Memory instance (if configured) |
|
|
2723
|
+
|
|
2724
|
+
#### IgniterAgentTool
|
|
2725
|
+
|
|
2726
|
+
| Method | Signature | Description |
|
|
2727
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------ | ----------------------------- |
|
|
2728
|
+
| `create()` | `(name: string) => IgniterAgentToolBuilder` | Create tool builder with name |
|
|
2729
|
+
| `withDescription()` | `(description: string) => IgniterAgentToolBuilder` | Set description |
|
|
2730
|
+
| `withInput()` | `<TNewParams>(inputSchema: z.ZodSchema<TNewParams>) => IgniterAgentToolBuilder` | Set input schema |
|
|
2731
|
+
| `withOutput()` | `<TNewResult>(outputSchema: z.ZodSchema<TNewResult>) => IgniterAgentToolBuilder` | Set output schema |
|
|
2732
|
+
| `withExecute()` | `<TNewExecute>(execute: (params, options: IgniterAgentToolExecuteOptions) => Promise<T>) => IgniterAgentToolBuilder` | Set handler function |
|
|
2733
|
+
| `build()` | `() => IgniterAgentBuiltTool` | Build tool instance |
|
|
2734
|
+
|
|
2735
|
+
#### IgniterAgentToolset
|
|
2736
|
+
|
|
2737
|
+
| Method | Signature | Description |
|
|
2738
|
+
| ---------------- | -------------------------------------------------------- | -------------------------------- |
|
|
2739
|
+
| `create()` | `(name: string) => IgniterAgentToolsetBuilder` | Create toolset builder with name |
|
|
2740
|
+
| `withName()` | `(name: string) => IgniterAgentToolsetBuilder` | Change toolset name |
|
|
2741
|
+
| `addTool()` | `(tool: IgniterAgentTool) => IgniterAgentToolsetBuilder` | Add tool |
|
|
2742
|
+
| `getName()` | `() => string` | Get toolset name |
|
|
2743
|
+
| `getTools()` | `() => Tool[]` | Get all tools |
|
|
2744
|
+
| `getToolCount()` | `() => number` | Get tool count |
|
|
2745
|
+
| `build()` | `() => IgniterAgentToolset` | Build toolset instance |
|
|
2746
|
+
|
|
2747
|
+
#### IgniterAgentMCPClient
|
|
2748
|
+
|
|
2749
|
+
| Method | Signature | Description |
|
|
2750
|
+
| --------------- | ------------------------------------------------------------------- | ------------------------------------------------ |
|
|
2751
|
+
| `create()` | `(name: string) => IgniterAgentMCPBuilder` | Create MCP builder with name |
|
|
2752
|
+
| `withName()` | `(name: string) => IgniterAgentMCPBuilder` | Change configuration name |
|
|
2753
|
+
| `withType()` | `(type: 'stdio' \| 'http') => IgniterAgentMCPBuilder` | Set transport type (required before other opts) |
|
|
2754
|
+
| `withCommand()` | `(command: string) => IgniterAgentMCPBuilder` | Set command (stdio only) |
|
|
2755
|
+
| `withArgs()` | `(args: string[]) => IgniterAgentMCPBuilder` | Set args (stdio only) |
|
|
2756
|
+
| `withEnv()` | `(env: Record<string, string>) => IgniterAgentMCPBuilder` | Set env vars (stdio only) |
|
|
2757
|
+
| `withURL()` | `(url: string) => IgniterAgentMCPBuilder` | Set URL (http only) |
|
|
2758
|
+
| `withHeaders()` | `(headers: Record<string, string>) => IgniterAgentMCPBuilder` | Set headers (http only) |
|
|
2759
|
+
| `build()` | `() => IgniterAgentMCPStdioConfig \| IgniterAgentMCPHttpConfig` | Build MCP configuration |
|
|
2760
|
+
|
|
2761
|
+
### 20. Implementation Examples
|
|
2762
|
+
|
|
2763
|
+
#### Complete E-commerce Agent System
|
|
2764
|
+
|
|
2765
|
+
```typescript
|
|
2766
|
+
import {
|
|
2767
|
+
IgniterAgentManager,
|
|
2768
|
+
IgniterAgent,
|
|
2769
|
+
IgniterAgentToolset,
|
|
2770
|
+
IgniterAgentTool,
|
|
2771
|
+
MemoryAdapter,
|
|
2772
|
+
} from "@igniter-js/agents";
|
|
2773
|
+
import { z } from "zod";
|
|
2774
|
+
|
|
2775
|
+
// Order management tools
|
|
2776
|
+
const orderTools = IgniterAgentToolset.create('order')
|
|
2777
|
+
.addTool(
|
|
2778
|
+
IgniterAgentTool.create("create")
|
|
2779
|
+
.withInput(
|
|
2780
|
+
z.object({
|
|
2781
|
+
customerId: z.string(),
|
|
2782
|
+
items: z.array(
|
|
2783
|
+
z.object({
|
|
2784
|
+
productId: z.string(),
|
|
2785
|
+
quantity: z.number().min(1),
|
|
2786
|
+
}),
|
|
2787
|
+
),
|
|
2788
|
+
}),
|
|
2789
|
+
)
|
|
2790
|
+
.withExecute(async ({ customerId, items }) => {
|
|
2791
|
+
const order = await db.orders.create({
|
|
2792
|
+
data: { customerId, items, status: "pending" },
|
|
2793
|
+
});
|
|
2794
|
+
return { orderId: order.id, total: calculateTotal(items) };
|
|
2795
|
+
})
|
|
2796
|
+
.build(),
|
|
2797
|
+
)
|
|
2798
|
+
.addTool(
|
|
2799
|
+
IgniterAgentTool.create("get_status")
|
|
2800
|
+
.withInput(z.object({ orderId: z.string() }))
|
|
2801
|
+
.withExecute(async ({ orderId }) => {
|
|
2802
|
+
const order = await db.orders.findUnique({ where: { id: orderId } });
|
|
2803
|
+
return order
|
|
2804
|
+
? { status: order.status, updatedAt: order.updatedAt }
|
|
2805
|
+
: null;
|
|
2806
|
+
})
|
|
2807
|
+
.build(),
|
|
2808
|
+
)
|
|
2809
|
+
.build();
|
|
2810
|
+
|
|
2811
|
+
// Customer service agent
|
|
2812
|
+
const customerServiceAgent = IgniterAgent.create("customer-service")
|
|
2813
|
+
.withToolset(orderTools)
|
|
2814
|
+
.withMemory(MemoryAdapter.create())
|
|
2815
|
+
.withSystemPrompt(
|
|
2816
|
+
`
|
|
2817
|
+
You are a helpful customer service agent for our e-commerce platform.
|
|
2818
|
+
You can help customers with order creation, status checking, and general inquiries.
|
|
2819
|
+
Always be polite and provide accurate information.
|
|
2820
|
+
`,
|
|
2821
|
+
)
|
|
2822
|
+
.build();
|
|
2823
|
+
|
|
2824
|
+
// Inventory management agent
|
|
2825
|
+
const inventoryAgent = IgniterAgent.create("inventory")
|
|
2826
|
+
.withToolset(
|
|
2827
|
+
IgniterAgentToolset.create()
|
|
2828
|
+
.addTool(
|
|
2829
|
+
IgniterAgentTool.create("check_stock")
|
|
2830
|
+
.withInput(z.object({ productId: z.string() }))
|
|
2831
|
+
.withExecute(async ({ productId }) => {
|
|
2832
|
+
const product = await db.products.findUnique({
|
|
2833
|
+
where: { id: productId },
|
|
2834
|
+
});
|
|
2835
|
+
|
|
2836
|
+
return product
|
|
2837
|
+
? { inStock: product.stock > 0, quantity: product.stock }
|
|
2838
|
+
: null;
|
|
2839
|
+
})
|
|
2840
|
+
.build(),
|
|
2841
|
+
)
|
|
2842
|
+
.build(),
|
|
2843
|
+
)
|
|
2844
|
+
.withSystemPrompt("You manage inventory and stock levels.")
|
|
2845
|
+
.build();
|
|
2846
|
+
|
|
2847
|
+
// Manager orchestration
|
|
2848
|
+
const agentManager = IgniterAgentManager.create()
|
|
2849
|
+
.withMemory(MemoryAdapter.create())
|
|
2850
|
+
.addAgent(customerServiceAgent)
|
|
2851
|
+
.addAgent(inventoryAgent)
|
|
2852
|
+
.build();
|
|
2853
|
+
|
|
2854
|
+
// Usage
|
|
2855
|
+
await agentManager.startAll();
|
|
2856
|
+
|
|
2857
|
+
// Route customer queries
|
|
2858
|
+
const customerQuery = "I want to check the status of my order #12345";
|
|
2859
|
+
const response = await agentManager
|
|
2860
|
+
.get("customer-service")
|
|
2861
|
+
.generate({ prompt: customerQuery });
|
|
2862
|
+
|
|
2863
|
+
const inventoryQuery = "How many units of product ABC123 are in stock?";
|
|
2864
|
+
const inventoryResponse = await agentManager
|
|
2865
|
+
.get("inventory")
|
|
2866
|
+
.generate({ prompt: customerQuery });
|
|
2867
|
+
```
|
|
2868
|
+
|
|
2869
|
+
#### Advanced MCP Integration
|
|
2870
|
+
|
|
2871
|
+
```typescript
|
|
2872
|
+
import { IgniterAgent, IgniterAgentMCPClient } from "@igniter-js/agents";
|
|
2873
|
+
|
|
2874
|
+
// Agent with full MCP integration
|
|
2875
|
+
const mcpAgent = IgniterAgent.create("mcp-integrated")
|
|
2876
|
+
.withMCPClient(
|
|
2877
|
+
IgniterAgentMCPClient.create()
|
|
2878
|
+
.withServerUrl("http://localhost:3000/mcp")
|
|
2879
|
+
.withToolFilter([
|
|
2880
|
+
"include",
|
|
2881
|
+
["database.query", "filesystem.read", "api.request", "git.status"],
|
|
2882
|
+
])
|
|
2883
|
+
.withCredentials({
|
|
2884
|
+
username: process.env.MCP_USERNAME,
|
|
2885
|
+
password: process.env.MCP_PASSWORD,
|
|
2886
|
+
})
|
|
2887
|
+
.build(),
|
|
2888
|
+
)
|
|
2889
|
+
.withSystemPrompt(
|
|
2890
|
+
`
|
|
2891
|
+
You are an AI agent with access to various tools through MCP.
|
|
2892
|
+
You can query databases, read files, make API calls, and check git status.
|
|
2893
|
+
Use these tools to help users accomplish their tasks.
|
|
2894
|
+
`,
|
|
2895
|
+
)
|
|
2896
|
+
.build();
|
|
2897
|
+
|
|
2898
|
+
// The agent can now use MCP tools automatically
|
|
2899
|
+
const result = await mcpAgent.generate({
|
|
2900
|
+
messages: [{
|
|
2901
|
+
role: 'user',
|
|
2902
|
+
content: 'Check the current git status and show me any uncommitted changes'
|
|
2903
|
+
}]
|
|
2904
|
+
});
|
|
2905
|
+
```
|
|
2906
|
+
|
|
2907
|
+
---
|
|
2908
|
+
|
|
2909
|
+
**Note:** This AGENTS.md has been partially updated to reflect the actual API. Some examples may still use deprecated method names (like `withInput` instead of `withInput`). A complete review and update of all examples is recommended.
|
|
2910
|
+
|
|
2911
|
+
**End of AGENTS.md for @igniter-js/agents**
|
|
2912
|
+
|
|
2913
|
+
This comprehensive documentation provides the complete operational manual for maintaining and consuming the @igniter-js/agents package, ensuring full compliance with the standardization guidelines in packages.instructions.md.
|