@jterrazz/intelligence 2.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +56 -268
  2. package/dist/index.cjs +652 -2017
  3. package/dist/index.d.ts +5 -15
  4. package/dist/index.js +5 -33
  5. package/dist/index.js.map +1 -1
  6. package/dist/middleware/__tests__/logging.middleware.test.js +390 -0
  7. package/dist/middleware/__tests__/logging.middleware.test.js.map +1 -0
  8. package/dist/middleware/logging.middleware.d.ts +21 -0
  9. package/dist/middleware/logging.middleware.js +296 -0
  10. package/dist/middleware/logging.middleware.js.map +1 -0
  11. package/dist/parsing/__tests__/create-schema-prompt.test.js +53 -0
  12. package/dist/parsing/__tests__/create-schema-prompt.test.js.map +1 -0
  13. package/dist/parsing/__tests__/parse-object.test.d.ts +1 -0
  14. package/dist/parsing/__tests__/parse-object.test.js +193 -0
  15. package/dist/parsing/__tests__/parse-object.test.js.map +1 -0
  16. package/dist/parsing/__tests__/parse-text.test.d.ts +1 -0
  17. package/dist/parsing/__tests__/parse-text.test.js +167 -0
  18. package/dist/parsing/__tests__/parse-text.test.js.map +1 -0
  19. package/dist/parsing/create-schema-prompt.d.ts +28 -0
  20. package/dist/parsing/create-schema-prompt.js +42 -0
  21. package/dist/parsing/create-schema-prompt.js.map +1 -0
  22. package/dist/parsing/parse-object.d.ts +33 -0
  23. package/dist/parsing/parse-object.js +360 -0
  24. package/dist/parsing/parse-object.js.map +1 -0
  25. package/dist/parsing/parse-text.d.ts +14 -0
  26. package/dist/parsing/parse-text.js +76 -0
  27. package/dist/parsing/parse-text.js.map +1 -0
  28. package/dist/providers/openrouter.provider.d.ts +36 -0
  29. package/dist/providers/openrouter.provider.js +58 -0
  30. package/dist/providers/openrouter.provider.js.map +1 -0
  31. package/package.json +14 -15
  32. package/dist/adapters/agents/chat-agent.adapter.d.ts +0 -27
  33. package/dist/adapters/agents/chat-agent.adapter.js +0 -356
  34. package/dist/adapters/agents/chat-agent.adapter.js.map +0 -1
  35. package/dist/adapters/agents/resilient-agent.adapter.d.ts +0 -20
  36. package/dist/adapters/agents/resilient-agent.adapter.js +0 -263
  37. package/dist/adapters/agents/resilient-agent.adapter.js.map +0 -1
  38. package/dist/adapters/agents/tool-agent.adapter.d.ts +0 -30
  39. package/dist/adapters/agents/tool-agent.adapter.js +0 -400
  40. package/dist/adapters/agents/tool-agent.adapter.js.map +0 -1
  41. package/dist/adapters/models/openrouter-model.adapter.d.ts +0 -23
  42. package/dist/adapters/models/openrouter-model.adapter.js +0 -148
  43. package/dist/adapters/models/openrouter-model.adapter.js.map +0 -1
  44. package/dist/adapters/prompts/__tests__/__snapshots__/presets.test.ts.snap +0 -120
  45. package/dist/adapters/prompts/__tests__/presets.test.js +0 -31
  46. package/dist/adapters/prompts/__tests__/presets.test.js.map +0 -1
  47. package/dist/adapters/prompts/library/categories/domain.d.ts +0 -11
  48. package/dist/adapters/prompts/library/categories/domain.js +0 -12
  49. package/dist/adapters/prompts/library/categories/domain.js.map +0 -1
  50. package/dist/adapters/prompts/library/categories/format.d.ts +0 -10
  51. package/dist/adapters/prompts/library/categories/format.js +0 -11
  52. package/dist/adapters/prompts/library/categories/format.js.map +0 -1
  53. package/dist/adapters/prompts/library/categories/foundations.d.ts +0 -12
  54. package/dist/adapters/prompts/library/categories/foundations.js +0 -13
  55. package/dist/adapters/prompts/library/categories/foundations.js.map +0 -1
  56. package/dist/adapters/prompts/library/categories/language.d.ts +0 -11
  57. package/dist/adapters/prompts/library/categories/language.js +0 -12
  58. package/dist/adapters/prompts/library/categories/language.js.map +0 -1
  59. package/dist/adapters/prompts/library/categories/persona.d.ts +0 -13
  60. package/dist/adapters/prompts/library/categories/persona.js +0 -14
  61. package/dist/adapters/prompts/library/categories/persona.js.map +0 -1
  62. package/dist/adapters/prompts/library/categories/response.d.ts +0 -9
  63. package/dist/adapters/prompts/library/categories/response.js +0 -10
  64. package/dist/adapters/prompts/library/categories/response.js.map +0 -1
  65. package/dist/adapters/prompts/library/categories/tone.d.ts +0 -9
  66. package/dist/adapters/prompts/library/categories/tone.js +0 -10
  67. package/dist/adapters/prompts/library/categories/tone.js.map +0 -1
  68. package/dist/adapters/prompts/library/categories/verbosity.d.ts +0 -8
  69. package/dist/adapters/prompts/library/categories/verbosity.js +0 -9
  70. package/dist/adapters/prompts/library/categories/verbosity.js.map +0 -1
  71. package/dist/adapters/prompts/library/index.d.ts +0 -68
  72. package/dist/adapters/prompts/library/index.js +0 -26
  73. package/dist/adapters/prompts/library/index.js.map +0 -1
  74. package/dist/adapters/prompts/library/presets.d.ts +0 -17
  75. package/dist/adapters/prompts/library/presets.js +0 -45
  76. package/dist/adapters/prompts/library/presets.js.map +0 -1
  77. package/dist/adapters/prompts/system-prompt.adapter.d.ts +0 -9
  78. package/dist/adapters/prompts/system-prompt.adapter.js +0 -57
  79. package/dist/adapters/prompts/system-prompt.adapter.js.map +0 -1
  80. package/dist/adapters/prompts/user-prompt.adapter.d.ts +0 -9
  81. package/dist/adapters/prompts/user-prompt.adapter.js +0 -57
  82. package/dist/adapters/prompts/user-prompt.adapter.js.map +0 -1
  83. package/dist/adapters/providers/openrouter-provider.adapter.d.ts +0 -34
  84. package/dist/adapters/providers/openrouter-provider.adapter.js +0 -57
  85. package/dist/adapters/providers/openrouter-provider.adapter.js.map +0 -1
  86. package/dist/adapters/tools/safe-tool.adapter.d.ts +0 -27
  87. package/dist/adapters/tools/safe-tool.adapter.js +0 -283
  88. package/dist/adapters/tools/safe-tool.adapter.js.map +0 -1
  89. package/dist/adapters/utils/__tests__/structured-response-parser.test.js +0 -289
  90. package/dist/adapters/utils/__tests__/structured-response-parser.test.js.map +0 -1
  91. package/dist/adapters/utils/structured-response-parser-error.d.ts +0 -8
  92. package/dist/adapters/utils/structured-response-parser-error.js +0 -136
  93. package/dist/adapters/utils/structured-response-parser-error.js.map +0 -1
  94. package/dist/adapters/utils/structured-response-parser.d.ts +0 -60
  95. package/dist/adapters/utils/structured-response-parser.js +0 -347
  96. package/dist/adapters/utils/structured-response-parser.js.map +0 -1
  97. package/dist/ports/agent.port.d.ts +0 -17
  98. package/dist/ports/agent.port.js +0 -7
  99. package/dist/ports/agent.port.js.map +0 -1
  100. package/dist/ports/model.port.d.ts +0 -37
  101. package/dist/ports/model.port.js +0 -5
  102. package/dist/ports/model.port.js.map +0 -1
  103. package/dist/ports/prompt.port.d.ts +0 -9
  104. package/dist/ports/prompt.port.js +0 -5
  105. package/dist/ports/prompt.port.js.map +0 -1
  106. package/dist/ports/provider.port.d.ts +0 -13
  107. package/dist/ports/provider.port.js +0 -5
  108. package/dist/ports/provider.port.js.map +0 -1
  109. package/dist/ports/tool.port.d.ts +0 -11
  110. package/dist/ports/tool.port.js +0 -5
  111. package/dist/ports/tool.port.js.map +0 -1
  112. /package/dist/{adapters/prompts/__tests__/presets.test.d.ts → middleware/__tests__/logging.middleware.test.d.ts} +0 -0
  113. /package/dist/{adapters/utils/__tests__/structured-response-parser.test.d.ts → parsing/__tests__/create-schema-prompt.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,324 +1,112 @@
1
1
  # @jterrazz/intelligence
2
2
 
3
- **A composable, type-safe, and framework-agnostic AI agent library for TypeScript.**
4
-
5
- [![NPM Version](https://img.shields.io/npm/v/@jterrazz/intelligence.svg)](https://www.npmjs.com/package/@jterrazz/intelligence)
6
- [![License](https://img.shields.io/npm/l/@jterrazz/intelligence.svg)](./LICENSE)
7
-
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
-
10
- ---
11
-
12
- ## Core Principles
13
-
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
-
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
-
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
-
20
- - **Structured Outputs**: Leverages both prompt-based schema instructions and OpenRouter's official structured outputs for reliable, validated responses.
3
+ Lightweight utilities for AI SDK apps structured output parsing, text sanitization, and provider helpers.
21
4
 
22
5
  ## Installation
23
6
 
24
7
  ```bash
25
- npm install @jterrazz/intelligence
8
+ npm install @jterrazz/intelligence ai zod
26
9
  ```
27
10
 
28
- ---
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**
11
+ ## Parsing Utilities
41
12
 
42
- For complex workflows requiring external tools and function calling. Can reason about when to use tools and provide structured responses.
13
+ ### `parseObject` Extract structured data from AI responses
43
14
 
44
- ---
45
-
46
- ## Quick Start
47
-
48
- Get your first agent running in minutes. This example creates a helpful conversational agent.
15
+ Extracts and validates JSON from messy AI outputs (markdown blocks, embedded JSON, malformed syntax).
49
16
 
50
17
  ```typescript
51
- import { ChatAgent, OpenRouterProvider, SystemPrompt, PROMPTS } from '@jterrazz/intelligence';
52
-
53
- // 1. Set up the model provider
54
- const provider = new OpenRouterProvider({
55
- apiKey: process.env.OPENROUTER_API_KEY!, // Make sure to set this environment variable
56
- });
57
-
58
- // 2. Get a model instance
59
- const model = provider.getModel('anthropic/claude-sonnet-4');
18
+ import { parseObject } from '@jterrazz/intelligence';
19
+ import { z } from 'zod';
60
20
 
61
- // 3. Create a conversational agent
62
- const agent = new ChatAgent('helpful-assistant', {
63
- model,
64
- systemPrompt: new SystemPrompt(PROMPTS.PRESETS.HELPFUL_ASSISTANT),
21
+ const schema = z.object({
22
+ title: z.string(),
23
+ tags: z.array(z.string()),
65
24
  });
66
25
 
67
- // 4. Run the agent
68
- const response = await agent.run();
69
-
70
- console.log(response);
71
- // Output: "Hello! I'm here to help you with any questions or tasks you might have. What can I assist you with today?"
26
+ // Handles markdown code blocks, embedded JSON, trailing commas, etc.
27
+ const text = '```json\n{"title": "Hello", "tags": ["ai", "typescript"]}\n```';
28
+ const result = parseObject(text, schema);
29
+ // → { title: 'Hello', tags: ['ai', 'typescript'] }
72
30
  ```
73
31
 
74
- ## Creating Domain-Specific Agents
32
+ ### `createSchemaPrompt` Generate schema instructions for prompts
75
33
 
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.
77
-
78
- ### 1. Data Extraction Agent (`ChatAgent`)
79
-
80
- Use `ChatAgent` for structured data extraction and conversational tasks. This example creates a reusable agent to extract contact information with full type safety.
34
+ Creates system prompt instructions for models that don't support native structured outputs.
81
35
 
82
36
  ```typescript
83
- import {
84
- ChatAgent,
85
- OpenRouterProvider,
86
- SystemPrompt,
87
- UserPrompt,
88
- PROMPTS,
89
- } from '@jterrazz/intelligence';
37
+ import { generateText } from 'ai';
38
+ import { createSchemaPrompt, parseObject } from '@jterrazz/intelligence';
90
39
  import { z } from 'zod';
91
40
 
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
- });
41
+ const schema = z.object({ summary: z.string(), score: z.number() });
98
42
 
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');
105
-
106
- super('contact-extractor', {
107
- model,
108
- schema: contactSchema, // Enables structured outputs + runtime validation
109
- systemPrompt: new SystemPrompt(
110
- 'You are an expert at extracting contact details from text.',
111
- 'Always extract the most complete information available.',
112
- ),
113
- });
114
- }
115
- }
116
-
117
- // 3. Instantiate and use the agent
118
- const provider = new OpenRouterProvider({
119
- apiKey: process.env.OPENROUTER_API_KEY!,
43
+ const { text } = await generateText({
44
+ model,
45
+ prompt: 'Analyze this article...',
46
+ system: createSchemaPrompt(schema), // Injects JSON schema instructions
120
47
  });
121
- const agent = new ContactExtractorAgent(provider);
122
48
 
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));
126
-
127
- console.log(contact);
128
- // Output: { name: 'John Doe', email: 'john.doe@example.com', phone: '(555) 123-4567' }
49
+ const result = parseObject(text, schema);
129
50
  ```
130
51
 
131
- ### 2. Tool-Enabled Agent (`ToolAgent`)
52
+ ### `parseText` — Sanitize AI-generated text
132
53
 
133
- Use `ToolAgent` when you need an agent that can reason and use tools to accomplish complex tasks. This example creates a weather assistant.
54
+ Removes invisible characters, normalizes typography, and cleans common AI artifacts.
134
55
 
135
56
  ```typescript
136
- import {
137
- ToolAgent,
138
- OpenRouterProvider,
139
- SafeTool,
140
- SystemPrompt,
141
- UserPrompt,
142
- } from '@jterrazz/intelligence';
143
- import { z } from 'zod';
57
+ import { parseText } from '@jterrazz/intelligence';
144
58
 
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(),
59
+ const clean = parseText(messyAiOutput, {
60
+ normalizeTypography: true, // Smart quotes → straight quotes
61
+ removeInvisibleChars: true, // Zero-width chars, etc.
62
+ trimWhitespace: true,
151
63
  });
152
-
153
- type WeatherReport = z.infer<typeof weatherReportSchema>;
154
-
155
- // 2. Create a weather tool
156
- const weatherTool = new SafeTool({
157
- name: 'get_weather',
158
- description: 'Gets the current weather for a specified city.',
159
- schema: z.object({
160
- city: z.string().describe('The name of the city'),
161
- }),
162
- execute: async ({ city }) => {
163
- // In a real app, you would call a weather API here
164
- if (city.toLowerCase() === 'paris') {
165
- return JSON.stringify({
166
- city: 'Paris',
167
- temperature: 25,
168
- conditions: 'sunny',
169
- forecast: 'clear skies for the next 24 hours',
170
- });
171
- }
172
- return `Sorry, I don't have weather information for ${city}.`;
173
- },
174
- });
175
-
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
-
181
- super('weather-assistant', {
182
- model,
183
- tools: [weatherTool],
184
- schema: weatherReportSchema, // Structured output for the final response
185
- systemPrompt: new SystemPrompt(
186
- 'You are a helpful weather assistant.',
187
- 'Use the available tools to get weather information, then provide a complete weather report.',
188
- ),
189
- });
190
- }
191
- }
192
-
193
- // 4. Instantiate and use the agent
194
- const provider = new OpenRouterProvider({
195
- apiKey: process.env.OPENROUTER_API_KEY!,
196
- });
197
- const agent = new WeatherAssistantAgent(provider);
198
-
199
- const response = await agent.run(new UserPrompt("What's the weather like in Paris?"));
200
-
201
- console.log(response);
202
- // Output: { city: 'Paris', temperature: 25, conditions: 'sunny', forecast: 'clear skies for the next 24 hours' }
203
64
  ```
204
65
 
205
- ### 3. Resilient Agent (`ResilientAgent`)
66
+ ## Provider
206
67
 
207
- Use `ResilientAgent` to add retry logic and fault tolerance to any existing agent. Perfect for production environments where reliability is crucial.
68
+ ### `createOpenRouterProvider` OpenRouter for AI SDK
208
69
 
209
70
  ```typescript
210
- import {
211
- ChatAgent,
212
- ResilientAgent,
213
- OpenRouterProvider,
214
- SystemPrompt,
215
- UserPrompt,
216
- } from '@jterrazz/intelligence';
217
- import { z } from 'zod';
71
+ import { generateText } from 'ai';
72
+ import { createOpenRouterProvider } from '@jterrazz/intelligence';
218
73
 
219
- // 1. Create a base agent
220
- const provider = new OpenRouterProvider({
221
- apiKey: process.env.OPENROUTER_API_KEY!,
74
+ const provider = createOpenRouterProvider({
75
+ apiKey: process.env.OPENROUTER_API_KEY,
222
76
  });
223
77
 
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
- ),
78
+ const { text } = await generateText({
79
+ model: provider.model('anthropic/claude-sonnet-4-20250514'),
80
+ prompt: 'Hello!',
236
81
  });
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
82
  ```
251
83
 
252
- ## Advanced Configuration
253
-
254
- ### Model Configuration
255
-
256
- Customize model behavior with detailed configuration options:
84
+ With reasoning models:
257
85
 
258
86
  ```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
- },
87
+ const model = provider.model('anthropic/claude-sonnet-4-20250514', {
88
+ maxTokens: 16000,
89
+ reasoning: { effort: 'high' },
274
90
  });
275
91
  ```
276
92
 
277
- ### Combining Agents
93
+ ## Middleware
278
94
 
279
- Create powerful workflows by combining different agent types:
95
+ ### `createLoggingMiddleware` Log AI SDK requests
280
96
 
281
97
  ```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
- /* ... */
98
+ import { wrapLanguageModel } from 'ai';
99
+ import { createLoggingMiddleware } from '@jterrazz/intelligence';
100
+
101
+ const model = wrapLanguageModel({
102
+ model: provider.model('anthropic/claude-sonnet-4-20250514'),
103
+ middleware: createLoggingMiddleware({
104
+ logger, // Any logger with debug/error methods
105
+ verbose: false, // Include full request/response in logs
106
+ }),
288
107
  });
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
108
  ```
295
109
 
296
- ## Development
297
-
298
- - **Linting**: `npm run lint`
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
315
-
316
- ## Contributing
317
-
318
- Contributions are welcome! Please feel free to open an issue or submit a pull request.
319
-
320
- ---
321
-
322
110
  ## License
323
111
 
324
- This project is licensed under the [MIT License](./LICENSE).
112
+ MIT