@jterrazz/intelligence 3.0.2 → 4.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.
- package/README.md +260 -63
- package/dist/index.cjs +594 -808
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +350 -5
- package/dist/index.js +620 -5
- package/dist/index.js.map +1 -1
- package/package.json +26 -20
- package/dist/middleware/__tests__/logging.middleware.test.d.ts +0 -1
- package/dist/middleware/__tests__/logging.middleware.test.js +0 -463
- package/dist/middleware/__tests__/logging.middleware.test.js.map +0 -1
- package/dist/middleware/logging.middleware.d.ts +0 -29
- package/dist/middleware/logging.middleware.js +0 -298
- package/dist/middleware/logging.middleware.js.map +0 -1
- package/dist/parsing/__tests__/create-schema-prompt.test.d.ts +0 -1
- package/dist/parsing/__tests__/create-schema-prompt.test.js +0 -53
- package/dist/parsing/__tests__/create-schema-prompt.test.js.map +0 -1
- package/dist/parsing/__tests__/parse-object.test.d.ts +0 -1
- package/dist/parsing/__tests__/parse-object.test.js +0 -433
- package/dist/parsing/__tests__/parse-object.test.js.map +0 -1
- package/dist/parsing/__tests__/parse-text.test.d.ts +0 -1
- package/dist/parsing/__tests__/parse-text.test.js +0 -167
- package/dist/parsing/__tests__/parse-text.test.js.map +0 -1
- package/dist/parsing/create-schema-prompt.d.ts +0 -28
- package/dist/parsing/create-schema-prompt.js +0 -42
- package/dist/parsing/create-schema-prompt.js.map +0 -1
- package/dist/parsing/parse-object.d.ts +0 -33
- package/dist/parsing/parse-object.js +0 -383
- package/dist/parsing/parse-object.js.map +0 -1
- package/dist/parsing/parse-text.d.ts +0 -14
- package/dist/parsing/parse-text.js +0 -76
- package/dist/parsing/parse-text.js.map +0 -1
- package/dist/providers/openrouter.provider.d.ts +0 -36
- package/dist/providers/openrouter.provider.js +0 -58
- package/dist/providers/openrouter.provider.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jterrazz/intelligence
|
|
2
2
|
|
|
3
|
-
Lightweight utilities for AI SDK apps
|
|
3
|
+
Lightweight, composable utilities for AI SDK apps - middleware for logging and observability, structured output parsing, result handling, and provider helpers.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,112 +8,309 @@ Lightweight utilities for AI SDK apps — structured output parsing, text saniti
|
|
|
8
8
|
npm install @jterrazz/intelligence ai zod
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Generation
|
|
12
12
|
|
|
13
|
-
### `
|
|
13
|
+
### `generateStructured` - Type-safe structured generation with error handling
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Combines `generateText` + `parseObject` + error classification into a single function that returns a discriminated union result.
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import {
|
|
19
|
-
import { z } from
|
|
18
|
+
import { generateStructured, withObservability } from "@jterrazz/intelligence";
|
|
19
|
+
import { z } from "zod";
|
|
20
20
|
|
|
21
21
|
const schema = z.object({
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
sentiment: z.string(),
|
|
23
|
+
score: z.number(),
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
const result = await generateStructured({
|
|
27
|
+
model,
|
|
28
|
+
prompt: "Analyze this article...",
|
|
29
|
+
schema,
|
|
30
|
+
providerOptions: withObservability({ traceId: "trace-123" }),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (result.success) {
|
|
34
|
+
console.log(result.data.sentiment, result.data.score);
|
|
35
|
+
} else {
|
|
36
|
+
// Typed error with code: TIMEOUT | RATE_LIMITED | PARSING_FAILED | etc.
|
|
37
|
+
console.error(result.error.code, result.error.message);
|
|
38
|
+
}
|
|
30
39
|
```
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
## Result Utilities
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
Discriminated union result type for explicit error handling.
|
|
35
44
|
|
|
36
45
|
```typescript
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
import {
|
|
47
|
+
generationSuccess,
|
|
48
|
+
generationFailure,
|
|
49
|
+
isSuccess,
|
|
50
|
+
isFailure,
|
|
51
|
+
unwrap,
|
|
52
|
+
unwrapOr,
|
|
53
|
+
classifyError,
|
|
54
|
+
type GenerationResult,
|
|
55
|
+
} from "@jterrazz/intelligence";
|
|
56
|
+
|
|
57
|
+
// Create results
|
|
58
|
+
const success = generationSuccess({ data: "value" });
|
|
59
|
+
const failure = generationFailure("TIMEOUT", "Request timed out");
|
|
60
|
+
|
|
61
|
+
// Type guards
|
|
62
|
+
if (isSuccess(result)) {
|
|
63
|
+
console.log(result.data);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Unwrap with default
|
|
67
|
+
const value = unwrapOr(result, defaultValue);
|
|
68
|
+
|
|
69
|
+
// Classify errors automatically
|
|
70
|
+
try {
|
|
71
|
+
await someOperation();
|
|
72
|
+
} catch (error) {
|
|
73
|
+
const code = classifyError(error); // TIMEOUT, RATE_LIMITED, PARSING_FAILED, etc.
|
|
74
|
+
}
|
|
75
|
+
```
|
|
40
76
|
|
|
41
|
-
|
|
77
|
+
## Middleware
|
|
42
78
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
79
|
+
Composable middlewares that wrap AI SDK models. Stack them together for logging, observability, and more.
|
|
80
|
+
|
|
81
|
+
### Composing Middlewares
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { wrapLanguageModel } from "ai";
|
|
85
|
+
import {
|
|
86
|
+
createLoggingMiddleware,
|
|
87
|
+
createObservabilityMiddleware,
|
|
88
|
+
LangfuseAdapter,
|
|
89
|
+
OpenRouterMetadataAdapter,
|
|
90
|
+
} from "@jterrazz/intelligence";
|
|
91
|
+
|
|
92
|
+
const model = wrapLanguageModel({
|
|
93
|
+
model: provider.model("anthropic/claude-sonnet-4-20250514"),
|
|
94
|
+
middleware: [
|
|
95
|
+
createLoggingMiddleware({ logger, include: { usage: true } }),
|
|
96
|
+
createObservabilityMiddleware({
|
|
97
|
+
observability: new LangfuseAdapter({
|
|
98
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
99
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
100
|
+
}),
|
|
101
|
+
providerMetadata: new OpenRouterMetadataAdapter(),
|
|
102
|
+
}),
|
|
103
|
+
],
|
|
47
104
|
});
|
|
105
|
+
```
|
|
48
106
|
|
|
49
|
-
|
|
107
|
+
### Logging Middleware
|
|
108
|
+
|
|
109
|
+
Logs AI SDK requests with timing, usage, and optional content.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { wrapLanguageModel, generateText } from "ai";
|
|
113
|
+
import { createLoggingMiddleware } from "@jterrazz/intelligence";
|
|
114
|
+
|
|
115
|
+
const model = wrapLanguageModel({
|
|
116
|
+
model: provider.model("anthropic/claude-sonnet-4-20250514"),
|
|
117
|
+
middleware: createLoggingMiddleware({
|
|
118
|
+
logger,
|
|
119
|
+
include: {
|
|
120
|
+
params: false, // Log request params
|
|
121
|
+
content: false, // Log response content
|
|
122
|
+
usage: true, // Log token usage (default: true)
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await generateText({ model, prompt: "Hello!" });
|
|
128
|
+
// Logs: ai.generate.start, ai.generate.complete (with durationMs, usage, etc.)
|
|
50
129
|
```
|
|
51
130
|
|
|
52
|
-
###
|
|
131
|
+
### Observability Middleware
|
|
53
132
|
|
|
54
|
-
|
|
133
|
+
Sends generation data to observability platforms (Langfuse, etc.).
|
|
55
134
|
|
|
56
135
|
```typescript
|
|
57
|
-
import {
|
|
136
|
+
import { wrapLanguageModel, generateText } from "ai";
|
|
137
|
+
import {
|
|
138
|
+
createObservabilityMiddleware,
|
|
139
|
+
withObservability,
|
|
140
|
+
LangfuseAdapter,
|
|
141
|
+
} from "@jterrazz/intelligence";
|
|
142
|
+
|
|
143
|
+
const observability = new LangfuseAdapter({
|
|
144
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
145
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
146
|
+
});
|
|
58
147
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
148
|
+
const model = wrapLanguageModel({
|
|
149
|
+
model: provider.model("anthropic/claude-sonnet-4-20250514"),
|
|
150
|
+
middleware: createObservabilityMiddleware({ observability }),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Use withObservability() helper for type-safe metadata
|
|
154
|
+
await generateText({
|
|
155
|
+
model,
|
|
156
|
+
prompt: "Analyze this...",
|
|
157
|
+
providerOptions: withObservability({
|
|
158
|
+
traceId: "trace-123",
|
|
159
|
+
name: "analyzer",
|
|
160
|
+
metadata: { userId: "user-1" },
|
|
161
|
+
}),
|
|
68
162
|
});
|
|
69
163
|
```
|
|
70
164
|
|
|
71
|
-
|
|
165
|
+
### Custom Adapters
|
|
72
166
|
|
|
73
|
-
|
|
167
|
+
Implement ports to integrate with any platform:
|
|
74
168
|
|
|
75
169
|
```typescript
|
|
76
|
-
import {
|
|
77
|
-
|
|
170
|
+
import type { ObservabilityPort, ProviderMetadataPort } from "@jterrazz/intelligence";
|
|
171
|
+
|
|
172
|
+
// Observability adapter (Datadog, etc.)
|
|
173
|
+
class DatadogAdapter implements ObservabilityPort {
|
|
174
|
+
trace(params) { /* ... */ }
|
|
175
|
+
generation(params) { /* ... */ }
|
|
176
|
+
async flush() { /* ... */ }
|
|
177
|
+
async shutdown() { /* ... */ }
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Provider metadata adapter (extract usage/cost)
|
|
181
|
+
class AnthropicMetadataAdapter implements ProviderMetadataPort {
|
|
182
|
+
extract(metadata) {
|
|
183
|
+
return { usage: { ... }, cost: { ... } };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
78
187
|
|
|
79
|
-
|
|
80
|
-
|
|
188
|
+
## Parsing Utilities
|
|
189
|
+
|
|
190
|
+
### `parseObject` - Extract structured data from AI responses
|
|
191
|
+
|
|
192
|
+
Extracts and validates JSON from messy AI outputs (markdown blocks, malformed syntax).
|
|
193
|
+
|
|
194
|
+
````typescript
|
|
195
|
+
import { parseObject } from "@jterrazz/intelligence";
|
|
196
|
+
import { z } from "zod";
|
|
197
|
+
|
|
198
|
+
const schema = z.object({
|
|
199
|
+
title: z.string(),
|
|
200
|
+
tags: z.array(z.string()),
|
|
81
201
|
});
|
|
82
202
|
|
|
203
|
+
const text = '```json\n{"title": "Hello", "tags": ["ai"]}\n```';
|
|
204
|
+
const result = parseObject(text, schema);
|
|
205
|
+
// { title: "Hello", tags: ["ai"] }
|
|
206
|
+
````
|
|
207
|
+
|
|
208
|
+
### `createSchemaPrompt` - Generate schema instructions
|
|
209
|
+
|
|
210
|
+
Creates system prompt instructions for models without native structured output.
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { generateText } from "ai";
|
|
214
|
+
import { createSchemaPrompt, parseObject } from "@jterrazz/intelligence";
|
|
215
|
+
import { z } from "zod";
|
|
216
|
+
|
|
217
|
+
const schema = z.object({ summary: z.string(), score: z.number() });
|
|
218
|
+
|
|
83
219
|
const { text } = await generateText({
|
|
84
|
-
|
|
85
|
-
|
|
220
|
+
model,
|
|
221
|
+
prompt: "Analyze this article...",
|
|
222
|
+
system: createSchemaPrompt(schema),
|
|
86
223
|
});
|
|
224
|
+
|
|
225
|
+
const result = parseObject(text, schema);
|
|
87
226
|
```
|
|
88
227
|
|
|
89
|
-
|
|
228
|
+
### `parseText` - Sanitize AI-generated text
|
|
229
|
+
|
|
230
|
+
Removes invisible characters, normalizes typography, cleans AI artifacts.
|
|
90
231
|
|
|
91
232
|
```typescript
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
233
|
+
import { parseText } from "@jterrazz/intelligence";
|
|
234
|
+
|
|
235
|
+
const clean = parseText(messyAiOutput);
|
|
236
|
+
// Removes: BOM, zero-width chars, citation markers
|
|
237
|
+
// Normalizes: smart quotes, em dashes, ellipsis
|
|
96
238
|
```
|
|
97
239
|
|
|
98
|
-
##
|
|
240
|
+
## Provider
|
|
99
241
|
|
|
100
|
-
### `
|
|
242
|
+
### `createOpenRouterProvider` - OpenRouter for AI SDK
|
|
101
243
|
|
|
102
244
|
```typescript
|
|
103
|
-
import {
|
|
104
|
-
import {
|
|
245
|
+
import { generateText } from "ai";
|
|
246
|
+
import { createOpenRouterProvider } from "@jterrazz/intelligence";
|
|
105
247
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
248
|
+
const provider = createOpenRouterProvider({
|
|
249
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const { text } = await generateText({
|
|
253
|
+
model: provider.model("anthropic/claude-sonnet-4-20250514"),
|
|
254
|
+
prompt: "Hello!",
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// With reasoning models
|
|
258
|
+
const reasoningModel = provider.model("anthropic/claude-sonnet-4-20250514", {
|
|
259
|
+
maxTokens: 16000,
|
|
260
|
+
reasoning: { effort: "high" },
|
|
116
261
|
});
|
|
117
262
|
```
|
|
118
263
|
|
|
119
|
-
|
|
264
|
+
## API Reference
|
|
265
|
+
|
|
266
|
+
### Generation
|
|
267
|
+
|
|
268
|
+
| Export | Description |
|
|
269
|
+
| ----------------------------- | ------------------------------------------------------ |
|
|
270
|
+
| `generateStructured(options)` | Generate and parse structured data with error handling |
|
|
271
|
+
|
|
272
|
+
### Result
|
|
273
|
+
|
|
274
|
+
| Export | Description |
|
|
275
|
+
| ------------------------------------------ | -------------------------------------------------------- |
|
|
276
|
+
| `GenerationResult<T>` | Discriminated union result type |
|
|
277
|
+
| `generationSuccess(data)` | Create success result |
|
|
278
|
+
| `generationFailure(code, message, cause?)` | Create failure result |
|
|
279
|
+
| `isSuccess(result)` | Type guard for success |
|
|
280
|
+
| `isFailure(result)` | Type guard for failure |
|
|
281
|
+
| `unwrap(result)` | Extract data or throw |
|
|
282
|
+
| `unwrapOr(result, default)` | Extract data or return default |
|
|
283
|
+
| `classifyError(error)` | Classify error into error code |
|
|
284
|
+
| `GenerationErrorCode` | Error codes: TIMEOUT, RATE_LIMITED, PARSING_FAILED, etc. |
|
|
285
|
+
|
|
286
|
+
### Middleware
|
|
287
|
+
|
|
288
|
+
| Export | Description |
|
|
289
|
+
| ---------------------------------------- | -------------------------------------------- |
|
|
290
|
+
| `createLoggingMiddleware(options)` | Creates logging middleware |
|
|
291
|
+
| `createObservabilityMiddleware(options)` | Creates observability middleware |
|
|
292
|
+
| `withObservability(meta)` | Helper for type-safe observability metadata |
|
|
293
|
+
| `LangfuseAdapter` | Langfuse implementation of ObservabilityPort |
|
|
294
|
+
| `NoopObservabilityAdapter` | No-op adapter for testing/development |
|
|
295
|
+
| `OpenRouterMetadataAdapter` | Extract usage/cost from OpenRouter |
|
|
296
|
+
|
|
297
|
+
### Ports
|
|
298
|
+
|
|
299
|
+
| Export | Description |
|
|
300
|
+
| ---------------------- | ------------------------------------------ |
|
|
301
|
+
| `ObservabilityPort` | Interface for observability adapters |
|
|
302
|
+
| `ProviderMetadataPort` | Interface for provider metadata extraction |
|
|
303
|
+
|
|
304
|
+
### Parsing
|
|
305
|
+
|
|
306
|
+
| Export | Description |
|
|
307
|
+
| ---------------------------- | ---------------------------------------- |
|
|
308
|
+
| `parseObject(text, schema)` | Parse and validate JSON from AI output |
|
|
309
|
+
| `createSchemaPrompt(schema)` | Generate schema instructions for prompts |
|
|
310
|
+
| `parseText(text, options?)` | Sanitize AI-generated text |
|
|
311
|
+
|
|
312
|
+
### Provider
|
|
313
|
+
|
|
314
|
+
| Export | Description |
|
|
315
|
+
| ---------------------------------- | ------------------------------------- |
|
|
316
|
+
| `createOpenRouterProvider(config)` | Create OpenRouter provider for AI SDK |
|