@jterrazz/intelligence 3.0.1 → 4.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.
Files changed (34) hide show
  1. package/README.md +259 -55
  2. package/dist/index.cjs +594 -783
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +352 -5
  5. package/dist/index.js +620 -5
  6. package/dist/index.js.map +1 -1
  7. package/package.json +26 -20
  8. package/dist/middleware/__tests__/logging.middleware.test.d.ts +0 -1
  9. package/dist/middleware/__tests__/logging.middleware.test.js +0 -390
  10. package/dist/middleware/__tests__/logging.middleware.test.js.map +0 -1
  11. package/dist/middleware/logging.middleware.d.ts +0 -21
  12. package/dist/middleware/logging.middleware.js +0 -296
  13. package/dist/middleware/logging.middleware.js.map +0 -1
  14. package/dist/parsing/__tests__/create-schema-prompt.test.d.ts +0 -1
  15. package/dist/parsing/__tests__/create-schema-prompt.test.js +0 -53
  16. package/dist/parsing/__tests__/create-schema-prompt.test.js.map +0 -1
  17. package/dist/parsing/__tests__/parse-object.test.d.ts +0 -1
  18. package/dist/parsing/__tests__/parse-object.test.js +0 -193
  19. package/dist/parsing/__tests__/parse-object.test.js.map +0 -1
  20. package/dist/parsing/__tests__/parse-text.test.d.ts +0 -1
  21. package/dist/parsing/__tests__/parse-text.test.js +0 -167
  22. package/dist/parsing/__tests__/parse-text.test.js.map +0 -1
  23. package/dist/parsing/create-schema-prompt.d.ts +0 -28
  24. package/dist/parsing/create-schema-prompt.js +0 -42
  25. package/dist/parsing/create-schema-prompt.js.map +0 -1
  26. package/dist/parsing/parse-object.d.ts +0 -33
  27. package/dist/parsing/parse-object.js +0 -360
  28. package/dist/parsing/parse-object.js.map +0 -1
  29. package/dist/parsing/parse-text.d.ts +0 -14
  30. package/dist/parsing/parse-text.js +0 -76
  31. package/dist/parsing/parse-text.js.map +0 -1
  32. package/dist/providers/openrouter.provider.d.ts +0 -36
  33. package/dist/providers/openrouter.provider.js +0 -58
  34. package/dist/providers/openrouter.provider.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,829 +1,640 @@
1
- 'use strict';
1
+ let langfuse = require("langfuse");
2
+ let ai = require("ai");
3
+ let jsonrepair = require("jsonrepair");
4
+ let zod_v4 = require("zod/v4");
5
+ let _openrouter_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
2
6
 
3
- var v4 = require('zod/v4');
4
- var jsonrepair = require('jsonrepair');
5
- var aiSdkProvider = require('@openrouter/ai-sdk-provider');
6
-
7
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
8
- try {
9
- var info = gen[key](arg);
10
- var value = info.value;
11
- } catch (error) {
12
- reject(error);
13
- return;
14
- }
15
- if (info.done) {
16
- resolve(value);
17
- } else {
18
- Promise.resolve(value).then(_next, _throw);
19
- }
20
- }
21
- function _async_to_generator(fn) {
22
- return function() {
23
- var self = this, args = arguments;
24
- return new Promise(function(resolve, reject) {
25
- var gen = fn.apply(self, args);
26
- function _next(value) {
27
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
28
- }
29
- function _throw(err) {
30
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
31
- }
32
- _next(undefined);
33
- });
34
- };
35
- }
36
- function _define_property$2(obj, key, value) {
37
- if (key in obj) {
38
- Object.defineProperty(obj, key, {
39
- value: value,
40
- enumerable: true,
41
- configurable: true,
42
- writable: true
43
- });
44
- } else {
45
- obj[key] = value;
46
- }
47
- return obj;
48
- }
49
- function _instanceof$1(left, right) {
50
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
51
- return !!right[Symbol.hasInstance](left);
52
- } else {
53
- return left instanceof right;
54
- }
55
- }
56
- function _object_spread$1(target) {
57
- for(var i = 1; i < arguments.length; i++){
58
- var source = arguments[i] != null ? arguments[i] : {};
59
- var ownKeys = Object.keys(source);
60
- if (typeof Object.getOwnPropertySymbols === "function") {
61
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
62
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
63
- }));
64
- }
65
- ownKeys.forEach(function(key) {
66
- _define_property$2(target, key, source[key]);
67
- });
68
- }
69
- return target;
70
- }
71
- function ownKeys(object, enumerableOnly) {
72
- var keys = Object.keys(object);
73
- if (Object.getOwnPropertySymbols) {
74
- var symbols = Object.getOwnPropertySymbols(object);
75
- keys.push.apply(keys, symbols);
76
- }
77
- return keys;
78
- }
79
- function _object_spread_props(target, source) {
80
- source = source != null ? source : {};
81
- if (Object.getOwnPropertyDescriptors) {
82
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
83
- } else {
84
- ownKeys(Object(source)).forEach(function(key) {
85
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
86
- });
87
- }
88
- return target;
7
+ //#region src/logging/logging.middleware.ts
8
+ /**
9
+ * Creates middleware that logs AI SDK requests and responses.
10
+ */
11
+ function createLoggingMiddleware(options) {
12
+ const { logger, include = {} } = options;
13
+ const { params: includeParams, content: includeContent, usage: includeUsage = true } = include;
14
+ return {
15
+ specificationVersion: "v3",
16
+ wrapGenerate: async ({ doGenerate, params, model }) => {
17
+ const startTime = Date.now();
18
+ logger.debug("ai.generate.start", {
19
+ model: model.modelId,
20
+ ...includeParams && { params }
21
+ });
22
+ try {
23
+ const result = await doGenerate();
24
+ const textContent = result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
25
+ logger.debug("ai.generate.complete", {
26
+ model: model.modelId,
27
+ durationMs: Date.now() - startTime,
28
+ finishReason: result.finishReason,
29
+ ...includeUsage && { usage: result.usage },
30
+ ...includeContent && { content: textContent }
31
+ });
32
+ return result;
33
+ } catch (error) {
34
+ logger.error("ai.generate.error", {
35
+ model: model.modelId,
36
+ durationMs: Date.now() - startTime,
37
+ error: error instanceof Error ? error.message : "Unknown error"
38
+ });
39
+ throw error;
40
+ }
41
+ },
42
+ wrapStream: async ({ doStream, params, model }) => {
43
+ const startTime = Date.now();
44
+ logger.debug("ai.stream.start", {
45
+ model: model.modelId,
46
+ ...includeParams && { params }
47
+ });
48
+ try {
49
+ const result = await doStream();
50
+ const chunks = [];
51
+ const transformStream = new TransformStream({
52
+ transform(chunk, controller) {
53
+ if (includeContent && chunk.type === "text-delta") chunks.push(chunk.delta);
54
+ controller.enqueue(chunk);
55
+ },
56
+ flush() {
57
+ logger.debug("ai.stream.complete", {
58
+ model: model.modelId,
59
+ durationMs: Date.now() - startTime,
60
+ ...includeContent && { content: chunks.join("") }
61
+ });
62
+ }
63
+ });
64
+ return {
65
+ specificationVersion: "v3",
66
+ ...result,
67
+ stream: result.stream.pipeThrough(transformStream)
68
+ };
69
+ } catch (error) {
70
+ logger.error("ai.stream.error", {
71
+ model: model.modelId,
72
+ durationMs: Date.now() - startTime,
73
+ error: error instanceof Error ? error.message : "Unknown error"
74
+ });
75
+ throw error;
76
+ }
77
+ }
78
+ };
89
79
  }
90
- function _ts_generator(thisArg, body) {
91
- var f, y, t, _ = {
92
- label: 0,
93
- sent: function() {
94
- if (t[0] & 1) throw t[1];
95
- return t[1];
96
- },
97
- trys: [],
98
- ops: []
99
- }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
100
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
101
- return this;
102
- }), g;
103
- function verb(n) {
104
- return function(v) {
105
- return step([
106
- n,
107
- v
108
- ]);
109
- };
110
- }
111
- function step(op) {
112
- if (f) throw new TypeError("Generator is already executing.");
113
- while(g && (g = 0, op[0] && (_ = 0)), _)try {
114
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
115
- if (y = 0, t) op = [
116
- op[0] & 2,
117
- t.value
118
- ];
119
- switch(op[0]){
120
- case 0:
121
- case 1:
122
- t = op;
123
- break;
124
- case 4:
125
- _.label++;
126
- return {
127
- value: op[1],
128
- done: false
129
- };
130
- case 5:
131
- _.label++;
132
- y = op[1];
133
- op = [
134
- 0
135
- ];
136
- continue;
137
- case 7:
138
- op = _.ops.pop();
139
- _.trys.pop();
140
- continue;
141
- default:
142
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
143
- _ = 0;
144
- continue;
145
- }
146
- if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
147
- _.label = op[1];
148
- break;
149
- }
150
- if (op[0] === 6 && _.label < t[1]) {
151
- _.label = t[1];
152
- t = op;
153
- break;
154
- }
155
- if (t && _.label < t[2]) {
156
- _.label = t[2];
157
- _.ops.push(op);
158
- break;
159
- }
160
- if (t[2]) _.ops.pop();
161
- _.trys.pop();
162
- continue;
163
- }
164
- op = body.call(thisArg, _);
165
- } catch (e) {
166
- op = [
167
- 6,
168
- e
169
- ];
170
- y = 0;
171
- } finally{
172
- f = t = 0;
173
- }
174
- if (op[0] & 5) throw op[1];
175
- return {
176
- value: op[0] ? op[1] : void 0,
177
- done: true
178
- };
179
- }
80
+
81
+ //#endregion
82
+ //#region src/observability/observability.middleware.ts
83
+ /**
84
+ * Helper to create type-safe observability metadata for providerOptions
85
+ */
86
+ function withObservability(meta) {
87
+ return { observability: meta };
180
88
  }
181
89
  /**
182
- * Creates AI SDK middleware that logs model requests and responses.
183
- *
184
- * @example
185
- * ```ts
186
- * import { wrapLanguageModel } from 'ai';
187
- *
188
- * const model = wrapLanguageModel({
189
- * model: openrouter('anthropic/claude-sonnet-4-20250514'),
190
- * middleware: createLoggingMiddleware({ logger }),
191
- * });
192
- * ```
193
- */ function createLoggingMiddleware(options) {
194
- var logger = options.logger, _options_verbose = options.verbose, verbose = _options_verbose === void 0 ? false : _options_verbose;
195
- return {
196
- middlewareVersion: 'v2',
197
- wrapGenerate: function(param) {
198
- var doGenerate = param.doGenerate, params = param.params;
199
- return _async_to_generator(function() {
200
- var startTime, result, error;
201
- return _ts_generator(this, function(_state) {
202
- switch(_state.label){
203
- case 0:
204
- startTime = Date.now();
205
- logger.debug('Model request started', _object_spread$1({}, verbose && {
206
- params: params
207
- }));
208
- _state.label = 1;
209
- case 1:
210
- _state.trys.push([
211
- 1,
212
- 3,
213
- ,
214
- 4
215
- ]);
216
- return [
217
- 4,
218
- doGenerate()
219
- ];
220
- case 2:
221
- result = _state.sent();
222
- logger.debug('Model request completed', _object_spread$1({
223
- durationMs: Date.now() - startTime,
224
- finishReason: result.finishReason,
225
- usage: result.usage
226
- }, verbose && {
227
- content: result.content
228
- }));
229
- return [
230
- 2,
231
- result
232
- ];
233
- case 3:
234
- error = _state.sent();
235
- logger.error('Model request failed', {
236
- durationMs: Date.now() - startTime,
237
- error: _instanceof$1(error, Error) ? error.message : 'Unknown error'
238
- });
239
- throw error;
240
- case 4:
241
- return [
242
- 2
243
- ];
244
- }
245
- });
246
- })();
247
- },
248
- wrapStream: function(param) {
249
- var doStream = param.doStream, params = param.params;
250
- return _async_to_generator(function() {
251
- var startTime, result, error;
252
- return _ts_generator(this, function(_state) {
253
- switch(_state.label){
254
- case 0:
255
- startTime = Date.now();
256
- logger.debug('Model stream started', _object_spread$1({}, verbose && {
257
- params: params
258
- }));
259
- _state.label = 1;
260
- case 1:
261
- _state.trys.push([
262
- 1,
263
- 3,
264
- ,
265
- 4
266
- ]);
267
- return [
268
- 4,
269
- doStream()
270
- ];
271
- case 2:
272
- result = _state.sent();
273
- return [
274
- 2,
275
- _object_spread_props(_object_spread$1({}, result), {
276
- stream: result.stream
277
- })
278
- ];
279
- case 3:
280
- error = _state.sent();
281
- logger.error('Model stream failed', {
282
- durationMs: Date.now() - startTime,
283
- error: _instanceof$1(error, Error) ? error.message : 'Unknown error'
284
- });
285
- throw error;
286
- case 4:
287
- return [
288
- 2
289
- ];
290
- }
291
- });
292
- })();
293
- }
294
- };
90
+ * Creates middleware that sends generation data to an observability platform.
91
+ */
92
+ function createObservabilityMiddleware(options) {
93
+ const { observability, providerMetadata } = options;
94
+ return {
95
+ specificationVersion: "v3",
96
+ wrapGenerate: async ({ doGenerate, params, model }) => {
97
+ const startTime = /* @__PURE__ */ new Date();
98
+ const meta = params.providerOptions?.observability;
99
+ const result = await doGenerate();
100
+ const endTime = /* @__PURE__ */ new Date();
101
+ if (meta?.traceId) {
102
+ const extracted = providerMetadata?.extract(result.providerMetadata);
103
+ const outputText = result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
104
+ observability.generation({
105
+ traceId: meta.traceId,
106
+ name: meta.name ?? "generation",
107
+ model: model.modelId,
108
+ input: params.prompt,
109
+ output: outputText,
110
+ startTime,
111
+ endTime,
112
+ usage: extracted?.usage,
113
+ cost: extracted?.cost,
114
+ metadata: meta.metadata
115
+ });
116
+ }
117
+ return result;
118
+ },
119
+ wrapStream: async ({ doStream, params, model }) => {
120
+ const startTime = /* @__PURE__ */ new Date();
121
+ const meta = params.providerOptions?.observability;
122
+ const result = await doStream();
123
+ if (!meta?.traceId) return result;
124
+ const chunks = [];
125
+ const transformStream = new TransformStream({
126
+ transform(chunk, controller) {
127
+ if (chunk.type === "text-delta") chunks.push(chunk.delta);
128
+ controller.enqueue(chunk);
129
+ },
130
+ flush() {
131
+ const endTime = /* @__PURE__ */ new Date();
132
+ observability.generation({
133
+ traceId: meta.traceId,
134
+ name: meta.name ?? "generation",
135
+ model: model.modelId,
136
+ input: params.prompt,
137
+ output: chunks.join(""),
138
+ startTime,
139
+ endTime,
140
+ metadata: meta.metadata
141
+ });
142
+ }
143
+ });
144
+ return {
145
+ specificationVersion: "v3",
146
+ ...result,
147
+ stream: result.stream.pipeThrough(transformStream)
148
+ };
149
+ }
150
+ };
295
151
  }
296
152
 
153
+ //#endregion
154
+ //#region src/observability/langfuse.adapter.ts
297
155
  /**
298
- * Creates a system prompt that instructs the model to output structured data
299
- * matching the provided Zod schema.
300
- *
301
- * Use this with `generateText` when the provider doesn't support native
302
- * structured outputs, then parse the response with `parseObject`.
303
- *
304
- * @param schema - A Zod schema defining the expected output structure
305
- * @returns A system prompt string with JSON schema instructions
306
- *
307
- * @example
308
- * ```ts
309
- * import { generateText } from 'ai';
310
- * import { createSchemaPrompt, parseObject } from '@jterrazz/intelligence';
311
- *
312
- * const schema = z.object({ title: z.string(), tags: z.array(z.string()) });
313
- *
314
- * const { text } = await generateText({
315
- * model,
316
- * prompt: 'Generate an article about TypeScript',
317
- * system: createSchemaPrompt(schema),
318
- * });
319
- *
320
- * const result = parseObject(text, schema);
321
- * ```
322
- */ function createSchemaPrompt(schema) {
323
- var jsonSchema = v4.z.toJSONSchema(schema);
324
- var schemaJson = JSON.stringify(jsonSchema, null, 2);
325
- var isPrimitive = [
326
- 'boolean',
327
- 'integer',
328
- 'number',
329
- 'string'
330
- ].includes(jsonSchema.type);
331
- if (isPrimitive) {
332
- return "<OUTPUT_FORMAT>\nYou must respond with a ".concat(jsonSchema.type, " value that matches this schema:\n\n```json\n").concat(schemaJson, "\n```\n\nYour response should be only the ").concat(jsonSchema.type, " value, without any JSON wrapping or additional text.\n</OUTPUT_FORMAT>");
333
- }
334
- return "<OUTPUT_FORMAT>\nYou must respond with valid JSON that matches this JSON schema:\n\n```json\n".concat(schemaJson, "\n```\n\nYour response must be parseable JSON that validates against this schema. Do not include any text outside the JSON.\n</OUTPUT_FORMAT>");
335
- }
156
+ * Langfuse adapter implementing ObservabilityPort
157
+ */
158
+ var LangfuseAdapter = class {
159
+ client;
160
+ constructor(config) {
161
+ this.client = new langfuse.Langfuse({
162
+ secretKey: config.secretKey,
163
+ publicKey: config.publicKey,
164
+ baseUrl: config.baseUrl,
165
+ environment: config.environment,
166
+ release: config.release
167
+ });
168
+ }
169
+ async flush() {
170
+ await this.client.flushAsync();
171
+ }
172
+ generation(params) {
173
+ const usageDetails = params.usage ? {
174
+ input: params.usage.input,
175
+ output: params.usage.output,
176
+ total: params.usage.total ?? params.usage.input + params.usage.output,
177
+ ...params.usage.reasoning !== void 0 && { reasoning: params.usage.reasoning },
178
+ ...params.usage.cacheRead !== void 0 && { cache_read: params.usage.cacheRead },
179
+ ...params.usage.cacheWrite !== void 0 && { cache_write: params.usage.cacheWrite }
180
+ } : void 0;
181
+ const costDetails = params.cost ? {
182
+ total: params.cost.total,
183
+ ...params.cost.input !== void 0 && { input: params.cost.input },
184
+ ...params.cost.output !== void 0 && { output: params.cost.output }
185
+ } : void 0;
186
+ this.client.generation({
187
+ traceId: params.traceId,
188
+ name: params.name,
189
+ model: params.model,
190
+ input: params.input,
191
+ output: params.output,
192
+ startTime: params.startTime,
193
+ endTime: params.endTime,
194
+ usageDetails,
195
+ costDetails,
196
+ metadata: params.metadata
197
+ });
198
+ }
199
+ async shutdown() {
200
+ await this.client.shutdownAsync();
201
+ }
202
+ trace(params) {
203
+ this.client.trace({
204
+ id: params.id,
205
+ name: params.name,
206
+ metadata: params.metadata
207
+ });
208
+ }
209
+ };
336
210
 
337
- function _array_like_to_array(arr, len) {
338
- if (len == null || len > arr.length) len = arr.length;
339
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
340
- return arr2;
341
- }
342
- function _array_with_holes(arr) {
343
- if (Array.isArray(arr)) return arr;
344
- }
345
- function _assert_this_initialized(self) {
346
- if (self === void 0) {
347
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
348
- }
349
- return self;
350
- }
351
- function _call_super(_this, derived, args) {
352
- derived = _get_prototype_of(derived);
353
- return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
354
- }
355
- function _class_call_check(instance, Constructor) {
356
- if (!(instance instanceof Constructor)) {
357
- throw new TypeError("Cannot call a class as a function");
358
- }
359
- }
360
- function _construct(Parent, args, Class) {
361
- if (_is_native_reflect_construct()) {
362
- _construct = Reflect.construct;
363
- } else {
364
- _construct = function construct(Parent, args, Class) {
365
- var a = [
366
- null
367
- ];
368
- a.push.apply(a, args);
369
- var Constructor = Function.bind.apply(Parent, a);
370
- var instance = new Constructor();
371
- if (Class) _set_prototype_of(instance, Class.prototype);
372
- return instance;
373
- };
374
- }
375
- return _construct.apply(null, arguments);
376
- }
377
- function _define_property$1(obj, key, value) {
378
- if (key in obj) {
379
- Object.defineProperty(obj, key, {
380
- value: value,
381
- enumerable: true,
382
- configurable: true,
383
- writable: true
384
- });
385
- } else {
386
- obj[key] = value;
387
- }
388
- return obj;
389
- }
390
- function _get_prototype_of(o) {
391
- _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
392
- return o.__proto__ || Object.getPrototypeOf(o);
393
- };
394
- return _get_prototype_of(o);
395
- }
396
- function _inherits(subClass, superClass) {
397
- if (typeof superClass !== "function" && superClass !== null) {
398
- throw new TypeError("Super expression must either be null or a function");
399
- }
400
- subClass.prototype = Object.create(superClass && superClass.prototype, {
401
- constructor: {
402
- value: subClass,
403
- writable: true,
404
- configurable: true
405
- }
406
- });
407
- if (superClass) _set_prototype_of(subClass, superClass);
408
- }
409
- function _instanceof(left, right) {
410
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
411
- return !!right[Symbol.hasInstance](left);
412
- } else {
413
- return left instanceof right;
414
- }
415
- }
416
- function _is_native_function(fn) {
417
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
418
- }
419
- function _iterable_to_array_limit(arr, i) {
420
- var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
421
- if (_i == null) return;
422
- var _arr = [];
423
- var _n = true;
424
- var _d = false;
425
- var _s, _e;
426
- try {
427
- for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
428
- _arr.push(_s.value);
429
- if (i && _arr.length === i) break;
430
- }
431
- } catch (err) {
432
- _d = true;
433
- _e = err;
434
- } finally{
435
- try {
436
- if (!_n && _i["return"] != null) _i["return"]();
437
- } finally{
438
- if (_d) throw _e;
439
- }
440
- }
441
- return _arr;
442
- }
443
- function _non_iterable_rest() {
444
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
445
- }
446
- function _possible_constructor_return(self, call) {
447
- if (call && (_type_of(call) === "object" || typeof call === "function")) {
448
- return call;
449
- }
450
- return _assert_this_initialized(self);
451
- }
452
- function _set_prototype_of(o, p) {
453
- _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
454
- o.__proto__ = p;
455
- return o;
456
- };
457
- return _set_prototype_of(o, p);
458
- }
459
- function _sliced_to_array(arr, i) {
460
- return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
211
+ //#endregion
212
+ //#region src/observability/noop.adapter.ts
213
+ /**
214
+ * No-op adapter that silently discards all observability data.
215
+ * Useful for testing, development, or when observability is disabled.
216
+ */
217
+ var NoopObservabilityAdapter = class {
218
+ async flush() {}
219
+ generation(_params) {}
220
+ async shutdown() {}
221
+ trace(_params) {}
222
+ };
223
+
224
+ //#endregion
225
+ //#region src/result/result.ts
226
+ /**
227
+ * Create a successful result
228
+ */
229
+ function generationSuccess(data) {
230
+ return {
231
+ success: true,
232
+ data
233
+ };
461
234
  }
462
- function _type_of(obj) {
463
- "@swc/helpers - typeof";
464
- return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
235
+ /**
236
+ * Create a failed result
237
+ */
238
+ function generationFailure(code, message, cause) {
239
+ return {
240
+ success: false,
241
+ error: {
242
+ code,
243
+ message,
244
+ cause
245
+ }
246
+ };
465
247
  }
466
- function _unsupported_iterable_to_array(o, minLen) {
467
- if (!o) return;
468
- if (typeof o === "string") return _array_like_to_array(o, minLen);
469
- var n = Object.prototype.toString.call(o).slice(8, -1);
470
- if (n === "Object" && o.constructor) n = o.constructor.name;
471
- if (n === "Map" || n === "Set") return Array.from(n);
472
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
248
+ /**
249
+ * Classify an error into a GenerationErrorCode
250
+ */
251
+ function classifyError(error) {
252
+ if (error instanceof Error) {
253
+ const message = error.message.toLowerCase();
254
+ if (message.includes("timeout") || message.includes("timed out")) return "TIMEOUT";
255
+ if (message.includes("rate limit") || message.includes("429")) return "RATE_LIMITED";
256
+ if (message.includes("parse") || message.includes("json") || message.includes("unexpected token")) return "PARSING_FAILED";
257
+ if (message.includes("valid") || message.includes("schema") || message.includes("zod")) return "VALIDATION_FAILED";
258
+ }
259
+ return "AI_GENERATION_FAILED";
473
260
  }
474
- function _wrap_native_super(Class) {
475
- var _cache = typeof Map === "function" ? new Map() : undefined;
476
- _wrap_native_super = function wrapNativeSuper(Class) {
477
- if (Class === null || !_is_native_function(Class)) return Class;
478
- if (typeof Class !== "function") {
479
- throw new TypeError("Super expression must either be null or a function");
480
- }
481
- if (typeof _cache !== "undefined") {
482
- if (_cache.has(Class)) return _cache.get(Class);
483
- _cache.set(Class, Wrapper);
484
- }
485
- function Wrapper() {
486
- return _construct(Class, arguments, _get_prototype_of(this).constructor);
487
- }
488
- Wrapper.prototype = Object.create(Class.prototype, {
489
- constructor: {
490
- value: Wrapper,
491
- enumerable: false,
492
- writable: true,
493
- configurable: true
494
- }
495
- });
496
- return _set_prototype_of(Wrapper, Class);
497
- };
498
- return _wrap_native_super(Class);
261
+ /**
262
+ * Check if a result is successful (type guard)
263
+ */
264
+ function isSuccess(result) {
265
+ return result.success;
499
266
  }
500
- function _is_native_reflect_construct() {
501
- try {
502
- var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
503
- } catch (_) {}
504
- return (_is_native_reflect_construct = function() {
505
- return !!result;
506
- })();
267
+ /**
268
+ * Check if a result is a failure (type guard)
269
+ */
270
+ function isFailure(result) {
271
+ return !result.success;
507
272
  }
508
273
  /**
509
- * Error thrown when object parsing fails.
510
- * Contains the original text for debugging purposes.
511
- */ var ParseObjectError = /*#__PURE__*/ function(Error1) {
512
- _inherits(ParseObjectError, Error1);
513
- function ParseObjectError(message, cause, text) {
514
- _class_call_check(this, ParseObjectError);
515
- var _this;
516
- _this = _call_super(this, ParseObjectError, [
517
- message
518
- ]), _define_property$1(_this, "cause", void 0), _define_property$1(_this, "text", void 0), _define_property$1(_this, "name", void 0), _this.cause = cause, _this.text = text, _this.name = 'ParseObjectError';
519
- return _this;
520
- }
521
- return ParseObjectError;
522
- }(_wrap_native_super(Error));
274
+ * Unwrap a result, throwing if it fails
275
+ */
276
+ function unwrap(result) {
277
+ if (result.success) return result.data;
278
+ throw new Error(`${result.error.code}: ${result.error.message}`);
279
+ }
523
280
  /**
524
- * Parses AI-generated text into structured data validated against a Zod schema.
525
- *
526
- * Handles common AI response formats:
527
- * - JSON wrapped in markdown code blocks
528
- * - JSON embedded in prose text
529
- * - Malformed JSON (auto-repaired)
530
- * - Escaped unicode and special characters
531
- *
532
- * @param text - The raw AI response text
533
- * @param schema - A Zod schema to validate and type the result
534
- * @returns The parsed and validated data
535
- * @throws {ParseObjectError} When parsing or validation fails
536
- *
537
- * @example
538
- * ```ts
539
- * const schema = z.object({ title: z.string(), tags: z.array(z.string()) });
540
- * const result = parseObject(aiResponse, schema);
541
- * // result is typed as { title: string; tags: string[] }
542
- * ```
543
- */ function parseObject(text, schema) {
544
- try {
545
- var jsonString = extractJsonString(text);
546
- var extracted = extractBySchemaType(jsonString, schema, text);
547
- var unescaped = unescapeJsonValues(extracted);
548
- return schema.parse(unescaped);
549
- } catch (error) {
550
- if (_instanceof(error, ParseObjectError)) {
551
- throw error;
552
- }
553
- if (_instanceof(error, v4.z.ZodError)) {
554
- throw new ParseObjectError('Failed to validate response against schema', error, text);
555
- }
556
- throw error;
557
- }
281
+ * Unwrap a result with a default value for failures
282
+ */
283
+ function unwrapOr(result, defaultValue) {
284
+ return result.success ? result.data : defaultValue;
558
285
  }
559
- var MARKDOWN_CODE_BLOCK_RE = /```(?:json)?\r?\n([^`]*?)\r?\n```/g;
286
+
287
+ //#endregion
288
+ //#region src/parsing/parse-object.ts
289
+ const MARKDOWN_CODE_BLOCK_RE = /```(?:json)?\r?\n([^`]*?)\r?\n```/g;
290
+ /**
291
+ * Error thrown when object parsing fails.
292
+ * Contains the original text for debugging purposes.
293
+ */
294
+ var ParseObjectError = class extends Error {
295
+ name = "ParseObjectError";
296
+ constructor(message, cause, text) {
297
+ super(message);
298
+ this.cause = cause;
299
+ this.text = text;
300
+ }
301
+ };
560
302
  function convertToPrimitive(value, schema) {
561
- if (_instanceof(schema, v4.z.ZodBoolean)) return Boolean(value);
562
- if (_instanceof(schema, v4.z.ZodNull)) return null;
563
- if (_instanceof(schema, v4.z.ZodNumber)) return Number(value);
564
- if (_instanceof(schema, v4.z.ZodString)) return String(value);
565
- return value;
303
+ if (schema instanceof zod_v4.z.ZodBoolean) return Boolean(value);
304
+ if (schema instanceof zod_v4.z.ZodNull) return null;
305
+ if (schema instanceof zod_v4.z.ZodNumber) return Number(value);
306
+ if (schema instanceof zod_v4.z.ZodString) return String(value);
307
+ return value;
566
308
  }
567
309
  function extractArray(text, originalText) {
568
- var start = text.indexOf('[');
569
- var end = text.lastIndexOf(']');
570
- if (start === -1 || end === -1) {
571
- throw new ParseObjectError('No array found in response', undefined, originalText);
572
- }
573
- try {
574
- var raw = text.slice(start, end + 1);
575
- return JSON.parse(jsonrepair.jsonrepair(raw));
576
- } catch (error) {
577
- throw new ParseObjectError('Failed to parse array JSON', error, originalText);
578
- }
310
+ const start = text.indexOf("[");
311
+ const end = text.lastIndexOf("]");
312
+ if (start === -1 || end === -1) throw new ParseObjectError("No array found in response", void 0, originalText);
313
+ try {
314
+ const raw = text.slice(start, end + 1);
315
+ return JSON.parse((0, jsonrepair.jsonrepair)(raw));
316
+ } catch (error) {
317
+ throw new ParseObjectError("Failed to parse array JSON", error, originalText);
318
+ }
579
319
  }
580
- function extractBySchemaType(text, schema, originalText) {
581
- if (_instanceof(schema, v4.z.ZodArray)) {
582
- return extractArray(text, originalText);
583
- }
584
- if (_instanceof(schema, v4.z.ZodObject)) {
585
- return extractObject(text, originalText);
586
- }
587
- if (_instanceof(schema, v4.z.ZodBoolean) || _instanceof(schema, v4.z.ZodNull) || _instanceof(schema, v4.z.ZodNumber) || _instanceof(schema, v4.z.ZodString)) {
588
- return extractPrimitive(text, schema);
589
- }
590
- throw new ParseObjectError('Unsupported schema type', undefined, originalText);
320
+ function extractObject(text, originalText) {
321
+ const start = text.indexOf("{");
322
+ const end = text.lastIndexOf("}");
323
+ if (start === -1 || end === -1) throw new ParseObjectError("No object found in response", void 0, originalText);
324
+ try {
325
+ const raw = text.slice(start, end + 1);
326
+ return JSON.parse((0, jsonrepair.jsonrepair)(raw));
327
+ } catch (error) {
328
+ throw new ParseObjectError("Failed to parse object JSON", error, originalText);
329
+ }
591
330
  }
592
- function extractJsonFromCodeBlock(block) {
593
- var content = block.replace(/```(?:json)?\r?\n([^`]*?)\r?\n```/, '$1').trim();
594
- try {
595
- JSON.parse(content);
596
- return content;
597
- } catch (e) {
598
- return null;
599
- }
331
+ function extractPrimitive(text, schema) {
332
+ const trimmed = text.trim();
333
+ try {
334
+ return convertToPrimitive(JSON.parse(trimmed), schema);
335
+ } catch {
336
+ return convertToPrimitive(trimmed, schema);
337
+ }
600
338
  }
601
- function extractJsonString(text) {
602
- var codeBlocks = text.match(MARKDOWN_CODE_BLOCK_RE);
603
- if (codeBlocks && codeBlocks.length > 0) {
604
- var validBlocks = codeBlocks.map(function(block) {
605
- return extractJsonFromCodeBlock(block);
606
- }).filter(function(block) {
607
- return block !== null;
608
- });
609
- if (validBlocks.length > 0) {
610
- return findLongestString(validBlocks);
611
- }
612
- }
613
- var structures = findJsonStructures(text);
614
- if (structures.length > 0) {
615
- return findLongestString(structures);
616
- }
617
- return text.replace(/\s+/g, ' ').trim();
339
+ function extractBySchemaType(text, schema, originalText) {
340
+ if (schema instanceof zod_v4.z.ZodArray) return extractArray(text, originalText);
341
+ if (schema instanceof zod_v4.z.ZodObject) return extractObject(text, originalText);
342
+ if (schema instanceof zod_v4.z.ZodBoolean || schema instanceof zod_v4.z.ZodNull || schema instanceof zod_v4.z.ZodNumber || schema instanceof zod_v4.z.ZodString) return extractPrimitive(text, schema);
343
+ if (schema instanceof zod_v4.z.ZodUnion || schema instanceof zod_v4.z.ZodDiscriminatedUnion) {
344
+ if (text.indexOf("{") !== -1) return extractObject(text, originalText);
345
+ if (text.indexOf("[") !== -1) return extractArray(text, originalText);
346
+ throw new ParseObjectError("No object or array found for union type", void 0, originalText);
347
+ }
348
+ if (schema instanceof zod_v4.z.ZodOptional || schema instanceof zod_v4.z.ZodNullable) return extractBySchemaType(text, schema.unwrap(), originalText);
349
+ if (schema instanceof zod_v4.z.ZodDefault) return extractBySchemaType(text, schema.def.innerType, originalText);
350
+ if (schema instanceof zod_v4.z.ZodPipe) return extractBySchemaType(text, schema.def.in, originalText);
351
+ throw new ParseObjectError("Unsupported schema type", void 0, originalText);
618
352
  }
619
- function extractObject(text, originalText) {
620
- var start = text.indexOf('{');
621
- var end = text.lastIndexOf('}');
622
- if (start === -1 || end === -1) {
623
- throw new ParseObjectError('No object found in response', undefined, originalText);
624
- }
625
- try {
626
- var raw = text.slice(start, end + 1);
627
- return JSON.parse(jsonrepair.jsonrepair(raw));
628
- } catch (error) {
629
- throw new ParseObjectError('Failed to parse object JSON', error, originalText);
630
- }
353
+ function extractJsonFromCodeBlock(block) {
354
+ const content = block.replace(/```(?:json)?\r?\n([^`]*?)\r?\n```/, "$1").trim();
355
+ try {
356
+ JSON.parse(content);
357
+ return content;
358
+ } catch {
359
+ return null;
360
+ }
631
361
  }
632
- function extractPrimitive(text, schema) {
633
- var trimmed = text.trim();
634
- try {
635
- return convertToPrimitive(JSON.parse(trimmed), schema);
636
- } catch (e) {
637
- return convertToPrimitive(trimmed, schema);
638
- }
362
+ function findLongestString(strings) {
363
+ return strings.reduce((longest, current) => current.length > longest.length ? current : longest);
639
364
  }
640
365
  function findJsonStructures(text) {
641
- var matches = [];
642
- var depth = 0;
643
- var start = -1;
644
- for(var i = 0; i < text.length; i++){
645
- var _char = text[i];
646
- if (_char === '{' || _char === '[') {
647
- if (depth === 0) start = i;
648
- depth++;
649
- } else if (_char === '}' || _char === ']') {
650
- depth--;
651
- if (depth === 0 && start !== -1) {
652
- var candidate = text.slice(start, i + 1);
653
- try {
654
- JSON.parse(candidate);
655
- matches.push(candidate);
656
- } catch (e) {
657
- // Invalid JSON, skip
658
- }
659
- }
660
- }
661
- }
662
- return matches;
366
+ const matches = [];
367
+ let depth = 0;
368
+ let start = -1;
369
+ for (let i = 0; i < text.length; i++) {
370
+ const char = text[i];
371
+ if (char === "{" || char === "[") {
372
+ if (depth === 0) start = i;
373
+ depth++;
374
+ } else if (char === "}" || char === "]") {
375
+ depth--;
376
+ if (depth === 0 && start !== -1) {
377
+ const candidate = text.slice(start, i + 1);
378
+ try {
379
+ JSON.parse(candidate);
380
+ matches.push(candidate);
381
+ } catch {}
382
+ }
383
+ }
384
+ }
385
+ return matches;
663
386
  }
664
- function findLongestString(strings) {
665
- return strings.reduce(function(longest, current) {
666
- return current.length > longest.length ? current : longest;
667
- });
387
+ function extractJsonString(text) {
388
+ const codeBlocks = text.match(MARKDOWN_CODE_BLOCK_RE);
389
+ if (codeBlocks && codeBlocks.length > 0) {
390
+ const validBlocks = codeBlocks.map((block) => extractJsonFromCodeBlock(block)).filter((block) => block !== null);
391
+ if (validBlocks.length > 0) return findLongestString(validBlocks);
392
+ }
393
+ const structures = findJsonStructures(text);
394
+ if (structures.length > 0) return findLongestString(structures);
395
+ return text.replace(/\s+/g, " ").trim();
396
+ }
397
+ function unescapeString(text) {
398
+ return text.replace(/\\"/g, "\"").replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\\\/g, "\\").replace(/\\u([0-9a-fA-F]{4})/g, (_, code) => String.fromCharCode(Number.parseInt(code, 16)));
668
399
  }
669
400
  function unescapeJsonValues(json) {
670
- if (typeof json === 'string') {
671
- return unescapeString(json);
672
- }
673
- if (Array.isArray(json)) {
674
- return json.map(unescapeJsonValues);
675
- }
676
- if ((typeof json === "undefined" ? "undefined" : _type_of(json)) === 'object' && json !== null) {
677
- return Object.fromEntries(Object.entries(json).map(function(param) {
678
- var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
679
- return [
680
- key,
681
- unescapeJsonValues(value)
682
- ];
683
- }));
684
- }
685
- return json;
401
+ if (typeof json === "string") return unescapeString(json);
402
+ if (Array.isArray(json)) return json.map(unescapeJsonValues);
403
+ if (typeof json === "object" && json !== null) return Object.fromEntries(Object.entries(json).map(([key, value]) => [key, unescapeJsonValues(value)]));
404
+ return json;
686
405
  }
687
- function unescapeString(text) {
688
- return text.replace(/\\"/g, '"').replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\t/g, '\t').replace(/\\\\/g, '\\').replace(/\\u([0-9a-fA-F]{4})/g, function(_, code) {
689
- return String.fromCharCode(Number.parseInt(code, 16));
690
- });
406
+ /**
407
+ * Parses AI-generated text into structured data validated against a Zod schema.
408
+ *
409
+ * Handles common AI response formats:
410
+ * - JSON wrapped in markdown code blocks
411
+ * - JSON embedded in prose text
412
+ * - Malformed JSON (auto-repaired)
413
+ * - Escaped unicode and special characters
414
+ *
415
+ * @param text - The raw AI response text
416
+ * @param schema - A Zod schema to validate and type the result
417
+ * @returns The parsed and validated data
418
+ * @throws {ParseObjectError} When parsing or validation fails
419
+ *
420
+ * @example
421
+ * ```ts
422
+ * const schema = z.object({ title: z.string(), tags: z.array(z.string()) });
423
+ * const result = parseObject(aiResponse, schema);
424
+ * // result is typed as { title: string; tags: string[] }
425
+ * ```
426
+ */
427
+ function parseObject(text, schema) {
428
+ try {
429
+ const unescaped = unescapeJsonValues(extractBySchemaType(extractJsonString(text), schema, text));
430
+ return schema.parse(unescaped);
431
+ } catch (error) {
432
+ if (error instanceof ParseObjectError) throw error;
433
+ if (error instanceof zod_v4.z.ZodError) throw new ParseObjectError("Failed to validate response against schema", error, text);
434
+ throw error;
435
+ }
691
436
  }
692
437
 
693
- var INVISIBLE_CHARS_RE = /[\u00AD\u180E\u200B-\u200C\u200E-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/g;
694
- /* eslint-disable no-control-regex -- intentionally matching control characters */ // biome-ignore lint/suspicious/noControlCharactersInRegex: intentionally matching control characters for sanitization
695
- var ASCII_CTRL_RE = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g;
696
- /* eslint-enable no-control-regex */ var SPACE_LIKE_RE = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
697
- var MULTIPLE_SPACES_RE = / {2,}/g;
698
- var CR_RE = /\r\n?/g;
699
- var CITATION_RE = / *\(oaicite:\d+\)\{index=\d+\}/g;
700
- var EM_DASH_SEPARATOR_RE = /\s*[—–―‒]\s*/g;
701
- var TYPOGRAPHY_REPLACEMENTS = [
702
- {
703
- pattern: /[\u2018\u2019\u201A]/g,
704
- replacement: "'"
705
- },
706
- {
707
- pattern: /[\u201C\u201D\u201E]/g,
708
- replacement: '"'
709
- },
710
- {
711
- pattern: /\u2026/g,
712
- replacement: '...'
713
- },
714
- {
715
- pattern: /[\u2022\u25AA-\u25AB\u25B8-\u25B9\u25CF]/g,
716
- replacement: '-'
717
- }
718
- ];
438
+ //#endregion
439
+ //#region src/generation/generate-structured.ts
719
440
  /**
720
- * Parses and sanitizes text by removing AI artifacts and normalizing typography.
721
- *
722
- * @param text - The text to parse
723
- * @param options - Parsing options
724
- * @returns The cleaned text
725
- */ function parseText(text) {
726
- var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
727
- var _options_normalizeEmDashesToCommas = options.normalizeEmDashesToCommas, normalizeEmDashesToCommas = _options_normalizeEmDashesToCommas === void 0 ? true : _options_normalizeEmDashesToCommas, _options_collapseSpaces = options.collapseSpaces, collapseSpaces = _options_collapseSpaces === void 0 ? true : _options_collapseSpaces;
728
- if (!text) return '';
729
- var result = text;
730
- if (result.charCodeAt(0) === 0xfeff) {
731
- result = result.slice(1);
732
- }
733
- result = result.replace(CR_RE, '\n');
734
- result = result.replace(CITATION_RE, '');
735
- result = result.normalize('NFKC');
736
- result = result.replace(INVISIBLE_CHARS_RE, '');
737
- result = result.replace(ASCII_CTRL_RE, '');
738
- if (normalizeEmDashesToCommas) {
739
- result = result.replace(EM_DASH_SEPARATOR_RE, ', ');
740
- }
741
- result = result.replace(SPACE_LIKE_RE, ' ');
742
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
743
- try {
744
- for(var _iterator = TYPOGRAPHY_REPLACEMENTS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
745
- var _step_value = _step.value, pattern = _step_value.pattern, replacement = _step_value.replacement;
746
- result = result.replace(pattern, replacement);
747
- }
748
- } catch (err) {
749
- _didIteratorError = true;
750
- _iteratorError = err;
751
- } finally{
752
- try {
753
- if (!_iteratorNormalCompletion && _iterator["return"] != null) {
754
- _iterator["return"]();
755
- }
756
- } finally{
757
- if (_didIteratorError) {
758
- throw _iteratorError;
759
- }
760
- }
761
- }
762
- if (collapseSpaces) {
763
- result = result.replace(MULTIPLE_SPACES_RE, ' ').trim();
764
- }
765
- return result;
441
+ * Generate structured data from an AI model with automatic parsing and error handling.
442
+ * Observability is handled by middleware - no metadata exposed to caller.
443
+ */
444
+ async function generateStructured(options) {
445
+ const { model, prompt, system, schema, providerOptions, abortSignal, maxOutputTokens, temperature } = options;
446
+ try {
447
+ const response = await (0, ai.generateText)({
448
+ model,
449
+ prompt,
450
+ system,
451
+ providerOptions,
452
+ abortSignal,
453
+ maxOutputTokens,
454
+ temperature
455
+ });
456
+ if (!response.text || response.text.trim() === "") return generationFailure("EMPTY_RESULT", "AI returned empty response");
457
+ try {
458
+ return generationSuccess(parseObject(response.text, schema));
459
+ } catch (error) {
460
+ if (error instanceof ParseObjectError) return generationFailure("PARSING_FAILED", error.message, error);
461
+ return generationFailure("VALIDATION_FAILED", "Schema validation failed", error);
462
+ }
463
+ } catch (error) {
464
+ return generationFailure(classifyError(error), error instanceof Error ? error.message : "Unknown error", error);
465
+ }
766
466
  }
767
467
 
768
- function _define_property(obj, key, value) {
769
- if (key in obj) {
770
- Object.defineProperty(obj, key, {
771
- value: value,
772
- enumerable: true,
773
- configurable: true,
774
- writable: true
775
- });
776
- } else {
777
- obj[key] = value;
778
- }
779
- return obj;
468
+ //#endregion
469
+ //#region src/parsing/create-schema-prompt.ts
470
+ /**
471
+ * Creates a system prompt that instructs the model to output structured data
472
+ * matching the provided Zod schema.
473
+ *
474
+ * Use this with `generateText` when the provider doesn't support native
475
+ * structured outputs, then parse the response with `parseObject`.
476
+ *
477
+ * @param schema - A Zod schema defining the expected output structure
478
+ * @returns A system prompt string with JSON schema instructions
479
+ *
480
+ * @example
481
+ * ```ts
482
+ * import { generateText } from 'ai';
483
+ * import { createSchemaPrompt, parseObject } from '@jterrazz/intelligence';
484
+ *
485
+ * const schema = z.object({ title: z.string(), tags: z.array(z.string()) });
486
+ *
487
+ * const { text } = await generateText({
488
+ * model,
489
+ * prompt: 'Generate an article about TypeScript',
490
+ * system: createSchemaPrompt(schema),
491
+ * });
492
+ *
493
+ * const result = parseObject(text, schema);
494
+ * ```
495
+ */
496
+ function createSchemaPrompt(schema) {
497
+ const jsonSchema = zod_v4.z.toJSONSchema(schema);
498
+ const schemaJson = JSON.stringify(jsonSchema, null, 2);
499
+ if ([
500
+ "boolean",
501
+ "integer",
502
+ "number",
503
+ "string"
504
+ ].includes(jsonSchema.type)) return `<OUTPUT_FORMAT>
505
+ You must respond with a ${jsonSchema.type} value that matches this schema:
506
+
507
+ \`\`\`json
508
+ ${schemaJson}
509
+ \`\`\`
510
+
511
+ Your response should be only the ${jsonSchema.type} value, without any JSON wrapping or additional text.
512
+ </OUTPUT_FORMAT>`;
513
+ return `<OUTPUT_FORMAT>
514
+ You must respond with valid JSON that matches this JSON schema:
515
+
516
+ \`\`\`json
517
+ ${schemaJson}
518
+ \`\`\`
519
+
520
+ Your response must be parseable JSON that validates against this schema. Do not include any text outside the JSON.
521
+ </OUTPUT_FORMAT>`;
780
522
  }
781
- function _object_spread(target) {
782
- for(var i = 1; i < arguments.length; i++){
783
- var source = arguments[i] != null ? arguments[i] : {};
784
- var ownKeys = Object.keys(source);
785
- if (typeof Object.getOwnPropertySymbols === "function") {
786
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
787
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
788
- }));
789
- }
790
- ownKeys.forEach(function(key) {
791
- _define_property(target, key, source[key]);
792
- });
793
- }
794
- return target;
523
+
524
+ //#endregion
525
+ //#region src/parsing/parse-text.ts
526
+ const INVISIBLE_CHARS_RE = /[\u00AD\u180E\u200B-\u200C\u200E-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/g;
527
+ const ASCII_CTRL_RE = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g;
528
+ const SPACE_LIKE_RE = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
529
+ const MULTIPLE_SPACES_RE = / {2,}/g;
530
+ const CR_RE = /\r\n?/g;
531
+ const CITATION_RE = / *\(oaicite:\d+\)\{index=\d+\}/g;
532
+ const EM_DASH_SEPARATOR_RE = /\s*[—–―‒]\s*/g;
533
+ const TYPOGRAPHY_REPLACEMENTS = [
534
+ {
535
+ pattern: /[\u2018\u2019\u201A]/g,
536
+ replacement: "'"
537
+ },
538
+ {
539
+ pattern: /[\u201C\u201D\u201E]/g,
540
+ replacement: "\""
541
+ },
542
+ {
543
+ pattern: /\u2026/g,
544
+ replacement: "..."
545
+ },
546
+ {
547
+ pattern: /[\u2022\u25AA-\u25AB\u25B8-\u25B9\u25CF]/g,
548
+ replacement: "-"
549
+ }
550
+ ];
551
+ /**
552
+ * Parses and sanitizes text by removing AI artifacts and normalizing typography.
553
+ *
554
+ * @param text - The text to parse
555
+ * @param options - Parsing options
556
+ * @returns The cleaned text
557
+ */
558
+ function parseText(text, options = {}) {
559
+ const { normalizeEmDashesToCommas = true, collapseSpaces = true } = options;
560
+ if (!text) return "";
561
+ let result = text;
562
+ result = result.replace(CR_RE, "\n");
563
+ result = result.replace(CITATION_RE, "");
564
+ result = result.normalize("NFKC");
565
+ result = result.replace(INVISIBLE_CHARS_RE, "");
566
+ result = result.replace(ASCII_CTRL_RE, "");
567
+ if (normalizeEmDashesToCommas) result = result.replace(EM_DASH_SEPARATOR_RE, ", ");
568
+ result = result.replace(SPACE_LIKE_RE, " ");
569
+ for (const { pattern, replacement } of TYPOGRAPHY_REPLACEMENTS) result = result.replace(pattern, replacement);
570
+ if (collapseSpaces) result = result.replace(MULTIPLE_SPACES_RE, " ").trim();
571
+ return result;
795
572
  }
573
+
574
+ //#endregion
575
+ //#region src/provider/openrouter.provider.ts
796
576
  /**
797
- * Creates an OpenRouter provider for AI SDK models.
798
- *
799
- * @example
800
- * ```ts
801
- * const provider = createOpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY });
802
- * const model = provider.model('anthropic/claude-sonnet-4-20250514');
803
- *
804
- * const { text } = await generateText({ model, prompt: 'Hello!' });
805
- * ```
806
- */ function createOpenRouterProvider(config) {
807
- var openrouter = aiSdkProvider.createOpenRouter({
808
- apiKey: config.apiKey
809
- });
810
- return {
811
- model: function model(name) {
812
- var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
813
- return openrouter(name, _object_spread({}, options.maxTokens !== undefined && {
814
- maxTokens: options.maxTokens
815
- }, options.reasoning && {
816
- extraBody: {
817
- reasoning: options.reasoning
818
- }
819
- }));
820
- }
821
- };
577
+ * Creates an OpenRouter provider for AI SDK models.
578
+ *
579
+ * @example
580
+ * ```ts
581
+ * const provider = createOpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY });
582
+ * const model = provider.model('anthropic/claude-sonnet-4-20250514');
583
+ *
584
+ * const { text } = await generateText({ model, prompt: 'Hello!' });
585
+ * ```
586
+ */
587
+ function createOpenRouterProvider(config) {
588
+ const openrouter = (0, _openrouter_ai_sdk_provider.createOpenRouter)({ apiKey: config.apiKey });
589
+ return { model(name, options = {}) {
590
+ return openrouter(name, {
591
+ ...options.maxTokens !== void 0 && { maxTokens: options.maxTokens },
592
+ ...options.reasoning && { extraBody: { reasoning: options.reasoning } }
593
+ });
594
+ } };
822
595
  }
823
596
 
597
+ //#endregion
598
+ //#region src/provider/openrouter-metadata.adapter.ts
599
+ /**
600
+ * OpenRouter adapter for extracting usage and cost from provider metadata
601
+ */
602
+ var OpenRouterMetadataAdapter = class {
603
+ extract(providerMetadata) {
604
+ const meta = providerMetadata?.openrouter;
605
+ if (!meta?.usage) return {};
606
+ const usage = meta.usage;
607
+ return {
608
+ usage: {
609
+ input: usage.promptTokens ?? 0,
610
+ output: usage.completionTokens ?? 0,
611
+ total: usage.totalTokens,
612
+ reasoning: usage.completionTokensDetails?.reasoningTokens,
613
+ cacheRead: usage.promptTokensDetails?.cachedTokens
614
+ },
615
+ cost: usage.cost !== void 0 ? { total: usage.cost } : void 0
616
+ };
617
+ }
618
+ };
619
+
620
+ //#endregion
621
+ exports.LangfuseAdapter = LangfuseAdapter;
622
+ exports.NoopObservabilityAdapter = NoopObservabilityAdapter;
623
+ exports.OpenRouterMetadataAdapter = OpenRouterMetadataAdapter;
824
624
  exports.ParseObjectError = ParseObjectError;
625
+ exports.classifyError = classifyError;
825
626
  exports.createLoggingMiddleware = createLoggingMiddleware;
627
+ exports.createObservabilityMiddleware = createObservabilityMiddleware;
826
628
  exports.createOpenRouterProvider = createOpenRouterProvider;
827
629
  exports.createSchemaPrompt = createSchemaPrompt;
630
+ exports.generateStructured = generateStructured;
631
+ exports.generationFailure = generationFailure;
632
+ exports.generationSuccess = generationSuccess;
633
+ exports.isFailure = isFailure;
634
+ exports.isSuccess = isSuccess;
828
635
  exports.parseObject = parseObject;
829
636
  exports.parseText = parseText;
637
+ exports.unwrap = unwrap;
638
+ exports.unwrapOr = unwrapOr;
639
+ exports.withObservability = withObservability;
640
+ //# sourceMappingURL=index.cjs.map