@jterrazz/intelligence 4.0.3 → 4.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/README.md CHANGED
@@ -15,26 +15,26 @@ npm install @jterrazz/intelligence ai zod
15
15
  Combines `generateText` + `parseObject` + error classification into a single function that returns a discriminated union result.
16
16
 
17
17
  ```typescript
18
- import { generateStructured, withObservability } from "@jterrazz/intelligence";
19
- import { z } from "zod";
18
+ import { generateStructured, withObservability } from '@jterrazz/intelligence';
19
+ import { z } from 'zod';
20
20
 
21
21
  const schema = z.object({
22
- sentiment: z.string(),
23
- score: z.number(),
22
+ sentiment: z.string(),
23
+ score: z.number(),
24
24
  });
25
25
 
26
26
  const result = await generateStructured({
27
- model,
28
- prompt: "Analyze this article...",
29
- schema,
30
- providerOptions: withObservability({ traceId: "trace-123" }),
27
+ model,
28
+ prompt: 'Analyze this article...',
29
+ schema,
30
+ providerOptions: withObservability({ traceId: 'trace-123' }),
31
31
  });
32
32
 
33
33
  if (result.success) {
34
- console.log(result.data.sentiment, result.data.score);
34
+ console.log(result.data.sentiment, result.data.score);
35
35
  } else {
36
- // Typed error with code: TIMEOUT | RATE_LIMITED | PARSING_FAILED | etc.
37
- console.error(result.error.code, result.error.message);
36
+ // Typed error with code: TIMEOUT | RATE_LIMITED | PARSING_FAILED | etc.
37
+ console.error(result.error.code, result.error.message);
38
38
  }
39
39
  ```
40
40
 
@@ -44,23 +44,23 @@ Discriminated union result type for explicit error handling.
44
44
 
45
45
  ```typescript
46
46
  import {
47
- generationSuccess,
48
- generationFailure,
49
- isSuccess,
50
- isFailure,
51
- unwrap,
52
- unwrapOr,
53
- classifyError,
54
- type GenerationResult,
55
- } from "@jterrazz/intelligence";
47
+ generationSuccess,
48
+ generationFailure,
49
+ isSuccess,
50
+ isFailure,
51
+ unwrap,
52
+ unwrapOr,
53
+ classifyError,
54
+ type GenerationResult,
55
+ } from '@jterrazz/intelligence';
56
56
 
57
57
  // Create results
58
- const success = generationSuccess({ data: "value" });
59
- const failure = generationFailure("TIMEOUT", "Request timed out");
58
+ const success = generationSuccess({ data: 'value' });
59
+ const failure = generationFailure('TIMEOUT', 'Request timed out');
60
60
 
61
61
  // Type guards
62
62
  if (isSuccess(result)) {
63
- console.log(result.data);
63
+ console.log(result.data);
64
64
  }
65
65
 
66
66
  // Unwrap with default
@@ -68,9 +68,9 @@ const value = unwrapOr(result, defaultValue);
68
68
 
69
69
  // Classify errors automatically
70
70
  try {
71
- await someOperation();
71
+ await someOperation();
72
72
  } catch (error) {
73
- const code = classifyError(error); // TIMEOUT, RATE_LIMITED, PARSING_FAILED, etc.
73
+ const code = classifyError(error); // TIMEOUT, RATE_LIMITED, PARSING_FAILED, etc.
74
74
  }
75
75
  ```
76
76
 
@@ -81,26 +81,26 @@ Composable middlewares that wrap AI SDK models. Stack them together for logging,
81
81
  ### Composing Middlewares
82
82
 
83
83
  ```typescript
84
- import { wrapLanguageModel } from "ai";
84
+ import { wrapLanguageModel } from 'ai';
85
85
  import {
86
- createLoggingMiddleware,
87
- createObservabilityMiddleware,
88
- LangfuseAdapter,
89
- OpenRouterMetadataAdapter,
90
- } from "@jterrazz/intelligence";
86
+ createLoggingMiddleware,
87
+ createObservabilityMiddleware,
88
+ LangfuseAdapter,
89
+ OpenRouterMetadataAdapter,
90
+ } from '@jterrazz/intelligence';
91
91
 
92
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
- ],
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
+ ],
104
104
  });
105
105
  ```
106
106
 
@@ -109,22 +109,22 @@ const model = wrapLanguageModel({
109
109
  Logs AI SDK requests with timing, usage, and optional content.
110
110
 
111
111
  ```typescript
112
- import { wrapLanguageModel, generateText } from "ai";
113
- import { createLoggingMiddleware } from "@jterrazz/intelligence";
112
+ import { wrapLanguageModel, generateText } from 'ai';
113
+ import { createLoggingMiddleware } from '@jterrazz/intelligence';
114
114
 
115
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
- }),
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
125
  });
126
126
 
127
- await generateText({ model, prompt: "Hello!" });
127
+ await generateText({ model, prompt: 'Hello!' });
128
128
  // Logs: ai.generate.start, ai.generate.complete (with durationMs, usage, etc.)
129
129
  ```
130
130
 
@@ -133,32 +133,32 @@ await generateText({ model, prompt: "Hello!" });
133
133
  Sends generation data to observability platforms (Langfuse, etc.).
134
134
 
135
135
  ```typescript
136
- import { wrapLanguageModel, generateText } from "ai";
136
+ import { wrapLanguageModel, generateText } from 'ai';
137
137
  import {
138
- createObservabilityMiddleware,
139
- withObservability,
140
- LangfuseAdapter,
141
- } from "@jterrazz/intelligence";
138
+ createObservabilityMiddleware,
139
+ withObservability,
140
+ LangfuseAdapter,
141
+ } from '@jterrazz/intelligence';
142
142
 
143
143
  const observability = new LangfuseAdapter({
144
- secretKey: process.env.LANGFUSE_SECRET_KEY,
145
- publicKey: process.env.LANGFUSE_PUBLIC_KEY,
144
+ secretKey: process.env.LANGFUSE_SECRET_KEY,
145
+ publicKey: process.env.LANGFUSE_PUBLIC_KEY,
146
146
  });
147
147
 
148
148
  const model = wrapLanguageModel({
149
- model: provider.model("anthropic/claude-sonnet-4-20250514"),
150
- middleware: createObservabilityMiddleware({ observability }),
149
+ model: provider.model('anthropic/claude-sonnet-4-20250514'),
150
+ middleware: createObservabilityMiddleware({ observability }),
151
151
  });
152
152
 
153
153
  // Use withObservability() helper for type-safe metadata
154
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
- }),
155
+ model,
156
+ prompt: 'Analyze this...',
157
+ providerOptions: withObservability({
158
+ traceId: 'trace-123',
159
+ name: 'analyzer',
160
+ metadata: { userId: 'user-1' },
161
+ }),
162
162
  });
163
163
  ```
164
164
 
@@ -192,12 +192,12 @@ class AnthropicMetadataAdapter implements ProviderMetadataPort {
192
192
  Extracts and validates JSON from messy AI outputs (markdown blocks, malformed syntax).
193
193
 
194
194
  ````typescript
195
- import { parseObject } from "@jterrazz/intelligence";
196
- import { z } from "zod";
195
+ import { parseObject } from '@jterrazz/intelligence';
196
+ import { z } from 'zod';
197
197
 
198
198
  const schema = z.object({
199
- title: z.string(),
200
- tags: z.array(z.string()),
199
+ title: z.string(),
200
+ tags: z.array(z.string()),
201
201
  });
202
202
 
203
203
  const text = '```json\n{"title": "Hello", "tags": ["ai"]}\n```';
@@ -210,16 +210,16 @@ const result = parseObject(text, schema);
210
210
  Creates system prompt instructions for models without native structured output.
211
211
 
212
212
  ```typescript
213
- import { generateText } from "ai";
214
- import { createSchemaPrompt, parseObject } from "@jterrazz/intelligence";
215
- import { z } from "zod";
213
+ import { generateText } from 'ai';
214
+ import { createSchemaPrompt, parseObject } from '@jterrazz/intelligence';
215
+ import { z } from 'zod';
216
216
 
217
217
  const schema = z.object({ summary: z.string(), score: z.number() });
218
218
 
219
219
  const { text } = await generateText({
220
- model,
221
- prompt: "Analyze this article...",
222
- system: createSchemaPrompt(schema),
220
+ model,
221
+ prompt: 'Analyze this article...',
222
+ system: createSchemaPrompt(schema),
223
223
  });
224
224
 
225
225
  const result = parseObject(text, schema);
@@ -230,7 +230,7 @@ const result = parseObject(text, schema);
230
230
  Removes invisible characters, normalizes typography, cleans AI artifacts.
231
231
 
232
232
  ```typescript
233
- import { parseText } from "@jterrazz/intelligence";
233
+ import { parseText } from '@jterrazz/intelligence';
234
234
 
235
235
  const clean = parseText(messyAiOutput);
236
236
  // Removes: BOM, zero-width chars, citation markers
@@ -242,22 +242,22 @@ const clean = parseText(messyAiOutput);
242
242
  ### `createOpenRouterProvider` - OpenRouter for AI SDK
243
243
 
244
244
  ```typescript
245
- import { generateText } from "ai";
246
- import { createOpenRouterProvider } from "@jterrazz/intelligence";
245
+ import { generateText } from 'ai';
246
+ import { createOpenRouterProvider } from '@jterrazz/intelligence';
247
247
 
248
248
  const provider = createOpenRouterProvider({
249
- apiKey: process.env.OPENROUTER_API_KEY,
249
+ apiKey: process.env.OPENROUTER_API_KEY,
250
250
  });
251
251
 
252
252
  const { text } = await generateText({
253
- model: provider.model("anthropic/claude-sonnet-4-20250514"),
254
- prompt: "Hello!",
253
+ model: provider.model('anthropic/claude-sonnet-4-20250514'),
254
+ prompt: 'Hello!',
255
255
  });
256
256
 
257
257
  // With reasoning models
258
- const reasoningModel = provider.model("anthropic/claude-sonnet-4-20250514", {
259
- maxTokens: 16000,
260
- reasoning: { effort: "high" },
258
+ const reasoningModel = provider.model('anthropic/claude-sonnet-4-20250514', {
259
+ maxTokens: 16000,
260
+ reasoning: { effort: 'high' },
261
261
  });
262
262
  ```
263
263
 
package/dist/index.cjs CHANGED
@@ -1,10 +1,11 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_parse_text = require("./parse-text.cjs");
1
3
  let langfuse = require("langfuse");
2
4
  let ai = require("ai");
3
5
  let jsonrepair = require("jsonrepair");
4
6
  let zod_v4 = require("zod/v4");
5
7
  let _openrouter_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
6
8
  let _ai_sdk_openai = require("@ai-sdk/openai");
7
-
8
9
  //#region src/logging/logging.middleware.ts
9
10
  /**
10
11
  * Creates middleware that logs AI SDK requests and responses.
@@ -78,7 +79,6 @@ function createLoggingMiddleware(options) {
78
79
  }
79
80
  };
80
81
  }
81
-
82
82
  //#endregion
83
83
  //#region src/observability/observability.middleware.ts
84
84
  /**
@@ -150,7 +150,6 @@ function createObservabilityMiddleware(options) {
150
150
  }
151
151
  };
152
152
  }
153
-
154
153
  //#endregion
155
154
  //#region src/observability/langfuse.adapter.ts
156
155
  /**
@@ -208,7 +207,6 @@ var LangfuseAdapter = class {
208
207
  });
209
208
  }
210
209
  };
211
-
212
210
  //#endregion
213
211
  //#region src/observability/noop.adapter.ts
214
212
  /**
@@ -221,7 +219,6 @@ var NoopObservabilityAdapter = class {
221
219
  async shutdown() {}
222
220
  trace(_params) {}
223
221
  };
224
-
225
222
  //#endregion
226
223
  //#region src/result/result.ts
227
224
  /**
@@ -284,7 +281,6 @@ function unwrap(result) {
284
281
  function unwrapOr(result, defaultValue) {
285
282
  return result.success ? result.data : defaultValue;
286
283
  }
287
-
288
284
  //#endregion
289
285
  //#region src/parsing/parse-object.ts
290
286
  const MARKDOWN_CODE_BLOCK_RE = /```(?:json)?\r?\n([^`]*?)\r?\n```/g;
@@ -294,6 +290,8 @@ const MARKDOWN_CODE_BLOCK_RE = /```(?:json)?\r?\n([^`]*?)\r?\n```/g;
294
290
  */
295
291
  var ParseObjectError = class extends Error {
296
292
  name = "ParseObjectError";
293
+ cause;
294
+ text;
297
295
  constructor(message, cause, text) {
298
296
  super(message);
299
297
  this.cause = cause;
@@ -435,7 +433,6 @@ function parseObject(text, schema) {
435
433
  throw error;
436
434
  }
437
435
  }
438
-
439
436
  //#endregion
440
437
  //#region src/generation/generate-structured.ts
441
438
  /**
@@ -465,7 +462,6 @@ async function generateStructured(options) {
465
462
  return generationFailure(classifyError(error), error instanceof Error ? error.message : "Unknown error", error);
466
463
  }
467
464
  }
468
-
469
465
  //#endregion
470
466
  //#region src/parsing/create-schema-prompt.ts
471
467
  /**
@@ -521,57 +517,6 @@ ${schemaJson}
521
517
  Your response must be parseable JSON that validates against this schema. Do not include any text outside the JSON.
522
518
  </OUTPUT_FORMAT>`;
523
519
  }
524
-
525
- //#endregion
526
- //#region src/parsing/parse-text.ts
527
- const INVISIBLE_CHARS_RE = /[\u00AD\u180E\u200B-\u200C\u200E-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/g;
528
- const ASCII_CTRL_RE = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g;
529
- const SPACE_LIKE_RE = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
530
- const MULTIPLE_SPACES_RE = / {2,}/g;
531
- const CR_RE = /\r\n?/g;
532
- const CITATION_RE = / *\(oaicite:\d+\)\{index=\d+\}/g;
533
- const EM_DASH_SEPARATOR_RE = /\s*[—–―‒]\s*/g;
534
- const TYPOGRAPHY_REPLACEMENTS = [
535
- {
536
- pattern: /[\u2018\u2019\u201A]/g,
537
- replacement: "'"
538
- },
539
- {
540
- pattern: /[\u201C\u201D\u201E]/g,
541
- replacement: "\""
542
- },
543
- {
544
- pattern: /\u2026/g,
545
- replacement: "..."
546
- },
547
- {
548
- pattern: /[\u2022\u25AA-\u25AB\u25B8-\u25B9\u25CF]/g,
549
- replacement: "-"
550
- }
551
- ];
552
- /**
553
- * Parses and sanitizes text by removing AI artifacts and normalizing typography.
554
- *
555
- * @param text - The text to parse
556
- * @param options - Parsing options
557
- * @returns The cleaned text
558
- */
559
- function parseText(text, options = {}) {
560
- const { normalizeEmDashesToCommas = true, collapseSpaces = true } = options;
561
- if (!text) return "";
562
- let result = text;
563
- result = result.replace(CR_RE, "\n");
564
- result = result.replace(CITATION_RE, "");
565
- result = result.normalize("NFKC");
566
- result = result.replace(INVISIBLE_CHARS_RE, "");
567
- result = result.replace(ASCII_CTRL_RE, "");
568
- if (normalizeEmDashesToCommas) result = result.replace(EM_DASH_SEPARATOR_RE, ", ");
569
- result = result.replace(SPACE_LIKE_RE, " ");
570
- for (const { pattern, replacement } of TYPOGRAPHY_REPLACEMENTS) result = result.replace(pattern, replacement);
571
- if (collapseSpaces) result = result.replace(MULTIPLE_SPACES_RE, " ").trim();
572
- return result;
573
- }
574
-
575
520
  //#endregion
576
521
  //#region src/provider/openrouter.provider.ts
577
522
  /**
@@ -594,7 +539,6 @@ function createOpenRouterProvider(config) {
594
539
  });
595
540
  } };
596
541
  }
597
-
598
542
  //#endregion
599
543
  //#region src/provider/openrouter-metadata.adapter.ts
600
544
  /**
@@ -617,7 +561,6 @@ var OpenRouterMetadataAdapter = class {
617
561
  };
618
562
  }
619
563
  };
620
-
621
564
  //#endregion
622
565
  //#region src/provider/openai-compatible.provider.ts
623
566
  /**
@@ -633,7 +576,6 @@ function createOpenAICompatibleProvider(config) {
633
576
  return openai(config.modelMapping?.[name] ?? name);
634
577
  } };
635
578
  }
636
-
637
579
  //#endregion
638
580
  //#region src/provider/openai-compatible-metadata.adapter.ts
639
581
  /**
@@ -652,7 +594,6 @@ var OpenAICompatibleMetadataAdapter = class {
652
594
  } };
653
595
  }
654
596
  };
655
-
656
597
  //#endregion
657
598
  exports.LangfuseAdapter = LangfuseAdapter;
658
599
  exports.NoopObservabilityAdapter = NoopObservabilityAdapter;
@@ -671,8 +612,9 @@ exports.generationSuccess = generationSuccess;
671
612
  exports.isFailure = isFailure;
672
613
  exports.isSuccess = isSuccess;
673
614
  exports.parseObject = parseObject;
674
- exports.parseText = parseText;
615
+ exports.parseText = require_parse_text.parseText;
675
616
  exports.unwrap = unwrap;
676
617
  exports.unwrapOr = unwrapOr;
677
618
  exports.withObservability = withObservability;
619
+
678
620
  //# sourceMappingURL=index.cjs.map