@jterrazz/intelligence 1.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -83
- package/dist/adapters/agents/{basic-agent.adapter.d.ts → chat-agent.adapter.d.ts} +6 -6
- package/dist/adapters/agents/{basic-agent.adapter.js → chat-agent.adapter.js} +54 -27
- package/dist/adapters/agents/chat-agent.adapter.js.map +1 -0
- package/dist/adapters/agents/{retryable-agent.adapter.d.ts → resilient-agent.adapter.d.ts} +4 -4
- package/dist/adapters/agents/{retryable-agent.adapter.js → resilient-agent.adapter.js} +22 -13
- package/dist/adapters/agents/resilient-agent.adapter.js.map +1 -0
- package/dist/adapters/agents/{autonomous-agent.adapter.d.ts → tool-agent.adapter.d.ts} +6 -6
- package/dist/adapters/agents/{autonomous-agent.adapter.js → tool-agent.adapter.js} +29 -18
- package/dist/adapters/agents/tool-agent.adapter.js.map +1 -0
- package/dist/adapters/models/openrouter-model.adapter.d.ts +17 -32
- package/dist/adapters/models/openrouter-model.adapter.js +84 -25
- package/dist/adapters/models/openrouter-model.adapter.js.map +1 -1
- package/dist/adapters/prompts/__tests__/presets.test.js +4 -4
- package/dist/adapters/prompts/__tests__/presets.test.js.map +1 -1
- package/dist/adapters/prompts/system-prompt.adapter.d.ts +2 -2
- package/dist/adapters/prompts/system-prompt.adapter.js +6 -6
- package/dist/adapters/prompts/system-prompt.adapter.js.map +1 -1
- package/dist/adapters/prompts/user-prompt.adapter.d.ts +2 -2
- package/dist/adapters/prompts/user-prompt.adapter.js +6 -6
- package/dist/adapters/prompts/user-prompt.adapter.js.map +1 -1
- package/dist/adapters/providers/openrouter-provider.adapter.d.ts +34 -0
- package/dist/adapters/providers/openrouter-provider.adapter.js +57 -0
- package/dist/adapters/providers/openrouter-provider.adapter.js.map +1 -0
- package/dist/adapters/tools/safe-tool.adapter.d.ts +2 -2
- package/dist/adapters/tools/safe-tool.adapter.js +6 -6
- package/dist/adapters/tools/safe-tool.adapter.js.map +1 -1
- package/dist/adapters/utils/__tests__/{ai-response-parser.test.js → structured-response-parser.test.js} +30 -30
- package/dist/adapters/utils/__tests__/structured-response-parser.test.js.map +1 -0
- package/dist/adapters/utils/{ai-response-parser-error.d.ts → structured-response-parser-error.d.ts} +2 -2
- package/dist/adapters/utils/{ai-response-parser-error.js → structured-response-parser-error.js} +9 -9
- package/dist/adapters/utils/structured-response-parser-error.js.map +1 -0
- package/dist/adapters/utils/{ai-response-parser.d.ts → structured-response-parser.d.ts} +1 -1
- package/dist/adapters/utils/{ai-response-parser.js → structured-response-parser.js} +13 -13
- package/dist/adapters/utils/structured-response-parser.js.map +1 -0
- package/dist/index.cjs +748 -342
- package/dist/index.d.ts +11 -8
- package/dist/index.js +29 -8
- package/dist/index.js.map +1 -1
- package/dist/ports/model.port.d.ts +30 -3
- package/dist/ports/model.port.js +1 -1
- package/dist/ports/model.port.js.map +1 -1
- package/dist/ports/provider.port.d.ts +13 -0
- package/dist/ports/provider.port.js +5 -0
- package/dist/ports/provider.port.js.map +1 -0
- package/package.json +11 -9
- package/dist/adapters/agents/autonomous-agent.adapter.js.map +0 -1
- package/dist/adapters/agents/basic-agent.adapter.js.map +0 -1
- package/dist/adapters/agents/retryable-agent.adapter.js.map +0 -1
- package/dist/adapters/utils/__tests__/ai-response-parser.test.js.map +0 -1
- package/dist/adapters/utils/ai-response-parser-error.js.map +0 -1
- package/dist/adapters/utils/ai-response-parser.js.map +0 -1
- /package/dist/adapters/utils/__tests__/{ai-response-parser.test.d.ts → structured-response-parser.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/@jterrazz/intelligence)
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
|
|
8
|
-
`@jterrazz/intelligence` provides a clean, structured, and extensible foundation for building sophisticated AI agents.
|
|
8
|
+
`@jterrazz/intelligence` provides a clean, structured, and extensible foundation for building sophisticated AI agents. Built on the **Vercel AI SDK** with **OpenRouter** support, it's designed to help you create reliable and maintainable AI-powered applications by focusing on composability, type safety, and resilience.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -13,10 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
- **Composable Prompts**: Instead of monolithic prompts, the library offers a collection of constants. Mix and match them to build a precise system prompt that defines your agent's behavior, personality, and output format.
|
|
15
15
|
|
|
16
|
-
- **Safe, Typed Tools**: A `
|
|
16
|
+
- **Safe, Typed Tools**: A `SafeTool` provides built-in error handling and Zod-based schema validation for any tool you create. This ensures that tool inputs are valid and that your agent can gracefully handle execution errors.
|
|
17
17
|
|
|
18
18
|
- **Ports & Adapters Architecture**: The library uses a hexagonal architecture to separate core logic from implementation details. This makes it easy to swap out underlying models or services (e.g., switching from OpenAI to Anthropic) without rewriting your application.
|
|
19
19
|
|
|
20
|
+
- **Structured Outputs**: Leverages both prompt-based schema instructions and OpenRouter's official structured outputs for reliable, validated responses.
|
|
21
|
+
|
|
20
22
|
## Installation
|
|
21
23
|
|
|
22
24
|
```bash
|
|
@@ -25,127 +27,140 @@ npm install @jterrazz/intelligence
|
|
|
25
27
|
|
|
26
28
|
---
|
|
27
29
|
|
|
30
|
+
## Agent Types
|
|
31
|
+
|
|
32
|
+
### 🗣️ **ChatAgent**
|
|
33
|
+
|
|
34
|
+
For conversational AI and text generation with optional schema validation. Perfect for chatbots, content generation, and structured data extraction.
|
|
35
|
+
|
|
36
|
+
### 🛡️ **ResilientAgent**
|
|
37
|
+
|
|
38
|
+
A decorator that adds retry logic to any agent for fault-tolerant execution. Wraps other agents to handle transient failures gracefully.
|
|
39
|
+
|
|
40
|
+
### 🔧 **ToolAgent**
|
|
41
|
+
|
|
42
|
+
For complex workflows requiring external tools and function calling. Can reason about when to use tools and provide structured responses.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
28
46
|
## Quick Start
|
|
29
47
|
|
|
30
|
-
Get your first agent running in minutes. This example creates a helpful agent
|
|
48
|
+
Get your first agent running in minutes. This example creates a helpful conversational agent.
|
|
31
49
|
|
|
32
50
|
```typescript
|
|
33
|
-
import {
|
|
34
|
-
AutonomousAgentAdapter,
|
|
35
|
-
OpenRouterAdapter,
|
|
36
|
-
SystemPromptAdapter,
|
|
37
|
-
PROMPT_LIBRARY,
|
|
38
|
-
} from '@jterrazz/intelligence';
|
|
51
|
+
import { ChatAgent, OpenRouterProvider, SystemPrompt, PROMPTS } from '@jterrazz/intelligence';
|
|
39
52
|
|
|
40
53
|
// 1. Set up the model provider
|
|
41
|
-
const
|
|
54
|
+
const provider = new OpenRouterProvider({
|
|
42
55
|
apiKey: process.env.OPENROUTER_API_KEY!, // Make sure to set this environment variable
|
|
43
|
-
modelName: 'anthropic/claude-3.5-sonnet',
|
|
44
56
|
});
|
|
45
57
|
|
|
46
|
-
// 2.
|
|
47
|
-
const
|
|
58
|
+
// 2. Get a model instance
|
|
59
|
+
const model = provider.getModel('anthropic/claude-sonnet-4');
|
|
60
|
+
|
|
61
|
+
// 3. Create a conversational agent
|
|
62
|
+
const agent = new ChatAgent('helpful-assistant', {
|
|
48
63
|
model,
|
|
49
|
-
systemPrompt: new
|
|
64
|
+
systemPrompt: new SystemPrompt(PROMPTS.PRESETS.HELPFUL_ASSISTANT),
|
|
50
65
|
});
|
|
51
66
|
|
|
52
|
-
//
|
|
67
|
+
// 4. Run the agent
|
|
53
68
|
const response = await agent.run();
|
|
54
69
|
|
|
55
70
|
console.log(response);
|
|
56
|
-
// Output
|
|
71
|
+
// Output: "Hello! I'm here to help you with any questions or tasks you might have. What can I assist you with today?"
|
|
57
72
|
```
|
|
58
73
|
|
|
59
74
|
## Creating Domain-Specific Agents
|
|
60
75
|
|
|
61
76
|
The most powerful feature of `@jterrazz/intelligence` is its ability to create specialized, reusable agents. By extending the base adapters, you can encapsulate an agent's logic, prompts, and tools into a clean, type-safe class.
|
|
62
77
|
|
|
63
|
-
### 1. Data Extraction Agent (`
|
|
78
|
+
### 1. Data Extraction Agent (`ChatAgent`)
|
|
64
79
|
|
|
65
|
-
Use `
|
|
80
|
+
Use `ChatAgent` for structured data extraction and conversational tasks. This example creates a reusable agent to extract contact information with full type safety.
|
|
66
81
|
|
|
67
82
|
```typescript
|
|
68
83
|
import {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
PROMPT_LIBRARY,
|
|
84
|
+
ChatAgent,
|
|
85
|
+
OpenRouterProvider,
|
|
86
|
+
SystemPrompt,
|
|
87
|
+
UserPrompt,
|
|
88
|
+
PROMPTS,
|
|
75
89
|
} from '@jterrazz/intelligence';
|
|
76
90
|
import { z } from 'zod';
|
|
77
91
|
|
|
78
|
-
// 1. Define the output
|
|
79
|
-
|
|
80
|
-
name: string
|
|
81
|
-
email: string
|
|
82
|
-
|
|
92
|
+
// 1. Define the output schema for both compile-time and runtime validation
|
|
93
|
+
const contactSchema = z.object({
|
|
94
|
+
name: z.string().describe('The full name of the person'),
|
|
95
|
+
email: z.string().email().describe('The email address'),
|
|
96
|
+
phone: z.string().optional().describe('Phone number if available'),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
type Contact = z.infer<typeof contactSchema>;
|
|
100
|
+
|
|
101
|
+
// 2. Create a specialized agent by extending ChatAgent
|
|
102
|
+
class ContactExtractorAgent extends ChatAgent<Contact> {
|
|
103
|
+
constructor(provider: OpenRouterProvider) {
|
|
104
|
+
const model = provider.getModel('anthropic/claude-sonnet-4');
|
|
83
105
|
|
|
84
|
-
// 2. Create a specialized agent by extending BasicAgentAdapter
|
|
85
|
-
class ContactExtractorAgent extends BasicAgentAdapter<Contact> {
|
|
86
|
-
constructor(model: ModelPort) {
|
|
87
106
|
super('contact-extractor', {
|
|
88
107
|
model,
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
name: z.string().describe('The full name of the person'),
|
|
92
|
-
email: z.string().email().describe('The email address'),
|
|
93
|
-
}),
|
|
94
|
-
// Compose the system prompt from the library
|
|
95
|
-
systemPrompt: new SystemPromptAdapter(
|
|
96
|
-
PROMPT_LIBRARY.FORMATS.JSON,
|
|
108
|
+
schema: contactSchema, // Enables structured outputs + runtime validation
|
|
109
|
+
systemPrompt: new SystemPrompt(
|
|
97
110
|
'You are an expert at extracting contact details from text.',
|
|
111
|
+
'Always extract the most complete information available.',
|
|
98
112
|
),
|
|
99
113
|
});
|
|
100
114
|
}
|
|
101
115
|
}
|
|
102
116
|
|
|
103
117
|
// 3. Instantiate and use the agent
|
|
104
|
-
const
|
|
118
|
+
const provider = new OpenRouterProvider({
|
|
105
119
|
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
106
|
-
modelName: 'anthropic/claude-3.5-sonnet',
|
|
107
120
|
});
|
|
108
|
-
const agent = new ContactExtractorAgent(
|
|
121
|
+
const agent = new ContactExtractorAgent(provider);
|
|
109
122
|
|
|
110
|
-
const text =
|
|
111
|
-
|
|
123
|
+
const text =
|
|
124
|
+
'Say hi to John Doe, you can reach him at john.doe@example.com or call (555) 123-4567.';
|
|
125
|
+
const contact = await agent.run(new UserPrompt(text));
|
|
112
126
|
|
|
113
127
|
console.log(contact);
|
|
114
|
-
// Output: { name: 'John Doe', email: 'john.doe@example.com' }
|
|
128
|
+
// Output: { name: 'John Doe', email: 'john.doe@example.com', phone: '(555) 123-4567' }
|
|
115
129
|
```
|
|
116
130
|
|
|
117
|
-
### 2.
|
|
131
|
+
### 2. Tool-Enabled Agent (`ToolAgent`)
|
|
118
132
|
|
|
119
|
-
Use `
|
|
133
|
+
Use `ToolAgent` when you need an agent that can reason and use tools to accomplish complex tasks. This example creates a weather assistant.
|
|
120
134
|
|
|
121
135
|
```typescript
|
|
122
136
|
import {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
UserPromptAdapter,
|
|
137
|
+
ToolAgent,
|
|
138
|
+
OpenRouterProvider,
|
|
139
|
+
SafeTool,
|
|
140
|
+
SystemPrompt,
|
|
141
|
+
UserPrompt,
|
|
129
142
|
} from '@jterrazz/intelligence';
|
|
130
143
|
import { z } from 'zod';
|
|
131
144
|
|
|
132
|
-
// 1. Define the agent's final output
|
|
133
|
-
|
|
134
|
-
city: string
|
|
135
|
-
temperature: number
|
|
136
|
-
conditions: string
|
|
137
|
-
forecast: string
|
|
138
|
-
}
|
|
145
|
+
// 1. Define the agent's final output schema
|
|
146
|
+
const weatherReportSchema = z.object({
|
|
147
|
+
city: z.string(),
|
|
148
|
+
temperature: z.number(),
|
|
149
|
+
conditions: z.string(),
|
|
150
|
+
forecast: z.string(),
|
|
151
|
+
});
|
|
139
152
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
153
|
+
type WeatherReport = z.infer<typeof weatherReportSchema>;
|
|
154
|
+
|
|
155
|
+
// 2. Create a weather tool
|
|
156
|
+
const weatherTool = new SafeTool({
|
|
143
157
|
name: 'get_weather',
|
|
144
158
|
description: 'Gets the current weather for a specified city.',
|
|
145
|
-
schema: z.object({
|
|
159
|
+
schema: z.object({
|
|
160
|
+
city: z.string().describe('The name of the city'),
|
|
161
|
+
}),
|
|
146
162
|
execute: async ({ city }) => {
|
|
147
|
-
// In a real app, you would call a weather API here
|
|
148
|
-
// The tool returns raw data, often as a JSON string.
|
|
163
|
+
// In a real app, you would call a weather API here
|
|
149
164
|
if (city.toLowerCase() === 'paris') {
|
|
150
165
|
return JSON.stringify({
|
|
151
166
|
city: 'Paris',
|
|
@@ -158,44 +173,145 @@ const weatherTool = new SafeToolAdapter({
|
|
|
158
173
|
},
|
|
159
174
|
});
|
|
160
175
|
|
|
161
|
-
// 3. Create a specialized
|
|
162
|
-
class WeatherAssistantAgent extends
|
|
163
|
-
constructor(
|
|
176
|
+
// 3. Create a specialized tool agent
|
|
177
|
+
class WeatherAssistantAgent extends ToolAgent<WeatherReport> {
|
|
178
|
+
constructor(provider: OpenRouterProvider) {
|
|
179
|
+
const model = provider.getModel('anthropic/claude-sonnet-4');
|
|
180
|
+
|
|
164
181
|
super('weather-assistant', {
|
|
165
182
|
model,
|
|
166
183
|
tools: [weatherTool],
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
city: z.string(),
|
|
170
|
-
temperature: z.number(),
|
|
171
|
-
conditions: z.string(),
|
|
172
|
-
forecast: z.string(),
|
|
173
|
-
}),
|
|
174
|
-
systemPrompt: new SystemPromptAdapter(
|
|
184
|
+
schema: weatherReportSchema, // Structured output for the final response
|
|
185
|
+
systemPrompt: new SystemPrompt(
|
|
175
186
|
'You are a helpful weather assistant.',
|
|
176
|
-
'
|
|
187
|
+
'Use the available tools to get weather information, then provide a complete weather report.',
|
|
177
188
|
),
|
|
178
189
|
});
|
|
179
190
|
}
|
|
180
191
|
}
|
|
181
192
|
|
|
182
193
|
// 4. Instantiate and use the agent
|
|
183
|
-
const
|
|
194
|
+
const provider = new OpenRouterProvider({
|
|
184
195
|
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
185
|
-
modelName: 'anthropic/claude-3.5-sonnet',
|
|
186
196
|
});
|
|
187
|
-
const agent = new WeatherAssistantAgent(
|
|
197
|
+
const agent = new WeatherAssistantAgent(provider);
|
|
188
198
|
|
|
189
|
-
const response = await agent.run(new
|
|
199
|
+
const response = await agent.run(new UserPrompt("What's the weather like in Paris?"));
|
|
190
200
|
|
|
191
201
|
console.log(response);
|
|
192
202
|
// Output: { city: 'Paris', temperature: 25, conditions: 'sunny', forecast: 'clear skies for the next 24 hours' }
|
|
193
203
|
```
|
|
194
204
|
|
|
205
|
+
### 3. Resilient Agent (`ResilientAgent`)
|
|
206
|
+
|
|
207
|
+
Use `ResilientAgent` to add retry logic and fault tolerance to any existing agent. Perfect for production environments where reliability is crucial.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import {
|
|
211
|
+
ChatAgent,
|
|
212
|
+
ResilientAgent,
|
|
213
|
+
OpenRouterProvider,
|
|
214
|
+
SystemPrompt,
|
|
215
|
+
UserPrompt,
|
|
216
|
+
} from '@jterrazz/intelligence';
|
|
217
|
+
import { z } from 'zod';
|
|
218
|
+
|
|
219
|
+
// 1. Create a base agent
|
|
220
|
+
const provider = new OpenRouterProvider({
|
|
221
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const model = provider.getModel('anthropic/claude-sonnet-4');
|
|
225
|
+
|
|
226
|
+
const baseAgent = new ChatAgent('sentiment-analyzer', {
|
|
227
|
+
model,
|
|
228
|
+
schema: z.object({
|
|
229
|
+
sentiment: z.enum(['positive', 'negative', 'neutral']),
|
|
230
|
+
confidence: z.number().min(0).max(1),
|
|
231
|
+
}),
|
|
232
|
+
systemPrompt: new SystemPrompt(
|
|
233
|
+
'You are a sentiment analysis expert.',
|
|
234
|
+
'Analyze the sentiment of the given text and provide your confidence level.',
|
|
235
|
+
),
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// 2. Wrap with resilient behavior
|
|
239
|
+
const resilientAgent = new ResilientAgent(baseAgent, {
|
|
240
|
+
retries: 3, // Will retry up to 3 times on failure
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// 3. Use the resilient agent - it will automatically retry on failures
|
|
244
|
+
const result = await resilientAgent.run(new UserPrompt('I absolutely love this new feature!'));
|
|
245
|
+
|
|
246
|
+
console.log(result);
|
|
247
|
+
// Output: { sentiment: 'positive', confidence: 0.95 }
|
|
248
|
+
console.log(resilientAgent.name);
|
|
249
|
+
// Output: "Resilient(sentiment-analyzer)"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Advanced Configuration
|
|
253
|
+
|
|
254
|
+
### Model Configuration
|
|
255
|
+
|
|
256
|
+
Customize model behavior with detailed configuration options:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
const provider = new OpenRouterProvider({
|
|
260
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
261
|
+
metadata: {
|
|
262
|
+
application: 'My AI App',
|
|
263
|
+
website: 'https://myapp.com',
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// Configure model-specific settings
|
|
268
|
+
const model = provider.getModel('anthropic/claude-sonnet-4', {
|
|
269
|
+
maxTokens: 100000,
|
|
270
|
+
reasoning: {
|
|
271
|
+
effort: 'high', // Use high reasoning effort for complex tasks
|
|
272
|
+
exclude: true, // Exclude reasoning from the response
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Combining Agents
|
|
278
|
+
|
|
279
|
+
Create powerful workflows by combining different agent types:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
// Create a pipeline: Chat Agent → Tool Agent → Resilient wrapper
|
|
283
|
+
const extractor = new ChatAgent('data-extractor', {
|
|
284
|
+
/* ... */
|
|
285
|
+
});
|
|
286
|
+
const processor = new ToolAgent('data-processor', {
|
|
287
|
+
/* ... */
|
|
288
|
+
});
|
|
289
|
+
const resilientProcessor = new ResilientAgent(processor, { retries: 3 });
|
|
290
|
+
|
|
291
|
+
// Use them in sequence
|
|
292
|
+
const rawData = await extractor.run(userInput);
|
|
293
|
+
const processedData = await resilientProcessor.run(rawData);
|
|
294
|
+
```
|
|
295
|
+
|
|
195
296
|
## Development
|
|
196
297
|
|
|
197
298
|
- **Linting**: `npm run lint`
|
|
198
299
|
- **Testing**: `npm run test`
|
|
300
|
+
- **Building**: `npm run build`
|
|
301
|
+
|
|
302
|
+
## Architecture
|
|
303
|
+
|
|
304
|
+
The library follows **Clean Architecture** principles:
|
|
305
|
+
|
|
306
|
+
- **Ports**: Define interfaces for models, agents, tools, and prompts
|
|
307
|
+
- **Adapters**: Implement the ports for specific providers (OpenRouter, tools, etc.)
|
|
308
|
+
- **Domain Logic**: Core agent behavior independent of external dependencies
|
|
309
|
+
|
|
310
|
+
This makes the library:
|
|
311
|
+
|
|
312
|
+
- **Testable**: Easy to mock dependencies and test business logic
|
|
313
|
+
- **Extensible**: Simple to add new model providers or agent types
|
|
314
|
+
- **Maintainable**: Clear separation between domain logic and infrastructure
|
|
199
315
|
|
|
200
316
|
## Contributing
|
|
201
317
|
|
|
@@ -3,23 +3,23 @@ import { z } from 'zod/v4';
|
|
|
3
3
|
import { type AgentPort } from '../../ports/agent.port.js';
|
|
4
4
|
import type { ModelPort } from '../../ports/model.port.js';
|
|
5
5
|
import type { PromptPort } from '../../ports/prompt.port.js';
|
|
6
|
-
import type {
|
|
7
|
-
export interface
|
|
6
|
+
import type { SystemPrompt } from '../prompts/system-prompt.adapter.js';
|
|
7
|
+
export interface ChatAgentOptions<TOutput = string> {
|
|
8
8
|
logger?: LoggerPort;
|
|
9
9
|
model: ModelPort;
|
|
10
10
|
schema?: z.ZodSchema<TOutput>;
|
|
11
|
-
systemPrompt:
|
|
11
|
+
systemPrompt: SystemPrompt;
|
|
12
12
|
verbose?: boolean;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* A
|
|
15
|
+
* A conversational agent for direct, one-shot interactions with a model.
|
|
16
16
|
* It supports optional response parsing against a Zod schema but does not use tools.
|
|
17
17
|
* @template TOutput - The TypeScript type of the output
|
|
18
18
|
*/
|
|
19
|
-
export declare class
|
|
19
|
+
export declare class ChatAgent<TOutput = string> implements AgentPort<PromptPort, TOutput> {
|
|
20
20
|
readonly name: string;
|
|
21
21
|
private readonly options;
|
|
22
|
-
constructor(name: string, options:
|
|
22
|
+
constructor(name: string, options: ChatAgentOptions<TOutput>);
|
|
23
23
|
run(input?: PromptPort): Promise<null | TOutput>;
|
|
24
24
|
private invokeModel;
|
|
25
25
|
private parseResponse;
|
|
@@ -157,22 +157,23 @@ function _ts_generator(thisArg, body) {
|
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
+
import { generateText } from 'ai';
|
|
160
161
|
import { z } from 'zod/v4';
|
|
161
|
-
import {
|
|
162
|
+
import { StructuredResponseParser } from '../utils/structured-response-parser.js';
|
|
162
163
|
/**
|
|
163
|
-
* A
|
|
164
|
+
* A conversational agent for direct, one-shot interactions with a model.
|
|
164
165
|
* It supports optional response parsing against a Zod schema but does not use tools.
|
|
165
166
|
* @template TOutput - The TypeScript type of the output
|
|
166
|
-
*/ export var
|
|
167
|
+
*/ export var ChatAgent = /*#__PURE__*/ function() {
|
|
167
168
|
"use strict";
|
|
168
|
-
function
|
|
169
|
-
_class_call_check(this,
|
|
169
|
+
function ChatAgent(name, options) {
|
|
170
|
+
_class_call_check(this, ChatAgent);
|
|
170
171
|
_define_property(this, "name", void 0);
|
|
171
172
|
_define_property(this, "options", void 0);
|
|
172
173
|
this.name = name;
|
|
173
174
|
this.options = options;
|
|
174
175
|
}
|
|
175
|
-
_create_class(
|
|
176
|
+
_create_class(ChatAgent, [
|
|
176
177
|
{
|
|
177
178
|
key: "run",
|
|
178
179
|
value: function run(input) {
|
|
@@ -181,7 +182,9 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
181
182
|
return _ts_generator(this, function(_state) {
|
|
182
183
|
switch(_state.label){
|
|
183
184
|
case 0:
|
|
184
|
-
(_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.debug(
|
|
185
|
+
(_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.debug('Starting query execution', {
|
|
186
|
+
agent: this.name
|
|
187
|
+
});
|
|
185
188
|
_state.label = 1;
|
|
186
189
|
case 1:
|
|
187
190
|
_state.trys.push([
|
|
@@ -199,15 +202,18 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
199
202
|
if (this.options.schema) {
|
|
200
203
|
;
|
|
201
204
|
parsedResponse = this.parseResponse(content, this.options.schema);
|
|
202
|
-
(_this_options_logger1 = this.options.logger) === null || _this_options_logger1 === void 0 ? void 0 : _this_options_logger1.
|
|
205
|
+
(_this_options_logger1 = this.options.logger) === null || _this_options_logger1 === void 0 ? void 0 : _this_options_logger1.debug('Execution finished and response parsed', {
|
|
206
|
+
agent: this.name
|
|
207
|
+
});
|
|
203
208
|
return [
|
|
204
209
|
2,
|
|
205
210
|
parsedResponse
|
|
206
211
|
];
|
|
207
212
|
} else {
|
|
208
213
|
;
|
|
209
|
-
(_this_options_logger2 = this.options.logger) === null || _this_options_logger2 === void 0 ? void 0 : _this_options_logger2.
|
|
210
|
-
|
|
214
|
+
(_this_options_logger2 = this.options.logger) === null || _this_options_logger2 === void 0 ? void 0 : _this_options_logger2.debug('Execution finished', {
|
|
215
|
+
agent: this.name
|
|
216
|
+
});
|
|
211
217
|
return [
|
|
212
218
|
2,
|
|
213
219
|
content
|
|
@@ -219,8 +225,10 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
219
225
|
];
|
|
220
226
|
case 3:
|
|
221
227
|
error = _state.sent();
|
|
222
|
-
(_this_options_logger3 = this.options.logger) === null || _this_options_logger3 === void 0 ? void 0 : _this_options_logger3.error(
|
|
223
|
-
|
|
228
|
+
(_this_options_logger3 = this.options.logger) === null || _this_options_logger3 === void 0 ? void 0 : _this_options_logger3.error('Execution failed', {
|
|
229
|
+
agent: this.name,
|
|
230
|
+
error: _instanceof(error, Error) ? error.message : 'Unknown error',
|
|
231
|
+
errorStack: _instanceof(error, Error) ? error.stack : undefined
|
|
224
232
|
});
|
|
225
233
|
return [
|
|
226
234
|
2,
|
|
@@ -239,13 +247,12 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
239
247
|
key: "invokeModel",
|
|
240
248
|
value: function invokeModel(input) {
|
|
241
249
|
return _async_to_generator(function() {
|
|
242
|
-
var _this_options_logger, userInput, systemMessage, jsonSchema, isPrimitiveType, messages, _this_options_logger1,
|
|
250
|
+
var _this_options_logger, userInput, systemMessage, jsonSchema, isPrimitiveType, messages, _this_options_logger1, generateConfig, jsonSchema1, text;
|
|
243
251
|
return _ts_generator(this, function(_state) {
|
|
244
252
|
switch(_state.label){
|
|
245
253
|
case 0:
|
|
246
254
|
userInput = this.resolveUserInput(input);
|
|
247
255
|
systemMessage = this.options.systemPrompt.generate();
|
|
248
|
-
// Add schema definition to system prompt if schema is provided
|
|
249
256
|
if (this.options.schema) {
|
|
250
257
|
jsonSchema = z.toJSONSchema(this.options.schema);
|
|
251
258
|
isPrimitiveType = [
|
|
@@ -270,28 +277,47 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
270
277
|
role: 'user'
|
|
271
278
|
}
|
|
272
279
|
];
|
|
273
|
-
(_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.debug(
|
|
280
|
+
(_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.debug('Invoking model...', {
|
|
281
|
+
agent: this.name,
|
|
274
282
|
hasSchema: !!this.options.schema
|
|
275
283
|
});
|
|
276
284
|
if (this.options.verbose) {
|
|
277
285
|
;
|
|
278
|
-
(_this_options_logger1 = this.options.logger) === null || _this_options_logger1 === void 0 ? void 0 : _this_options_logger1.
|
|
286
|
+
(_this_options_logger1 = this.options.logger) === null || _this_options_logger1 === void 0 ? void 0 : _this_options_logger1.debug('Sending messages to model...', {
|
|
287
|
+
agent: this.name,
|
|
279
288
|
messages: messages
|
|
280
289
|
});
|
|
281
290
|
}
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
+
generateConfig = {
|
|
293
|
+
messages: messages,
|
|
294
|
+
model: this.options.model.getVercelModel()
|
|
295
|
+
};
|
|
296
|
+
// Prepare structured outputs configuration for better schema validation when schema is provided
|
|
297
|
+
// NOTE: OpenRouter supports structured outputs, but @openrouter/ai-sdk-provider (v0.7.3)
|
|
298
|
+
// doesn't pass through responseFormat parameter yet. Currently relies on prompt-based instructions.
|
|
299
|
+
// Once provider support is added, this will provide stronger guarantees than prompts alone.
|
|
300
|
+
// See: https://openrouter.ai/docs/features/structured-outputs
|
|
301
|
+
if (this.options.schema) {
|
|
302
|
+
jsonSchema1 = z.toJSONSchema(this.options.schema);
|
|
303
|
+
generateConfig.responseFormat = {
|
|
304
|
+
json_schema: {
|
|
305
|
+
name: 'response',
|
|
306
|
+
schema: jsonSchema1,
|
|
307
|
+
strict: true
|
|
308
|
+
},
|
|
309
|
+
type: 'json_schema'
|
|
310
|
+
};
|
|
311
|
+
}
|
|
282
312
|
return [
|
|
283
313
|
4,
|
|
284
|
-
|
|
314
|
+
generateText(generateConfig)
|
|
285
315
|
];
|
|
286
316
|
case 1:
|
|
287
|
-
|
|
288
|
-
content = response.content;
|
|
289
|
-
if (typeof content !== 'string') {
|
|
290
|
-
throw new Error('Model returned a non-string content type.');
|
|
291
|
-
}
|
|
317
|
+
text = _state.sent().text;
|
|
292
318
|
return [
|
|
293
319
|
2,
|
|
294
|
-
|
|
320
|
+
text
|
|
295
321
|
];
|
|
296
322
|
}
|
|
297
323
|
});
|
|
@@ -302,10 +328,11 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
302
328
|
key: "parseResponse",
|
|
303
329
|
value: function parseResponse(content, schema) {
|
|
304
330
|
try {
|
|
305
|
-
return new
|
|
331
|
+
return new StructuredResponseParser(schema).parse(content);
|
|
306
332
|
} catch (error) {
|
|
307
333
|
var _this_options_logger;
|
|
308
|
-
(_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.error(
|
|
334
|
+
(_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.error('Failed to parse model response.', {
|
|
335
|
+
agent: this.name,
|
|
309
336
|
error: _instanceof(error, Error) ? error.message : 'Unknown error',
|
|
310
337
|
rawContent: content
|
|
311
338
|
});
|
|
@@ -323,7 +350,7 @@ import { AIResponseParser } from '../utils/ai-response-parser.js';
|
|
|
323
350
|
}
|
|
324
351
|
}
|
|
325
352
|
]);
|
|
326
|
-
return
|
|
353
|
+
return ChatAgent;
|
|
327
354
|
}();
|
|
328
355
|
|
|
329
|
-
//# sourceMappingURL=
|
|
356
|
+
//# sourceMappingURL=chat-agent.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/adapters/agents/chat-agent.adapter.ts"],"sourcesContent":["import { type LoggerPort } from '@jterrazz/logger';\nimport { generateText } from 'ai';\nimport { z } from 'zod/v4';\n\nimport { type AgentPort } from '../../ports/agent.port.js';\nimport type { ModelPort } from '../../ports/model.port.js';\nimport type { PromptPort } from '../../ports/prompt.port.js';\n\nimport { StructuredResponseParser } from '../utils/structured-response-parser.js';\n\nimport type { SystemPrompt } from '../prompts/system-prompt.adapter.js';\n\nexport interface ChatAgentOptions<TOutput = string> {\n logger?: LoggerPort;\n model: ModelPort;\n schema?: z.ZodSchema<TOutput>;\n systemPrompt: SystemPrompt;\n verbose?: boolean;\n}\n\n/**\n * A conversational agent for direct, one-shot interactions with a model.\n * It supports optional response parsing against a Zod schema but does not use tools.\n * @template TOutput - The TypeScript type of the output\n */\nexport class ChatAgent<TOutput = string> implements AgentPort<PromptPort, TOutput> {\n constructor(\n public readonly name: string,\n private readonly options: ChatAgentOptions<TOutput>,\n ) {}\n\n async run(input?: PromptPort): Promise<null | TOutput> {\n this.options.logger?.debug('Starting query execution', { agent: this.name });\n\n try {\n const content = await this.invokeModel(input);\n\n if (this.options.schema) {\n const parsedResponse = this.parseResponse(content, this.options.schema);\n\n this.options.logger?.debug('Execution finished and response parsed', {\n agent: this.name,\n });\n\n return parsedResponse;\n } else {\n this.options.logger?.debug('Execution finished', { agent: this.name });\n\n return content as TOutput;\n }\n } catch (error) {\n this.options.logger?.error('Execution failed', {\n agent: this.name,\n error: error instanceof Error ? error.message : 'Unknown error',\n errorStack: error instanceof Error ? error.stack : undefined,\n });\n return null;\n }\n }\n\n private async invokeModel(input?: PromptPort): Promise<string> {\n const userInput = this.resolveUserInput(input);\n let systemMessage = this.options.systemPrompt.generate();\n\n if (this.options.schema) {\n const jsonSchema = z.toJSONSchema(this.options.schema);\n const isPrimitiveType = ['boolean', 'integer', 'number', 'string'].includes(\n jsonSchema.type as string,\n );\n\n if (isPrimitiveType) {\n systemMessage += `\\n\\n<OUTPUT_FORMAT>\nYou must respond with a ${jsonSchema.type} value that matches this schema:\n\n\\`\\`\\`json\n${JSON.stringify(jsonSchema, null, 2)}\n\\`\\`\\`\n\nYour response should be only the ${jsonSchema.type} value, without any JSON wrapping or additional text.\n</OUTPUT_FORMAT>`;\n } else {\n systemMessage += `\\n\\n<OUTPUT_FORMAT>\nYou must respond with valid JSON that matches this JSON schema description:\n\n\\`\\`\\`json\n${JSON.stringify(jsonSchema, null, 2)}\n\\`\\`\\`\n\nYour response must be parseable JSON that validates against this schema. Do not include any text outside the JSON.\n</OUTPUT_FORMAT>`;\n }\n }\n\n const messages = [\n { content: systemMessage, role: 'system' as const },\n { content: userInput, role: 'user' as const },\n ];\n\n this.options.logger?.debug('Invoking model...', {\n agent: this.name,\n hasSchema: !!this.options.schema,\n });\n\n if (this.options.verbose) {\n this.options.logger?.debug('Sending messages to model...', {\n agent: this.name,\n messages,\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const generateConfig: any = {\n messages,\n model: this.options.model.getVercelModel(),\n };\n\n // Prepare structured outputs configuration for better schema validation when schema is provided\n // NOTE: OpenRouter supports structured outputs, but @openrouter/ai-sdk-provider (v0.7.3)\n // doesn't pass through responseFormat parameter yet. Currently relies on prompt-based instructions.\n // Once provider support is added, this will provide stronger guarantees than prompts alone.\n // See: https://openrouter.ai/docs/features/structured-outputs\n if (this.options.schema) {\n const jsonSchema = z.toJSONSchema(this.options.schema);\n generateConfig.responseFormat = {\n json_schema: {\n name: 'response',\n schema: jsonSchema,\n strict: true,\n },\n type: 'json_schema',\n };\n }\n\n const { text } = await generateText(generateConfig);\n\n return text;\n }\n\n private parseResponse<TResponse>(content: string, schema: z.ZodSchema<TResponse>): TResponse {\n try {\n return new StructuredResponseParser(schema).parse(content);\n } catch (error) {\n this.options.logger?.error('Failed to parse model response.', {\n agent: this.name,\n error: error instanceof Error ? error.message : 'Unknown error',\n rawContent: content,\n });\n throw new Error('Invalid response format from model.');\n }\n }\n\n private resolveUserInput(input?: PromptPort): string {\n if (input) {\n return input.generate();\n }\n return 'Proceed with your instructions.';\n }\n}\n"],"names":["generateText","z","StructuredResponseParser","ChatAgent","name","options","run","input","content","parsedResponse","error","logger","debug","agent","invokeModel","schema","parseResponse","Error","message","errorStack","stack","undefined","userInput","systemMessage","jsonSchema","isPrimitiveType","messages","generateConfig","text","resolveUserInput","systemPrompt","generate","toJSONSchema","includes","type","JSON","stringify","role","hasSchema","verbose","model","getVercelModel","responseFormat","json_schema","strict","parse","rawContent"],"mappings":"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"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { type LoggerPort } from '@jterrazz/logger';
|
|
2
2
|
import { type AgentPort } from '../../ports/agent.port.js';
|
|
3
3
|
import type { PromptPort } from '../../ports/prompt.port.js';
|
|
4
|
-
export interface
|
|
4
|
+
export interface ResilientAgentOptions {
|
|
5
5
|
logger?: LoggerPort;
|
|
6
6
|
retries?: number;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* A decorator agent that adds retry logic to an existing agent.
|
|
9
|
+
* A decorator agent that adds retry logic to an existing agent for resilient execution.
|
|
10
10
|
* @template TInput - The TypeScript type of the input
|
|
11
11
|
* @template TOutput - The TypeScript type of the output
|
|
12
12
|
*/
|
|
13
|
-
export declare class
|
|
13
|
+
export declare class ResilientAgent<TInput = PromptPort, TOutput = string> implements AgentPort<TInput, TOutput> {
|
|
14
14
|
private readonly agent;
|
|
15
15
|
readonly name: string;
|
|
16
16
|
private readonly logger?;
|
|
17
17
|
private readonly retries;
|
|
18
|
-
constructor(agent: AgentPort<TInput, TOutput>, options?:
|
|
18
|
+
constructor(agent: AgentPort<TInput, TOutput>, options?: ResilientAgentOptions);
|
|
19
19
|
run(input?: TInput): Promise<null | TOutput>;
|
|
20
20
|
}
|