@jterrazz/intelligence 6.0.0 → 7.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 +16 -6
- package/dist/index.cjs +60 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -16
- package/dist/index.d.ts +31 -16
- package/dist/index.js +60 -33
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -62,9 +62,10 @@ Each agent has a `provider` (a key into `providers`) and a `model` (the technica
|
|
|
62
62
|
For each resolved model reference:
|
|
63
63
|
|
|
64
64
|
1. The provider's base model (via `createOpenRouterProvider` or `createGatewayProvider`).
|
|
65
|
-
2. `
|
|
66
|
-
3.
|
|
67
|
-
4. If
|
|
65
|
+
2. `createAgentMiddleware` — names the AI SDK's inference span after the agent (`gen_ai.agent.name`), so a trace backend that only reads that span (Langfuse) still knows which agent generated.
|
|
66
|
+
3. `createCostMiddleware` — records the generation's USD cost on the same span.
|
|
67
|
+
4. If the agent has a `fallback`, `createFallbackModel` wraps primary + fallback with automatic retry-on-failure.
|
|
68
|
+
5. If a `logger` is configured, `createLoggingMiddleware` wraps the whole thing.
|
|
68
69
|
|
|
69
70
|
On first use, `createIntelligence` registers the AI SDK's OpenTelemetry integration (`@ai-sdk/otel`) globally. This is idempotent and best-effort — if the host app hasn't set up an OpenTelemetry SDK, this is a no-op rather than an error.
|
|
70
71
|
|
|
@@ -112,7 +113,6 @@ const model = wrapLanguageModel({
|
|
|
112
113
|
model: provider.model('google/gemini-2.5-flash-lite'),
|
|
113
114
|
middleware: [
|
|
114
115
|
createCostMiddleware({
|
|
115
|
-
modelRef: 'openrouter/google/gemini-2.5-flash-lite',
|
|
116
116
|
// Only used as a fallback when the provider doesn't report actual cost
|
|
117
117
|
pricing: { input: 0.1, output: 0.4 }, // USD per million tokens
|
|
118
118
|
}),
|
|
@@ -125,7 +125,7 @@ Cost resolution order:
|
|
|
125
125
|
1. Actual cost reported by the provider (currently: OpenRouter's `providerMetadata.openrouter.usage.cost`), when present and greater than zero.
|
|
126
126
|
2. Otherwise, an estimate from `pricing` and the reported token usage.
|
|
127
127
|
|
|
128
|
-
When a cost is determined, it's set as the `gen_ai.usage.cost` attribute on `trace.getActiveSpan()
|
|
128
|
+
When a cost is determined, it's set as the `gen_ai.usage.cost` attribute on `trace.getActiveSpan()` — the AI SDK's inference span, which it activates for the provider call. Langfuse prioritizes that attribute over its own cost inference. When no cost is known nothing is written, and `gen_ai.request.model` is left as the bare model id so Langfuse can price it from its catalogue (a provider-prefixed id like `gateway/claude-…` matches nothing there). All enrichment is best-effort: it never throws, even with no active span or a broken telemetry backend.
|
|
129
129
|
|
|
130
130
|
### Fallback model
|
|
131
131
|
|
|
@@ -308,7 +308,8 @@ Each rule is deliberately best-effort where full static verification isn't possi
|
|
|
308
308
|
|
|
309
309
|
| Export | Description |
|
|
310
310
|
| ---------------------------------- | --------------------------------------------- |
|
|
311
|
-
| `
|
|
311
|
+
| `createAgentMiddleware(options)` | Names the active OTel span after the agent |
|
|
312
|
+
| `createCostMiddleware(options?)` | Records USD cost on the active OTel span |
|
|
312
313
|
| `createLoggingMiddleware(options)` | Logs requests/responses with timing and usage |
|
|
313
314
|
|
|
314
315
|
### Model
|
|
@@ -330,3 +331,12 @@ Each rule is deliberately best-effort where full static verification isn't possi
|
|
|
330
331
|
| -------------------------------- | -------------------------------------------------------------------------- |
|
|
331
332
|
| `cleanAiText(text, options?)` | Sanitize AI-generated text (also at `/formatting`) |
|
|
332
333
|
| `toSentenceCase(text, options?)` | Normalize Title Case overuse back to sentence case (also at `/formatting`) |
|
|
334
|
+
|
|
335
|
+
> **Next.js consumers**: `toSentenceCase` lazy-loads hunspell dictionaries from
|
|
336
|
+
> disk (`require.resolve` + `readFileSync`), which breaks when bundled. Add
|
|
337
|
+
> `serverExternalPackages: ['@jterrazz/intelligence']` to `next.config.ts` so
|
|
338
|
+
> the package stays a native server require.
|
|
339
|
+
|
|
340
|
+
## Decisions
|
|
341
|
+
|
|
342
|
+
Why this package looks the way it does is recorded in [`docs/decisions/`](docs/decisions/).
|
package/dist/index.cjs
CHANGED
|
@@ -4,9 +4,46 @@ let ai = require("ai");
|
|
|
4
4
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
5
5
|
let _ai_sdk_openai = require("@ai-sdk/openai");
|
|
6
6
|
let _openrouter_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
|
|
7
|
+
//#region src/middleware/agent.middleware.ts
|
|
8
|
+
const AGENT_ATTRIBUTE = "gen_ai.agent.name";
|
|
9
|
+
/**
|
|
10
|
+
* Creates middleware that names the AI SDK's inference span after the agent.
|
|
11
|
+
*
|
|
12
|
+
* The AI SDK names that span `chat <model>` and only puts the agent identity
|
|
13
|
+
* (`gen_ai.agent.name`, from `experimental_telemetry.functionId`) on the
|
|
14
|
+
* parent `invoke_agent` span. Langfuse extracts model, usage and cost from
|
|
15
|
+
* the inference span alone, so a pipeline that forwards only that span would
|
|
16
|
+
* otherwise show every agent as "chat <model>". This runs inside the
|
|
17
|
+
* inference span's context (the AI SDK activates it for the provider call),
|
|
18
|
+
* so the active span is the right one.
|
|
19
|
+
*
|
|
20
|
+
* Never throws: all enrichment is best-effort.
|
|
21
|
+
*/
|
|
22
|
+
function createAgentMiddleware(options) {
|
|
23
|
+
const { agentName } = options;
|
|
24
|
+
const nameActiveSpan = () => {
|
|
25
|
+
try {
|
|
26
|
+
const span = _opentelemetry_api.trace.getActiveSpan();
|
|
27
|
+
if (!span) return;
|
|
28
|
+
span.updateName(agentName);
|
|
29
|
+
span.setAttribute(AGENT_ATTRIBUTE, agentName);
|
|
30
|
+
} catch {}
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
specificationVersion: "v4",
|
|
34
|
+
wrapGenerate: async ({ doGenerate }) => {
|
|
35
|
+
nameActiveSpan();
|
|
36
|
+
return doGenerate();
|
|
37
|
+
},
|
|
38
|
+
wrapStream: async ({ doStream }) => {
|
|
39
|
+
nameActiveSpan();
|
|
40
|
+
return doStream();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
7
45
|
//#region src/middleware/cost.middleware.ts
|
|
8
46
|
const COST_ATTRIBUTE = "gen_ai.usage.cost";
|
|
9
|
-
const MODEL_ATTRIBUTE = "gen_ai.request.model";
|
|
10
47
|
function resolveCost(providerMetadata, usage, pricing) {
|
|
11
48
|
const actualCost = providerMetadata?.openrouter?.usage?.cost;
|
|
12
49
|
if (typeof actualCost === "number" && actualCost > 0) return actualCost;
|
|
@@ -16,16 +53,15 @@ function resolveCost(providerMetadata, usage, pricing) {
|
|
|
16
53
|
return inputTokens / 1e6 * pricing.input + outputTokens / 1e6 * pricing.output;
|
|
17
54
|
}
|
|
18
55
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
span.setAttribute(MODEL_ATTRIBUTE, modelRef);
|
|
23
|
-
if (cost !== void 0) span.setAttribute(COST_ATTRIBUTE, cost);
|
|
56
|
+
function recordCost(cost) {
|
|
57
|
+
if (cost === void 0) return;
|
|
58
|
+
_opentelemetry_api.trace.getActiveSpan()?.setAttribute(COST_ATTRIBUTE, cost);
|
|
24
59
|
}
|
|
25
60
|
/**
|
|
26
|
-
* Creates middleware that
|
|
27
|
-
*
|
|
28
|
-
* (`gen_ai.
|
|
61
|
+
* Creates middleware that records the USD cost of a generation as
|
|
62
|
+
* `gen_ai.usage.cost` on the active OpenTelemetry span — the AI SDK's own
|
|
63
|
+
* inference span (`gen_ai.operation.name = chat`), which is what Langfuse
|
|
64
|
+
* ingests as a generation.
|
|
29
65
|
*
|
|
30
66
|
* Resolution order:
|
|
31
67
|
* 1. Actual cost reported by the provider (currently: OpenRouter's
|
|
@@ -33,9 +69,10 @@ function recordGeneration(modelRef, cost) {
|
|
|
33
69
|
* 2. Estimated cost from `pricing` (USD per million input/output tokens),
|
|
34
70
|
* computed from the reported token usage.
|
|
35
71
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
72
|
+
* When neither is available nothing is written: `gen_ai.request.model` is
|
|
73
|
+
* left to the AI SDK (the bare model id), so Langfuse can still price the
|
|
74
|
+
* generation from its own model catalogue. Langfuse prioritizes
|
|
75
|
+
* `gen_ai.usage.cost` over that inference when both exist.
|
|
39
76
|
*
|
|
40
77
|
* Never throws: all enrichment is best-effort.
|
|
41
78
|
*
|
|
@@ -43,23 +80,18 @@ function recordGeneration(modelRef, cost) {
|
|
|
43
80
|
* ```ts
|
|
44
81
|
* const model = wrapLanguageModel({
|
|
45
82
|
* model: provider.model('google/gemini-2.5-flash-lite'),
|
|
46
|
-
* middleware: [
|
|
47
|
-
* createCostMiddleware({
|
|
48
|
-
* modelRef: 'openrouter/google/gemini-2.5-flash-lite',
|
|
49
|
-
* pricing: { input: 0.1, output: 0.4 },
|
|
50
|
-
* }),
|
|
51
|
-
* ],
|
|
83
|
+
* middleware: [createCostMiddleware({ pricing: { input: 0.1, output: 0.4 } })],
|
|
52
84
|
* });
|
|
53
85
|
* ```
|
|
54
86
|
*/
|
|
55
|
-
function createCostMiddleware(options) {
|
|
56
|
-
const {
|
|
87
|
+
function createCostMiddleware(options = {}) {
|
|
88
|
+
const { pricing } = options;
|
|
57
89
|
return {
|
|
58
90
|
specificationVersion: "v4",
|
|
59
91
|
wrapGenerate: async ({ doGenerate }) => {
|
|
60
92
|
const result = await doGenerate();
|
|
61
93
|
try {
|
|
62
|
-
|
|
94
|
+
recordCost(resolveCost(result.providerMetadata, result.usage, pricing));
|
|
63
95
|
} catch {}
|
|
64
96
|
return result;
|
|
65
97
|
},
|
|
@@ -77,7 +109,7 @@ function createCostMiddleware(options) {
|
|
|
77
109
|
},
|
|
78
110
|
flush() {
|
|
79
111
|
try {
|
|
80
|
-
|
|
112
|
+
recordCost(resolveCost(finishProviderMetadata, finishUsage, pricing));
|
|
81
113
|
} catch {}
|
|
82
114
|
}
|
|
83
115
|
});
|
|
@@ -773,16 +805,11 @@ function createIntelligence(config) {
|
|
|
773
805
|
}
|
|
774
806
|
return provider;
|
|
775
807
|
}
|
|
776
|
-
function buildModel(ref) {
|
|
808
|
+
function buildModel(ref, agentName) {
|
|
777
809
|
assertProviderExists(ref.provider, providers);
|
|
778
|
-
const baseModel = resolveProvider(ref.provider).model(ref.model);
|
|
779
|
-
const pricingKey = `${ref.provider}/${ref.model}`;
|
|
780
810
|
return (0, ai.wrapLanguageModel)({
|
|
781
|
-
model:
|
|
782
|
-
middleware: [createCostMiddleware({
|
|
783
|
-
modelRef: pricingKey,
|
|
784
|
-
pricing: pricing?.[pricingKey]
|
|
785
|
-
})]
|
|
811
|
+
model: resolveProvider(ref.provider).model(ref.model),
|
|
812
|
+
middleware: [createAgentMiddleware({ agentName }), createCostMiddleware({ pricing: pricing?.[`${ref.provider}/${ref.model}`] })]
|
|
786
813
|
});
|
|
787
814
|
}
|
|
788
815
|
function buildAgentModel(agentName) {
|
|
@@ -794,9 +821,9 @@ function createIntelligence(config) {
|
|
|
794
821
|
const primary = buildModel({
|
|
795
822
|
model: agentConfig.model,
|
|
796
823
|
provider: agentConfig.provider
|
|
797
|
-
});
|
|
824
|
+
}, agentName);
|
|
798
825
|
const composed = agentConfig.fallback ? createFallbackModel({
|
|
799
|
-
fallback: buildModel(agentConfig.fallback),
|
|
826
|
+
fallback: buildModel(agentConfig.fallback, agentName),
|
|
800
827
|
logger,
|
|
801
828
|
primary
|
|
802
829
|
}) : primary;
|
|
@@ -816,6 +843,7 @@ function createIntelligence(config) {
|
|
|
816
843
|
} };
|
|
817
844
|
}
|
|
818
845
|
//#endregion
|
|
846
|
+
exports.createAgentMiddleware = createAgentMiddleware;
|
|
819
847
|
exports.createCostMiddleware = createCostMiddleware;
|
|
820
848
|
exports.createFallbackModel = createFallbackModel;
|
|
821
849
|
exports.createGatewayProvider = createGatewayProvider;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["trace","OpenTelemetry"],"sources":["../src/middleware/cost.middleware.ts","../src/middleware/logging.middleware.ts","../node_modules/@ai-sdk/provider/dist/index.js","../src/model/fallback-model.ts","../src/middleware/schema-instruction.middleware.ts","../src/provider/gateway.provider.ts","../src/provider/openrouter.provider.ts","../src/factory/create-intelligence.ts"],"sourcesContent":["import type { LanguageModelV4StreamPart, LanguageModelV4Usage } from '@ai-sdk/provider';\nimport { trace } from '@opentelemetry/api';\nimport type { LanguageModelMiddleware } from 'ai';\n\nconst COST_ATTRIBUTE = 'gen_ai.usage.cost';\nconst MODEL_ATTRIBUTE = 'gen_ai.request.model';\n\ninterface OpenRouterCostMetadata {\n openrouter?: {\n usage?: {\n cost?: number;\n };\n };\n}\n\ninterface CostPricing {\n /** USD per million input tokens */\n input: number;\n /** USD per million output tokens */\n output: number;\n}\n\nfunction resolveCost(\n providerMetadata: Record<string, unknown> | undefined,\n usage: LanguageModelV4Usage | undefined,\n pricing: CostPricing | undefined,\n): number | undefined {\n const actualCost = (providerMetadata as OpenRouterCostMetadata | undefined)?.openrouter?.usage\n ?.cost;\n if (typeof actualCost === 'number' && actualCost > 0) {\n return actualCost;\n }\n\n if (pricing) {\n const inputTokens = usage?.inputTokens?.total ?? 0;\n const outputTokens = usage?.outputTokens?.total ?? 0;\n return (\n (inputTokens / 1_000_000) * pricing.input + (outputTokens / 1_000_000) * pricing.output\n );\n }\n\n return undefined;\n}\n\nfunction recordGeneration(modelRef: string, cost: number | undefined): void {\n const span = trace.getActiveSpan();\n if (!span) {\n return;\n }\n span.setAttribute(MODEL_ATTRIBUTE, modelRef);\n if (cost !== undefined) {\n span.setAttribute(COST_ATTRIBUTE, cost);\n }\n}\n\nexport type { CostPricing };\n\nexport interface CostMiddlewareOptions {\n /** Full model reference, e.g. `'openrouter/google/gemini-2.5-flash-lite'` */\n modelRef: string;\n /** Fallback USD-per-million-token pricing, used when the provider doesn't report actual cost */\n pricing?: CostPricing;\n}\n\n/**\n * Creates middleware that enriches the active OpenTelemetry span with the\n * model reference (`gen_ai.request.model`) and the USD cost\n * (`gen_ai.usage.cost`) of a generation.\n *\n * Resolution order:\n * 1. Actual cost reported by the provider (currently: OpenRouter's\n * `providerMetadata.openrouter.usage.cost`).\n * 2. Estimated cost from `pricing` (USD per million input/output tokens),\n * computed from the reported token usage.\n *\n * The `gen_ai.usage.cost` attribute is set on `trace.getActiveSpan()` because\n * that's the attribute Langfuse's OTel ingestion prioritizes over its own\n * cost inference (`langfuse.observation.cost_details` is buggy on ingestion).\n *\n * Never throws: all enrichment is best-effort.\n *\n * @example\n * ```ts\n * const model = wrapLanguageModel({\n * model: provider.model('google/gemini-2.5-flash-lite'),\n * middleware: [\n * createCostMiddleware({\n * modelRef: 'openrouter/google/gemini-2.5-flash-lite',\n * pricing: { input: 0.1, output: 0.4 },\n * }),\n * ],\n * });\n * ```\n */\nexport function createCostMiddleware(options: CostMiddlewareOptions): LanguageModelMiddleware {\n const { modelRef, pricing } = options;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate }) => {\n const result = await doGenerate();\n\n try {\n recordGeneration(\n modelRef,\n resolveCost(\n result.providerMetadata as Record<string, unknown> | undefined,\n result.usage,\n pricing,\n ),\n );\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n\n return result;\n },\n\n wrapStream: async ({ doStream }) => {\n const result = await doStream();\n\n let finishUsage: LanguageModelV4Usage | undefined;\n let finishProviderMetadata: Record<string, unknown> | undefined;\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'finish') {\n finishUsage = chunk.usage;\n finishProviderMetadata = chunk.providerMetadata as\n | Record<string, unknown>\n | undefined;\n }\n controller.enqueue(chunk);\n },\n flush() {\n try {\n recordGeneration(\n modelRef,\n resolveCost(finishProviderMetadata, finishUsage, pricing),\n );\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n },\n });\n\n return {\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n },\n };\n}\n","import type { LanguageModelV4StreamPart } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModelMiddleware } from 'ai';\n\nexport interface LoggingMiddlewareOptions {\n logger: LoggerPort;\n include?: {\n params?: boolean;\n content?: boolean;\n usage?: boolean;\n };\n}\n\n/**\n * Creates middleware that logs AI SDK requests and responses.\n */\nexport function createLoggingMiddleware(\n options: LoggingMiddlewareOptions,\n): LanguageModelMiddleware {\n const { logger, include = {} } = options;\n const { params: includeParams, content: includeContent, usage: includeUsage = true } = include;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.generate.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doGenerate();\n\n // Extract text from content\n const textContent = result.content\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n logger.debug('ai.generate.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n finishReason: result.finishReason,\n ...(includeUsage && { usage: result.usage }),\n ...(includeContent && { content: textContent }),\n });\n\n return result;\n } catch (error) {\n logger.error('ai.generate.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n\n wrapStream: async ({ doStream, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.stream.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doStream();\n\n const chunks: string[] = [];\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (includeContent && chunk.type === 'text-delta') {\n chunks.push(chunk.delta);\n }\n controller.enqueue(chunk);\n },\n flush() {\n logger.debug('ai.stream.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n ...(includeContent && { content: chunks.join('') }),\n });\n },\n });\n\n return {\n specificationVersion: 'v4',\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n } catch (error) {\n logger.error('ai.stream.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n };\n}\n","// src/errors/ai-sdk-error.ts\nvar marker = \"vercel.ai.error\";\nvar symbol = Symbol.for(marker);\nvar _a, _b;\nvar AISDKError = class _AISDKError extends (_b = Error, _a = symbol, _b) {\n /**\n * Creates an AI SDK Error.\n *\n * @param {Object} params - The parameters for creating the error.\n * @param {string} params.name - The name of the error.\n * @param {string} params.message - The error message.\n * @param {unknown} [params.cause] - The underlying cause of the error.\n */\n constructor({\n name: name15,\n message,\n cause\n }) {\n super(message);\n this[_a] = true;\n this.name = name15;\n this.cause = cause;\n }\n /**\n * Checks if the given error is an AI SDK Error.\n * @param {unknown} error - The error to check.\n * @returns {boolean} True if the error is an AI SDK Error, false otherwise.\n */\n static isInstance(error) {\n return _AISDKError.hasMarker(error, marker);\n }\n static hasMarker(error, marker16) {\n const markerSymbol = Symbol.for(marker16);\n return error != null && typeof error === \"object\" && markerSymbol in error && typeof error[markerSymbol] === \"boolean\" && error[markerSymbol] === true;\n }\n};\n\n// src/errors/api-call-error.ts\nvar name = \"AI_APICallError\";\nvar marker2 = `vercel.ai.error.${name}`;\nvar symbol2 = Symbol.for(marker2);\nvar _a2, _b2;\nvar APICallError = class extends (_b2 = AISDKError, _a2 = symbol2, _b2) {\n constructor({\n message,\n url,\n requestBodyValues,\n statusCode,\n responseHeaders,\n responseBody,\n cause,\n isRetryable = statusCode != null && (statusCode === 408 || // request timeout\n statusCode === 409 || // conflict\n statusCode === 429 || // too many requests\n statusCode >= 500),\n // server error\n data\n }) {\n super({ name, message, cause });\n this[_a2] = true;\n this.url = url;\n this.requestBodyValues = requestBodyValues;\n this.statusCode = statusCode;\n this.responseHeaders = responseHeaders;\n this.responseBody = responseBody;\n this.isRetryable = isRetryable;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker2);\n }\n};\n\n// src/errors/empty-response-body-error.ts\nvar name2 = \"AI_EmptyResponseBodyError\";\nvar marker3 = `vercel.ai.error.${name2}`;\nvar symbol3 = Symbol.for(marker3);\nvar _a3, _b3;\nvar EmptyResponseBodyError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) {\n // used in isInstance\n constructor({ message = \"Empty response body\" } = {}) {\n super({ name: name2, message });\n this[_a3] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker3);\n }\n};\n\n// src/errors/get-error-message.ts\nfunction getErrorMessage(error) {\n if (error == null) {\n return \"unknown error\";\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error instanceof Error) {\n return error.toString();\n }\n return JSON.stringify(error);\n}\n\n// src/errors/invalid-argument-error.ts\nvar name3 = \"AI_InvalidArgumentError\";\nvar marker4 = `vercel.ai.error.${name3}`;\nvar symbol4 = Symbol.for(marker4);\nvar _a4, _b4;\nvar InvalidArgumentError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) {\n constructor({\n message,\n cause,\n argument\n }) {\n super({ name: name3, message, cause });\n this[_a4] = true;\n this.argument = argument;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker4);\n }\n};\n\n// src/errors/invalid-prompt-error.ts\nvar name4 = \"AI_InvalidPromptError\";\nvar marker5 = `vercel.ai.error.${name4}`;\nvar symbol5 = Symbol.for(marker5);\nvar _a5, _b5;\nvar InvalidPromptError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) {\n constructor({\n prompt,\n message,\n cause\n }) {\n super({ name: name4, message: `Invalid prompt: ${message}`, cause });\n this[_a5] = true;\n this.prompt = prompt;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker5);\n }\n};\n\n// src/errors/invalid-response-data-error.ts\nvar name5 = \"AI_InvalidResponseDataError\";\nvar marker6 = `vercel.ai.error.${name5}`;\nvar symbol6 = Symbol.for(marker6);\nvar _a6, _b6;\nvar InvalidResponseDataError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) {\n constructor({\n data,\n message = `Invalid response data: ${JSON.stringify(data)}.`\n }) {\n super({ name: name5, message });\n this[_a6] = true;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker6);\n }\n};\n\n// src/errors/json-parse-error.ts\nvar name6 = \"AI_JSONParseError\";\nvar marker7 = `vercel.ai.error.${name6}`;\nvar symbol7 = Symbol.for(marker7);\nvar _a7, _b7;\nvar JSONParseError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) {\n constructor({ text, cause }) {\n super({\n name: name6,\n message: `JSON parsing failed: Text: ${text}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a7] = true;\n this.text = text;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker7);\n }\n};\n\n// src/errors/load-api-key-error.ts\nvar name7 = \"AI_LoadAPIKeyError\";\nvar marker8 = `vercel.ai.error.${name7}`;\nvar symbol8 = Symbol.for(marker8);\nvar _a8, _b8;\nvar LoadAPIKeyError = class extends (_b8 = AISDKError, _a8 = symbol8, _b8) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name7, message });\n this[_a8] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker8);\n }\n};\n\n// src/errors/load-setting-error.ts\nvar name8 = \"AI_LoadSettingError\";\nvar marker9 = `vercel.ai.error.${name8}`;\nvar symbol9 = Symbol.for(marker9);\nvar _a9, _b9;\nvar LoadSettingError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name8, message });\n this[_a9] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker9);\n }\n};\n\n// src/errors/no-content-generated-error.ts\nvar name9 = \"AI_NoContentGeneratedError\";\nvar marker10 = `vercel.ai.error.${name9}`;\nvar symbol10 = Symbol.for(marker10);\nvar _a10, _b10;\nvar NoContentGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) {\n // used in isInstance\n constructor({\n message = \"No content generated.\"\n } = {}) {\n super({ name: name9, message });\n this[_a10] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker10);\n }\n};\n\n// src/errors/no-such-model-error.ts\nvar name10 = \"AI_NoSuchModelError\";\nvar marker11 = `vercel.ai.error.${name10}`;\nvar symbol11 = Symbol.for(marker11);\nvar _a11, _b11;\nvar NoSuchModelError = class extends (_b11 = AISDKError, _a11 = symbol11, _b11) {\n constructor({\n errorName = name10,\n modelId,\n modelType,\n message = `No such ${modelType}: ${modelId}`\n }) {\n super({ name: errorName, message });\n this[_a11] = true;\n this.modelId = modelId;\n this.modelType = modelType;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker11);\n }\n};\n\n// src/errors/no-such-provider-reference-error.ts\nvar name11 = \"AI_NoSuchProviderReferenceError\";\nvar marker12 = `vercel.ai.error.${name11}`;\nvar symbol12 = Symbol.for(marker12);\nvar _a12, _b12;\nvar NoSuchProviderReferenceError = class extends (_b12 = AISDKError, _a12 = symbol12, _b12) {\n constructor({\n provider,\n reference,\n message = `No provider reference found for provider '${provider}'. Available providers: ${Object.keys(reference).join(\", \")}`\n }) {\n super({ name: name11, message });\n this[_a12] = true;\n this.provider = provider;\n this.reference = reference;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker12);\n }\n};\n\n// src/errors/too-many-embedding-values-for-call-error.ts\nvar name12 = \"AI_TooManyEmbeddingValuesForCallError\";\nvar marker13 = `vercel.ai.error.${name12}`;\nvar symbol13 = Symbol.for(marker13);\nvar _a13, _b13;\nvar TooManyEmbeddingValuesForCallError = class extends (_b13 = AISDKError, _a13 = symbol13, _b13) {\n constructor(options) {\n super({\n name: name12,\n message: `Too many values for a single embedding call. The ${options.provider} model \"${options.modelId}\" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`\n });\n this[_a13] = true;\n this.provider = options.provider;\n this.modelId = options.modelId;\n this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;\n this.values = options.values;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker13);\n }\n};\n\n// src/errors/type-validation-error.ts\nvar name13 = \"AI_TypeValidationError\";\nvar marker14 = `vercel.ai.error.${name13}`;\nvar symbol14 = Symbol.for(marker14);\nvar _a14, _b14;\nvar TypeValidationError = class _TypeValidationError extends (_b14 = AISDKError, _a14 = symbol14, _b14) {\n constructor({\n value,\n cause,\n context\n }) {\n let contextPrefix = \"Type validation failed\";\n if (context == null ? void 0 : context.field) {\n contextPrefix += ` for ${context.field}`;\n }\n if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) {\n contextPrefix += \" (\";\n const parts = [];\n if (context.entityName) {\n parts.push(context.entityName);\n }\n if (context.entityId) {\n parts.push(`id: \"${context.entityId}\"`);\n }\n contextPrefix += parts.join(\", \");\n contextPrefix += \")\";\n }\n super({\n name: name13,\n message: `${contextPrefix}: Value: ${JSON.stringify(value)}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a14] = true;\n this.value = value;\n this.context = context;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker14);\n }\n /**\n * Wraps an error into a TypeValidationError.\n * If the cause is already a TypeValidationError with the same value and context, it returns the cause.\n * Otherwise, it creates a new TypeValidationError.\n *\n * @param {Object} params - The parameters for wrapping the error.\n * @param {unknown} params.value - The value that failed validation.\n * @param {unknown} params.cause - The original error or cause of the validation failure.\n * @param {TypeValidationContext} params.context - Optional context about what is being validated.\n * @returns {TypeValidationError} A TypeValidationError instance.\n */\n static wrap({\n value,\n cause,\n context\n }) {\n var _a16, _b16, _c;\n if (_TypeValidationError.isInstance(cause) && cause.value === value && ((_a16 = cause.context) == null ? void 0 : _a16.field) === (context == null ? void 0 : context.field) && ((_b16 = cause.context) == null ? void 0 : _b16.entityName) === (context == null ? void 0 : context.entityName) && ((_c = cause.context) == null ? void 0 : _c.entityId) === (context == null ? void 0 : context.entityId)) {\n return cause;\n }\n return new _TypeValidationError({ value, cause, context });\n }\n};\n\n// src/errors/unsupported-functionality-error.ts\nvar name14 = \"AI_UnsupportedFunctionalityError\";\nvar marker15 = `vercel.ai.error.${name14}`;\nvar symbol15 = Symbol.for(marker15);\nvar _a15, _b15;\nvar UnsupportedFunctionalityError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) {\n constructor({\n functionality,\n message = `'${functionality}' functionality not supported.`\n }) {\n super({ name: name14, message });\n this[_a15] = true;\n this.functionality = functionality;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker15);\n }\n};\n\n// src/json-value/is-json.ts\nfunction isJSONValue(value) {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(isJSONValue);\n }\n if (typeof value === \"object\") {\n return Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n }\n return false;\n}\nfunction isJSONArray(value) {\n return Array.isArray(value) && value.every(isJSONValue);\n}\nfunction isJSONObject(value) {\n return value != null && typeof value === \"object\" && Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n}\nexport {\n AISDKError,\n APICallError,\n EmptyResponseBodyError,\n InvalidArgumentError,\n InvalidPromptError,\n InvalidResponseDataError,\n JSONParseError,\n LoadAPIKeyError,\n LoadSettingError,\n NoContentGeneratedError,\n NoSuchModelError,\n NoSuchProviderReferenceError,\n TooManyEmbeddingValuesForCallError,\n TypeValidationError,\n UnsupportedFunctionalityError,\n getErrorMessage,\n isJSONArray,\n isJSONObject,\n isJSONValue\n};\n//# sourceMappingURL=index.js.map","import {\n APICallError,\n type LanguageModelV4,\n type LanguageModelV4CallOptions,\n} from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModel } from 'ai';\n\nconst RETRYABLE_MESSAGE_PATTERNS = [\n /ECONNREFUSED/i,\n /ECONNRESET/i,\n /ETIMEDOUT/i,\n /EAI_AGAIN/i,\n /ENOTFOUND/i,\n /timed?\\s*out/i,\n /network/i,\n /fetch failed/i,\n];\n\nfunction isRetryableError(error: unknown): boolean {\n if (APICallError.isInstance(error)) {\n if (typeof error.statusCode === 'number') {\n return error.statusCode === 429 || error.statusCode >= 500;\n }\n return error.isRetryable;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport interface FallbackModelOptions {\n primary: LanguageModel;\n fallback: LanguageModel;\n logger?: LoggerPort;\n}\n\n/**\n * Creates a `LanguageModelV4` that transparently falls back to a secondary\n * model when the primary model fails with a retryable error (HTTP 429, 5xx,\n * network errors/timeouts). Non-retryable errors (400s, validation, abort)\n * propagate unchanged.\n *\n * This is a model, not a middleware — middleware cannot switch the\n * underlying model, only transform a single model's behavior.\n *\n * @example\n * ```ts\n * const model = createFallbackModel({\n * primary: provider.model('anthropic/claude-sonnet-4'),\n * fallback: provider.model('openai/gpt-4o-mini'),\n * logger,\n * });\n * ```\n */\nexport function createFallbackModel(options: FallbackModelOptions): LanguageModel {\n const { primary, fallback, logger } = options;\n const primaryModel = primary as LanguageModelV4;\n const fallbackModel = fallback as LanguageModelV4;\n\n function logFallback(error: unknown): void {\n logger?.warn('ai.fallback.triggered', {\n modelIds: [primaryModel.modelId, fallbackModel.modelId],\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const model: LanguageModelV4 = {\n specificationVersion: 'v4',\n provider: primaryModel.provider,\n modelId: primaryModel.modelId,\n supportedUrls: primaryModel.supportedUrls,\n\n async doGenerate(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doGenerate(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doGenerate(callOptions);\n }\n },\n\n async doStream(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doStream(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doStream(callOptions);\n }\n },\n };\n\n return model;\n}\n","import type { LanguageModelV4CallOptions, LanguageModelV4Prompt } from '@ai-sdk/provider';\nimport type { LanguageModelMiddleware } from 'ai';\n\nfunction buildInstruction(responseFormat: LanguageModelV4CallOptions['responseFormat']): string {\n if (responseFormat?.type !== 'json') {\n return '';\n }\n\n const lines = ['You must respond with valid JSON only — no prose, no markdown code fences.'];\n if (responseFormat.schema) {\n lines.push(\n 'The JSON must strictly conform to this JSON schema:',\n JSON.stringify(responseFormat.schema),\n );\n }\n return lines.join('\\n');\n}\n\nfunction appendToLastUserMessage(\n prompt: LanguageModelV4Prompt,\n instruction: string,\n): LanguageModelV4Prompt {\n const lastUserIndex = prompt.findLastIndex((message) => message.role === 'user');\n if (lastUserIndex === -1) {\n return [...prompt, { content: [{ text: instruction, type: 'text' }], role: 'user' }];\n }\n\n return prompt.map((message, index) => {\n if (index !== lastUserIndex || message.role !== 'user') {\n return message;\n }\n\n // Merge into the last text part rather than appending a new part:\n // A single-part text message serializes as a plain string, which\n // Proxies and prompt-matching tooling handle more reliably.\n const lastTextIndex = message.content.findLastIndex((part) => part.type === 'text');\n if (lastTextIndex === -1) {\n return {\n ...message,\n content: [...message.content, { text: instruction, type: 'text' as const }],\n };\n }\n\n return {\n ...message,\n content: message.content.map((part, partIndex) => {\n if (partIndex !== lastTextIndex || part.type !== 'text') {\n return part;\n }\n return { ...part, text: `${part.text}\\n\\n${instruction}` };\n }),\n };\n });\n}\n\n/**\n * Creates middleware that injects the JSON schema of a structured-output\n * request into the last user message.\n *\n * Some gateways silently drop the native structured-output field when\n * translating to their backend, so the model never sees the schema and\n * answers in free prose. This middleware re-states the schema as part of the\n * user message so structured output works regardless. It targets the user\n * message rather than a system message because gateways backed by cloaked\n * CLI agents bury injected system messages under their own persona prompt and\n * ignore them. The original `responseFormat` is left untouched: backends that\n * honor it get the native signal too.\n *\n * No-op for text generations (no `responseFormat`, or `type: 'text'`).\n */\nexport function createSchemaInstructionMiddleware(): LanguageModelMiddleware {\n return {\n specificationVersion: 'v4',\n transformParams: ({ params }) => {\n const instruction = buildInstruction(params.responseFormat);\n if (!instruction) {\n return Promise.resolve(params);\n }\n\n return Promise.resolve({\n ...params,\n prompt: appendToLastUserMessage(params.prompt, instruction),\n });\n },\n };\n}\n","import { createOpenAI } from '@ai-sdk/openai';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { extractJsonMiddleware, type LanguageModel, wrapLanguageModel } from 'ai';\n\nimport { createSchemaInstructionMiddleware } from '../middleware/schema-instruction.middleware.js';\n\nexport interface GatewayConfig {\n /** Base URL of the gateway's chat-completions endpoint */\n baseURL: string;\n /** API key for authentication, if required by the endpoint */\n apiKey?: string;\n}\n\nexport interface GatewayProvider {\n /** Get a language model instance for the given model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates a provider for gateways exposing a chat-completions API — any API\n * implementing the OpenAI chat completions spec.\n *\n * Every model returned is automatically wrapped with two safety nets for\n * gateways that don't support native structured output:\n * - `createSchemaInstructionMiddleware` injects the JSON schema into the\n * system prompt (some gateways silently drop `response_format`);\n * - `extractJsonMiddleware` strips markdown code fences from JSON responses.\n *\n * @example\n * ```ts\n * const provider = createGatewayProvider({ baseURL: 'https://gateway.example.com/v1' });\n * const model = provider.model('gpt-4o-mini');\n *\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createGatewayProvider(config: GatewayConfig): GatewayProvider {\n const openai = createOpenAI({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n // Use `.chat()` explicitly rather than the base callable, which\n // Targets the Responses API — most gateways only implement chat\n // Completions.\n return wrapLanguageModel({\n model: openai.chat(id),\n middleware: [createSchemaInstructionMiddleware(), extractJsonMiddleware()],\n });\n },\n };\n}\n","import type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport type { LanguageModel } from 'ai';\n\nexport interface OpenRouterMetadata {\n /** Application name, sent as the `X-OpenRouter-Title` header for dashboard attribution */\n application?: string;\n /** Application URL, sent as the `HTTP-Referer` header for dashboard attribution */\n website?: string;\n}\n\nexport interface OpenRouterConfig {\n apiKey: string;\n metadata?: OpenRouterMetadata;\n}\n\nexport interface OpenRouterProvider {\n /** Get a language model instance for the given OpenRouter model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates an OpenRouter provider for AI SDK models.\n *\n * Per-call options (reasoning effort, max tokens, etc.) are no longer\n * configured here — pass them at the call site via `providerOptions.openrouter`\n * on `generateText`/`streamText`.\n *\n * @example\n * ```ts\n * const provider = createOpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY });\n * const model = provider.model('anthropic/claude-sonnet-4-20250514');\n *\n * const { text } = await generateText({\n * model,\n * prompt: 'Hello!',\n * providerOptions: { openrouter: { reasoning: { effort: 'high' } } },\n * });\n * ```\n */\nexport function createOpenRouterProvider(config: OpenRouterConfig): OpenRouterProvider {\n const openrouter = createOpenRouter({\n apiKey: config.apiKey,\n appName: config.metadata?.application,\n appUrl: config.metadata?.website,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n return openrouter(id);\n },\n };\n}\n","import { OpenTelemetry } from '@ai-sdk/otel';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport { type LanguageModel, registerTelemetry, wrapLanguageModel } from 'ai';\n\nimport { createCostMiddleware } from '../middleware/cost.middleware.js';\nimport { createLoggingMiddleware } from '../middleware/logging.middleware.js';\nimport { createFallbackModel } from '../model/fallback-model.js';\nimport { createGatewayProvider, type GatewayConfig } from '../provider/gateway.provider.js';\nimport {\n createOpenRouterProvider,\n type OpenRouterConfig,\n} from '../provider/openrouter.provider.js';\n\ntype ProviderConfig =\n | (GatewayConfig & { type: 'gateway' })\n | (OpenRouterConfig & { type: 'openrouter' });\n\ninterface ResolvedProvider {\n model: (id: string) => LanguageModel;\n}\n\nlet telemetryRegistered = false;\n\n/**\n * Registers the AI SDK OpenTelemetry integration, once per process. Best\n * effort — if the host app has no OTel SDK configured, `@ai-sdk/otel` spans\n * are simply dropped rather than throwing.\n */\nfunction ensureTelemetryRegistered(): void {\n if (telemetryRegistered) {\n return;\n }\n telemetryRegistered = true;\n\n try {\n registerTelemetry(new OpenTelemetry());\n } catch {\n // Best-effort: telemetry registration must never break the app.\n }\n}\n\nfunction createProvider(config: ProviderConfig): ResolvedProvider {\n switch (config.type) {\n case 'gateway': {\n return createGatewayProvider(config);\n }\n case 'openrouter': {\n return createOpenRouterProvider(config);\n }\n }\n}\n\nfunction assertProviderExists(\n providerKey: string,\n providers: Record<string, ProviderConfig>,\n): void {\n if (providers[providerKey]) {\n return;\n }\n const available = Object.keys(providers).join(', ') || '(none configured)';\n throw new Error(`Unknown provider \"${providerKey}\". Available providers: ${available}.`);\n}\n\nexport type { ProviderConfig };\n\nexport interface ModelRef {\n /** Key into `providers` */\n provider: string;\n /** Technical model id passed through to the provider as-is */\n model: string;\n}\n\nexport interface AgentConfig extends ModelRef {\n /** Model used when the primary `provider`/`model` fails with a retryable error */\n fallback?: ModelRef;\n}\n\nexport interface IntelligenceConfig {\n providers: Record<string, ProviderConfig>;\n agents: Record<string, AgentConfig>;\n /**\n * USD-per-million-token pricing, keyed by `\"<provider>/<model>\"` (the\n * agent's `provider` and `model` joined with `/`, not a provider-side\n * identifier).\n */\n pricing?: Record<string, { input: number; output: number }>;\n logger?: LoggerPort;\n}\n\nexport interface Intelligence {\n /** Get the composed language model for the given agent name */\n model: (agentName: string) => LanguageModel;\n}\n\n/**\n * Creates a composition root over AI SDK v7: resolves each agent's\n * `provider`/`model` pair into a fully instrumented `LanguageModel` — cost\n * tracking, optional fallback, and optional logging — cached per agent name.\n *\n * Registers the `@ai-sdk/otel` telemetry integration on first use (idempotent,\n * best-effort). The host app is expected to have already registered an\n * OpenTelemetry Node SDK (e.g. via `@jterrazz/telemetry`).\n *\n * @example\n * ```ts\n * const intelligence = createIntelligence({\n * providers: {\n * openrouter: { type: 'openrouter', apiKey: process.env.OPENROUTER_API_KEY },\n * },\n * agents: {\n * summarizer: {\n * provider: 'openrouter',\n * model: 'google/gemini-2.5-flash-lite',\n * fallback: { provider: 'openrouter', model: 'openai/gpt-4o-mini' },\n * },\n * },\n * pricing: {\n * 'openrouter/google/gemini-2.5-flash-lite': { input: 0.1, output: 0.4 },\n * },\n * logger,\n * });\n *\n * const model = intelligence.model('summarizer');\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createIntelligence(config: IntelligenceConfig): Intelligence {\n ensureTelemetryRegistered();\n\n const { agents, logger, pricing, providers } = config;\n\n const providerCache = new Map<string, ResolvedProvider>();\n const modelCache = new Map<string, LanguageModel>();\n\n function resolveProvider(providerKey: string): ResolvedProvider {\n let provider = providerCache.get(providerKey);\n if (!provider) {\n provider = createProvider(providers[providerKey]);\n providerCache.set(providerKey, provider);\n }\n return provider;\n }\n\n function buildModel(ref: ModelRef): LanguageModel {\n assertProviderExists(ref.provider, providers);\n\n const provider = resolveProvider(ref.provider);\n const baseModel = provider.model(ref.model) as LanguageModelV4;\n const pricingKey = `${ref.provider}/${ref.model}`;\n\n return wrapLanguageModel({\n model: baseModel,\n middleware: [\n createCostMiddleware({ modelRef: pricingKey, pricing: pricing?.[pricingKey] }),\n ],\n });\n }\n\n function buildAgentModel(agentName: string): LanguageModel {\n const agentConfig = agents[agentName];\n if (!agentConfig) {\n const available = Object.keys(agents).join(', ') || '(none configured)';\n throw new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n }\n\n const primary = buildModel({ model: agentConfig.model, provider: agentConfig.provider });\n const composed = agentConfig.fallback\n ? createFallbackModel({\n fallback: buildModel(agentConfig.fallback),\n logger,\n primary,\n })\n : primary;\n\n if (!logger) {\n return composed;\n }\n\n return wrapLanguageModel({\n model: composed as LanguageModelV4,\n middleware: [createLoggingMiddleware({ logger })],\n });\n }\n\n return {\n model(agentName: string): LanguageModel {\n let model = modelCache.get(agentName);\n if (!model) {\n model = buildAgentModel(agentName);\n modelCache.set(agentName, model);\n }\n return model;\n },\n };\n}\n"],"x_google_ignoreList":[2],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["trace","OpenTelemetry"],"sources":["../src/middleware/agent.middleware.ts","../src/middleware/cost.middleware.ts","../src/middleware/logging.middleware.ts","../node_modules/@ai-sdk/provider/dist/index.js","../src/model/fallback-model.ts","../src/middleware/schema-instruction.middleware.ts","../src/provider/gateway.provider.ts","../src/provider/openrouter.provider.ts","../src/factory/create-intelligence.ts"],"sourcesContent":["import { trace } from '@opentelemetry/api';\nimport type { LanguageModelMiddleware } from 'ai';\n\nconst AGENT_ATTRIBUTE = 'gen_ai.agent.name';\n\nexport interface AgentMiddlewareOptions {\n /** The agent this model serves — becomes the generation's name in Langfuse */\n agentName: string;\n}\n\n/**\n * Creates middleware that names the AI SDK's inference span after the agent.\n *\n * The AI SDK names that span `chat <model>` and only puts the agent identity\n * (`gen_ai.agent.name`, from `experimental_telemetry.functionId`) on the\n * parent `invoke_agent` span. Langfuse extracts model, usage and cost from\n * the inference span alone, so a pipeline that forwards only that span would\n * otherwise show every agent as \"chat <model>\". This runs inside the\n * inference span's context (the AI SDK activates it for the provider call),\n * so the active span is the right one.\n *\n * Never throws: all enrichment is best-effort.\n */\nexport function createAgentMiddleware(options: AgentMiddlewareOptions): LanguageModelMiddleware {\n const { agentName } = options;\n\n const nameActiveSpan = (): void => {\n try {\n const span = trace.getActiveSpan();\n if (!span) {\n return;\n }\n span.updateName(agentName);\n span.setAttribute(AGENT_ATTRIBUTE, agentName);\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n };\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate }) => {\n nameActiveSpan();\n return doGenerate();\n },\n wrapStream: async ({ doStream }) => {\n nameActiveSpan();\n return doStream();\n },\n };\n}\n","import type { LanguageModelV4StreamPart, LanguageModelV4Usage } from '@ai-sdk/provider';\nimport { trace } from '@opentelemetry/api';\nimport type { LanguageModelMiddleware } from 'ai';\n\nconst COST_ATTRIBUTE = 'gen_ai.usage.cost';\n\ninterface OpenRouterCostMetadata {\n openrouter?: {\n usage?: {\n cost?: number;\n };\n };\n}\n\ninterface CostPricing {\n /** USD per million input tokens */\n input: number;\n /** USD per million output tokens */\n output: number;\n}\n\nfunction resolveCost(\n providerMetadata: Record<string, unknown> | undefined,\n usage: LanguageModelV4Usage | undefined,\n pricing: CostPricing | undefined,\n): number | undefined {\n const actualCost = (providerMetadata as OpenRouterCostMetadata | undefined)?.openrouter?.usage\n ?.cost;\n if (typeof actualCost === 'number' && actualCost > 0) {\n return actualCost;\n }\n\n if (pricing) {\n const inputTokens = usage?.inputTokens?.total ?? 0;\n const outputTokens = usage?.outputTokens?.total ?? 0;\n return (\n (inputTokens / 1_000_000) * pricing.input + (outputTokens / 1_000_000) * pricing.output\n );\n }\n\n return undefined;\n}\n\nfunction recordCost(cost: number | undefined): void {\n if (cost === undefined) {\n return;\n }\n trace.getActiveSpan()?.setAttribute(COST_ATTRIBUTE, cost);\n}\n\nexport type { CostPricing };\n\nexport interface CostMiddlewareOptions {\n /** Fallback USD-per-million-token pricing, used when the provider doesn't report actual cost */\n pricing?: CostPricing;\n}\n\n/**\n * Creates middleware that records the USD cost of a generation as\n * `gen_ai.usage.cost` on the active OpenTelemetry span — the AI SDK's own\n * inference span (`gen_ai.operation.name = chat`), which is what Langfuse\n * ingests as a generation.\n *\n * Resolution order:\n * 1. Actual cost reported by the provider (currently: OpenRouter's\n * `providerMetadata.openrouter.usage.cost`).\n * 2. Estimated cost from `pricing` (USD per million input/output tokens),\n * computed from the reported token usage.\n *\n * When neither is available nothing is written: `gen_ai.request.model` is\n * left to the AI SDK (the bare model id), so Langfuse can still price the\n * generation from its own model catalogue. Langfuse prioritizes\n * `gen_ai.usage.cost` over that inference when both exist.\n *\n * Never throws: all enrichment is best-effort.\n *\n * @example\n * ```ts\n * const model = wrapLanguageModel({\n * model: provider.model('google/gemini-2.5-flash-lite'),\n * middleware: [createCostMiddleware({ pricing: { input: 0.1, output: 0.4 } })],\n * });\n * ```\n */\nexport function createCostMiddleware(options: CostMiddlewareOptions = {}): LanguageModelMiddleware {\n const { pricing } = options;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate }) => {\n const result = await doGenerate();\n\n try {\n recordCost(\n resolveCost(\n result.providerMetadata as Record<string, unknown> | undefined,\n result.usage,\n pricing,\n ),\n );\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n\n return result;\n },\n\n wrapStream: async ({ doStream }) => {\n const result = await doStream();\n\n let finishUsage: LanguageModelV4Usage | undefined;\n let finishProviderMetadata: Record<string, unknown> | undefined;\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'finish') {\n finishUsage = chunk.usage;\n finishProviderMetadata = chunk.providerMetadata as\n | Record<string, unknown>\n | undefined;\n }\n controller.enqueue(chunk);\n },\n flush() {\n try {\n recordCost(resolveCost(finishProviderMetadata, finishUsage, pricing));\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n },\n });\n\n return {\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n },\n };\n}\n","import type { LanguageModelV4StreamPart } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModelMiddleware } from 'ai';\n\nexport interface LoggingMiddlewareOptions {\n logger: LoggerPort;\n include?: {\n params?: boolean;\n content?: boolean;\n usage?: boolean;\n };\n}\n\n/**\n * Creates middleware that logs AI SDK requests and responses.\n */\nexport function createLoggingMiddleware(\n options: LoggingMiddlewareOptions,\n): LanguageModelMiddleware {\n const { logger, include = {} } = options;\n const { params: includeParams, content: includeContent, usage: includeUsage = true } = include;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.generate.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doGenerate();\n\n // Extract text from content\n const textContent = result.content\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n logger.debug('ai.generate.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n finishReason: result.finishReason,\n ...(includeUsage && { usage: result.usage }),\n ...(includeContent && { content: textContent }),\n });\n\n return result;\n } catch (error) {\n logger.error('ai.generate.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n\n wrapStream: async ({ doStream, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.stream.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doStream();\n\n const chunks: string[] = [];\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (includeContent && chunk.type === 'text-delta') {\n chunks.push(chunk.delta);\n }\n controller.enqueue(chunk);\n },\n flush() {\n logger.debug('ai.stream.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n ...(includeContent && { content: chunks.join('') }),\n });\n },\n });\n\n return {\n specificationVersion: 'v4',\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n } catch (error) {\n logger.error('ai.stream.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n };\n}\n","// src/errors/ai-sdk-error.ts\nvar marker = \"vercel.ai.error\";\nvar symbol = Symbol.for(marker);\nvar _a, _b;\nvar AISDKError = class _AISDKError extends (_b = Error, _a = symbol, _b) {\n /**\n * Creates an AI SDK Error.\n *\n * @param {Object} params - The parameters for creating the error.\n * @param {string} params.name - The name of the error.\n * @param {string} params.message - The error message.\n * @param {unknown} [params.cause] - The underlying cause of the error.\n */\n constructor({\n name: name15,\n message,\n cause\n }) {\n super(message);\n this[_a] = true;\n this.name = name15;\n this.cause = cause;\n }\n /**\n * Checks if the given error is an AI SDK Error.\n * @param {unknown} error - The error to check.\n * @returns {boolean} True if the error is an AI SDK Error, false otherwise.\n */\n static isInstance(error) {\n return _AISDKError.hasMarker(error, marker);\n }\n static hasMarker(error, marker16) {\n const markerSymbol = Symbol.for(marker16);\n return error != null && typeof error === \"object\" && markerSymbol in error && typeof error[markerSymbol] === \"boolean\" && error[markerSymbol] === true;\n }\n};\n\n// src/errors/api-call-error.ts\nvar name = \"AI_APICallError\";\nvar marker2 = `vercel.ai.error.${name}`;\nvar symbol2 = Symbol.for(marker2);\nvar _a2, _b2;\nvar APICallError = class extends (_b2 = AISDKError, _a2 = symbol2, _b2) {\n constructor({\n message,\n url,\n requestBodyValues,\n statusCode,\n responseHeaders,\n responseBody,\n cause,\n isRetryable = statusCode != null && (statusCode === 408 || // request timeout\n statusCode === 409 || // conflict\n statusCode === 429 || // too many requests\n statusCode >= 500),\n // server error\n data\n }) {\n super({ name, message, cause });\n this[_a2] = true;\n this.url = url;\n this.requestBodyValues = requestBodyValues;\n this.statusCode = statusCode;\n this.responseHeaders = responseHeaders;\n this.responseBody = responseBody;\n this.isRetryable = isRetryable;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker2);\n }\n};\n\n// src/errors/empty-response-body-error.ts\nvar name2 = \"AI_EmptyResponseBodyError\";\nvar marker3 = `vercel.ai.error.${name2}`;\nvar symbol3 = Symbol.for(marker3);\nvar _a3, _b3;\nvar EmptyResponseBodyError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) {\n // used in isInstance\n constructor({ message = \"Empty response body\" } = {}) {\n super({ name: name2, message });\n this[_a3] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker3);\n }\n};\n\n// src/errors/get-error-message.ts\nfunction getErrorMessage(error) {\n if (error == null) {\n return \"unknown error\";\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error instanceof Error) {\n return error.toString();\n }\n return JSON.stringify(error);\n}\n\n// src/errors/invalid-argument-error.ts\nvar name3 = \"AI_InvalidArgumentError\";\nvar marker4 = `vercel.ai.error.${name3}`;\nvar symbol4 = Symbol.for(marker4);\nvar _a4, _b4;\nvar InvalidArgumentError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) {\n constructor({\n message,\n cause,\n argument\n }) {\n super({ name: name3, message, cause });\n this[_a4] = true;\n this.argument = argument;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker4);\n }\n};\n\n// src/errors/invalid-prompt-error.ts\nvar name4 = \"AI_InvalidPromptError\";\nvar marker5 = `vercel.ai.error.${name4}`;\nvar symbol5 = Symbol.for(marker5);\nvar _a5, _b5;\nvar InvalidPromptError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) {\n constructor({\n prompt,\n message,\n cause\n }) {\n super({ name: name4, message: `Invalid prompt: ${message}`, cause });\n this[_a5] = true;\n this.prompt = prompt;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker5);\n }\n};\n\n// src/errors/invalid-response-data-error.ts\nvar name5 = \"AI_InvalidResponseDataError\";\nvar marker6 = `vercel.ai.error.${name5}`;\nvar symbol6 = Symbol.for(marker6);\nvar _a6, _b6;\nvar InvalidResponseDataError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) {\n constructor({\n data,\n message = `Invalid response data: ${JSON.stringify(data)}.`\n }) {\n super({ name: name5, message });\n this[_a6] = true;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker6);\n }\n};\n\n// src/errors/json-parse-error.ts\nvar name6 = \"AI_JSONParseError\";\nvar marker7 = `vercel.ai.error.${name6}`;\nvar symbol7 = Symbol.for(marker7);\nvar _a7, _b7;\nvar JSONParseError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) {\n constructor({ text, cause }) {\n super({\n name: name6,\n message: `JSON parsing failed: Text: ${text}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a7] = true;\n this.text = text;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker7);\n }\n};\n\n// src/errors/load-api-key-error.ts\nvar name7 = \"AI_LoadAPIKeyError\";\nvar marker8 = `vercel.ai.error.${name7}`;\nvar symbol8 = Symbol.for(marker8);\nvar _a8, _b8;\nvar LoadAPIKeyError = class extends (_b8 = AISDKError, _a8 = symbol8, _b8) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name7, message });\n this[_a8] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker8);\n }\n};\n\n// src/errors/load-setting-error.ts\nvar name8 = \"AI_LoadSettingError\";\nvar marker9 = `vercel.ai.error.${name8}`;\nvar symbol9 = Symbol.for(marker9);\nvar _a9, _b9;\nvar LoadSettingError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name8, message });\n this[_a9] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker9);\n }\n};\n\n// src/errors/no-content-generated-error.ts\nvar name9 = \"AI_NoContentGeneratedError\";\nvar marker10 = `vercel.ai.error.${name9}`;\nvar symbol10 = Symbol.for(marker10);\nvar _a10, _b10;\nvar NoContentGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) {\n // used in isInstance\n constructor({\n message = \"No content generated.\"\n } = {}) {\n super({ name: name9, message });\n this[_a10] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker10);\n }\n};\n\n// src/errors/no-such-model-error.ts\nvar name10 = \"AI_NoSuchModelError\";\nvar marker11 = `vercel.ai.error.${name10}`;\nvar symbol11 = Symbol.for(marker11);\nvar _a11, _b11;\nvar NoSuchModelError = class extends (_b11 = AISDKError, _a11 = symbol11, _b11) {\n constructor({\n errorName = name10,\n modelId,\n modelType,\n message = `No such ${modelType}: ${modelId}`\n }) {\n super({ name: errorName, message });\n this[_a11] = true;\n this.modelId = modelId;\n this.modelType = modelType;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker11);\n }\n};\n\n// src/errors/no-such-provider-reference-error.ts\nvar name11 = \"AI_NoSuchProviderReferenceError\";\nvar marker12 = `vercel.ai.error.${name11}`;\nvar symbol12 = Symbol.for(marker12);\nvar _a12, _b12;\nvar NoSuchProviderReferenceError = class extends (_b12 = AISDKError, _a12 = symbol12, _b12) {\n constructor({\n provider,\n reference,\n message = `No provider reference found for provider '${provider}'. Available providers: ${Object.keys(reference).join(\", \")}`\n }) {\n super({ name: name11, message });\n this[_a12] = true;\n this.provider = provider;\n this.reference = reference;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker12);\n }\n};\n\n// src/errors/too-many-embedding-values-for-call-error.ts\nvar name12 = \"AI_TooManyEmbeddingValuesForCallError\";\nvar marker13 = `vercel.ai.error.${name12}`;\nvar symbol13 = Symbol.for(marker13);\nvar _a13, _b13;\nvar TooManyEmbeddingValuesForCallError = class extends (_b13 = AISDKError, _a13 = symbol13, _b13) {\n constructor(options) {\n super({\n name: name12,\n message: `Too many values for a single embedding call. The ${options.provider} model \"${options.modelId}\" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`\n });\n this[_a13] = true;\n this.provider = options.provider;\n this.modelId = options.modelId;\n this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;\n this.values = options.values;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker13);\n }\n};\n\n// src/errors/type-validation-error.ts\nvar name13 = \"AI_TypeValidationError\";\nvar marker14 = `vercel.ai.error.${name13}`;\nvar symbol14 = Symbol.for(marker14);\nvar _a14, _b14;\nvar TypeValidationError = class _TypeValidationError extends (_b14 = AISDKError, _a14 = symbol14, _b14) {\n constructor({\n value,\n cause,\n context\n }) {\n let contextPrefix = \"Type validation failed\";\n if (context == null ? void 0 : context.field) {\n contextPrefix += ` for ${context.field}`;\n }\n if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) {\n contextPrefix += \" (\";\n const parts = [];\n if (context.entityName) {\n parts.push(context.entityName);\n }\n if (context.entityId) {\n parts.push(`id: \"${context.entityId}\"`);\n }\n contextPrefix += parts.join(\", \");\n contextPrefix += \")\";\n }\n super({\n name: name13,\n message: `${contextPrefix}: Value: ${JSON.stringify(value)}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a14] = true;\n this.value = value;\n this.context = context;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker14);\n }\n /**\n * Wraps an error into a TypeValidationError.\n * If the cause is already a TypeValidationError with the same value and context, it returns the cause.\n * Otherwise, it creates a new TypeValidationError.\n *\n * @param {Object} params - The parameters for wrapping the error.\n * @param {unknown} params.value - The value that failed validation.\n * @param {unknown} params.cause - The original error or cause of the validation failure.\n * @param {TypeValidationContext} params.context - Optional context about what is being validated.\n * @returns {TypeValidationError} A TypeValidationError instance.\n */\n static wrap({\n value,\n cause,\n context\n }) {\n var _a16, _b16, _c;\n if (_TypeValidationError.isInstance(cause) && cause.value === value && ((_a16 = cause.context) == null ? void 0 : _a16.field) === (context == null ? void 0 : context.field) && ((_b16 = cause.context) == null ? void 0 : _b16.entityName) === (context == null ? void 0 : context.entityName) && ((_c = cause.context) == null ? void 0 : _c.entityId) === (context == null ? void 0 : context.entityId)) {\n return cause;\n }\n return new _TypeValidationError({ value, cause, context });\n }\n};\n\n// src/errors/unsupported-functionality-error.ts\nvar name14 = \"AI_UnsupportedFunctionalityError\";\nvar marker15 = `vercel.ai.error.${name14}`;\nvar symbol15 = Symbol.for(marker15);\nvar _a15, _b15;\nvar UnsupportedFunctionalityError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) {\n constructor({\n functionality,\n message = `'${functionality}' functionality not supported.`\n }) {\n super({ name: name14, message });\n this[_a15] = true;\n this.functionality = functionality;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker15);\n }\n};\n\n// src/json-value/is-json.ts\nfunction isJSONValue(value) {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(isJSONValue);\n }\n if (typeof value === \"object\") {\n return Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n }\n return false;\n}\nfunction isJSONArray(value) {\n return Array.isArray(value) && value.every(isJSONValue);\n}\nfunction isJSONObject(value) {\n return value != null && typeof value === \"object\" && Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n}\nexport {\n AISDKError,\n APICallError,\n EmptyResponseBodyError,\n InvalidArgumentError,\n InvalidPromptError,\n InvalidResponseDataError,\n JSONParseError,\n LoadAPIKeyError,\n LoadSettingError,\n NoContentGeneratedError,\n NoSuchModelError,\n NoSuchProviderReferenceError,\n TooManyEmbeddingValuesForCallError,\n TypeValidationError,\n UnsupportedFunctionalityError,\n getErrorMessage,\n isJSONArray,\n isJSONObject,\n isJSONValue\n};\n//# sourceMappingURL=index.js.map","import {\n APICallError,\n type LanguageModelV4,\n type LanguageModelV4CallOptions,\n} from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModel } from 'ai';\n\nconst RETRYABLE_MESSAGE_PATTERNS = [\n /ECONNREFUSED/i,\n /ECONNRESET/i,\n /ETIMEDOUT/i,\n /EAI_AGAIN/i,\n /ENOTFOUND/i,\n /timed?\\s*out/i,\n /network/i,\n /fetch failed/i,\n];\n\nfunction isRetryableError(error: unknown): boolean {\n if (APICallError.isInstance(error)) {\n if (typeof error.statusCode === 'number') {\n return error.statusCode === 429 || error.statusCode >= 500;\n }\n return error.isRetryable;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport interface FallbackModelOptions {\n primary: LanguageModel;\n fallback: LanguageModel;\n logger?: LoggerPort;\n}\n\n/**\n * Creates a `LanguageModelV4` that transparently falls back to a secondary\n * model when the primary model fails with a retryable error (HTTP 429, 5xx,\n * network errors/timeouts). Non-retryable errors (400s, validation, abort)\n * propagate unchanged.\n *\n * This is a model, not a middleware — middleware cannot switch the\n * underlying model, only transform a single model's behavior.\n *\n * @example\n * ```ts\n * const model = createFallbackModel({\n * primary: provider.model('anthropic/claude-sonnet-4'),\n * fallback: provider.model('openai/gpt-4o-mini'),\n * logger,\n * });\n * ```\n */\nexport function createFallbackModel(options: FallbackModelOptions): LanguageModel {\n const { primary, fallback, logger } = options;\n const primaryModel = primary as LanguageModelV4;\n const fallbackModel = fallback as LanguageModelV4;\n\n function logFallback(error: unknown): void {\n logger?.warn('ai.fallback.triggered', {\n modelIds: [primaryModel.modelId, fallbackModel.modelId],\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const model: LanguageModelV4 = {\n specificationVersion: 'v4',\n provider: primaryModel.provider,\n modelId: primaryModel.modelId,\n supportedUrls: primaryModel.supportedUrls,\n\n async doGenerate(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doGenerate(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doGenerate(callOptions);\n }\n },\n\n async doStream(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doStream(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doStream(callOptions);\n }\n },\n };\n\n return model;\n}\n","import type { LanguageModelV4CallOptions, LanguageModelV4Prompt } from '@ai-sdk/provider';\nimport type { LanguageModelMiddleware } from 'ai';\n\nfunction buildInstruction(responseFormat: LanguageModelV4CallOptions['responseFormat']): string {\n if (responseFormat?.type !== 'json') {\n return '';\n }\n\n const lines = ['You must respond with valid JSON only — no prose, no markdown code fences.'];\n if (responseFormat.schema) {\n lines.push(\n 'The JSON must strictly conform to this JSON schema:',\n JSON.stringify(responseFormat.schema),\n );\n }\n return lines.join('\\n');\n}\n\nfunction appendToLastUserMessage(\n prompt: LanguageModelV4Prompt,\n instruction: string,\n): LanguageModelV4Prompt {\n const lastUserIndex = prompt.findLastIndex((message) => message.role === 'user');\n if (lastUserIndex === -1) {\n return [...prompt, { content: [{ text: instruction, type: 'text' }], role: 'user' }];\n }\n\n return prompt.map((message, index) => {\n if (index !== lastUserIndex || message.role !== 'user') {\n return message;\n }\n\n // Merge into the last text part rather than appending a new part:\n // A single-part text message serializes as a plain string, which\n // Proxies and prompt-matching tooling handle more reliably.\n const lastTextIndex = message.content.findLastIndex((part) => part.type === 'text');\n if (lastTextIndex === -1) {\n return {\n ...message,\n content: [...message.content, { text: instruction, type: 'text' as const }],\n };\n }\n\n return {\n ...message,\n content: message.content.map((part, partIndex) => {\n if (partIndex !== lastTextIndex || part.type !== 'text') {\n return part;\n }\n return { ...part, text: `${part.text}\\n\\n${instruction}` };\n }),\n };\n });\n}\n\n/**\n * Creates middleware that injects the JSON schema of a structured-output\n * request into the last user message.\n *\n * Some gateways silently drop the native structured-output field when\n * translating to their backend, so the model never sees the schema and\n * answers in free prose. This middleware re-states the schema as part of the\n * user message so structured output works regardless. It targets the user\n * message rather than a system message because gateways backed by cloaked\n * CLI agents bury injected system messages under their own persona prompt and\n * ignore them. The original `responseFormat` is left untouched: backends that\n * honor it get the native signal too.\n *\n * No-op for text generations (no `responseFormat`, or `type: 'text'`).\n */\nexport function createSchemaInstructionMiddleware(): LanguageModelMiddleware {\n return {\n specificationVersion: 'v4',\n transformParams: ({ params }) => {\n const instruction = buildInstruction(params.responseFormat);\n if (!instruction) {\n return Promise.resolve(params);\n }\n\n return Promise.resolve({\n ...params,\n prompt: appendToLastUserMessage(params.prompt, instruction),\n });\n },\n };\n}\n","import { createOpenAI } from '@ai-sdk/openai';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { extractJsonMiddleware, type LanguageModel, wrapLanguageModel } from 'ai';\n\nimport { createSchemaInstructionMiddleware } from '../middleware/schema-instruction.middleware.js';\n\nexport interface GatewayConfig {\n /** Base URL of the gateway's chat-completions endpoint */\n baseURL: string;\n /** API key for authentication, if required by the endpoint */\n apiKey?: string;\n}\n\nexport interface GatewayProvider {\n /** Get a language model instance for the given model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates a provider for gateways exposing a chat-completions API — any API\n * implementing the OpenAI chat completions spec.\n *\n * Every model returned is automatically wrapped with two safety nets for\n * gateways that don't support native structured output:\n * - `createSchemaInstructionMiddleware` injects the JSON schema into the\n * system prompt (some gateways silently drop `response_format`);\n * - `extractJsonMiddleware` strips markdown code fences from JSON responses.\n *\n * @example\n * ```ts\n * const provider = createGatewayProvider({ baseURL: 'https://gateway.example.com/v1' });\n * const model = provider.model('gpt-4o-mini');\n *\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createGatewayProvider(config: GatewayConfig): GatewayProvider {\n const openai = createOpenAI({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n // Use `.chat()` explicitly rather than the base callable, which\n // Targets the Responses API — most gateways only implement chat\n // Completions.\n return wrapLanguageModel({\n model: openai.chat(id),\n middleware: [createSchemaInstructionMiddleware(), extractJsonMiddleware()],\n });\n },\n };\n}\n","import type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport type { LanguageModel } from 'ai';\n\nexport interface OpenRouterMetadata {\n /** Application name, sent as the `X-OpenRouter-Title` header for dashboard attribution */\n application?: string;\n /** Application URL, sent as the `HTTP-Referer` header for dashboard attribution */\n website?: string;\n}\n\nexport interface OpenRouterConfig {\n apiKey: string;\n metadata?: OpenRouterMetadata;\n}\n\nexport interface OpenRouterProvider {\n /** Get a language model instance for the given OpenRouter model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates an OpenRouter provider for AI SDK models.\n *\n * Per-call options (reasoning effort, max tokens, etc.) are no longer\n * configured here — pass them at the call site via `providerOptions.openrouter`\n * on `generateText`/`streamText`.\n *\n * @example\n * ```ts\n * const provider = createOpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY });\n * const model = provider.model('anthropic/claude-sonnet-4-20250514');\n *\n * const { text } = await generateText({\n * model,\n * prompt: 'Hello!',\n * providerOptions: { openrouter: { reasoning: { effort: 'high' } } },\n * });\n * ```\n */\nexport function createOpenRouterProvider(config: OpenRouterConfig): OpenRouterProvider {\n const openrouter = createOpenRouter({\n apiKey: config.apiKey,\n appName: config.metadata?.application,\n appUrl: config.metadata?.website,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n return openrouter(id);\n },\n };\n}\n","import { OpenTelemetry } from '@ai-sdk/otel';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport { type LanguageModel, registerTelemetry, wrapLanguageModel } from 'ai';\n\nimport { createAgentMiddleware } from '../middleware/agent.middleware.js';\nimport { createCostMiddleware } from '../middleware/cost.middleware.js';\nimport { createLoggingMiddleware } from '../middleware/logging.middleware.js';\nimport { createFallbackModel } from '../model/fallback-model.js';\nimport { createGatewayProvider, type GatewayConfig } from '../provider/gateway.provider.js';\nimport {\n createOpenRouterProvider,\n type OpenRouterConfig,\n} from '../provider/openrouter.provider.js';\n\ntype ProviderConfig =\n | (GatewayConfig & { type: 'gateway' })\n | (OpenRouterConfig & { type: 'openrouter' });\n\ninterface ResolvedProvider {\n model: (id: string) => LanguageModel;\n}\n\nlet telemetryRegistered = false;\n\n/**\n * Registers the AI SDK OpenTelemetry integration, once per process. Best\n * effort — if the host app has no OTel SDK configured, `@ai-sdk/otel` spans\n * are simply dropped rather than throwing.\n */\nfunction ensureTelemetryRegistered(): void {\n if (telemetryRegistered) {\n return;\n }\n telemetryRegistered = true;\n\n try {\n registerTelemetry(new OpenTelemetry());\n } catch {\n // Best-effort: telemetry registration must never break the app.\n }\n}\n\nfunction createProvider(config: ProviderConfig): ResolvedProvider {\n switch (config.type) {\n case 'gateway': {\n return createGatewayProvider(config);\n }\n case 'openrouter': {\n return createOpenRouterProvider(config);\n }\n }\n}\n\nfunction assertProviderExists(\n providerKey: string,\n providers: Record<string, ProviderConfig>,\n): void {\n if (providers[providerKey]) {\n return;\n }\n const available = Object.keys(providers).join(', ') || '(none configured)';\n throw new Error(`Unknown provider \"${providerKey}\". Available providers: ${available}.`);\n}\n\nexport type { ProviderConfig };\n\nexport interface ModelRef {\n /** Key into `providers` */\n provider: string;\n /** Technical model id passed through to the provider as-is */\n model: string;\n}\n\nexport interface AgentConfig extends ModelRef {\n /** Model used when the primary `provider`/`model` fails with a retryable error */\n fallback?: ModelRef;\n}\n\nexport interface IntelligenceConfig {\n providers: Record<string, ProviderConfig>;\n agents: Record<string, AgentConfig>;\n /**\n * USD-per-million-token pricing, keyed by `\"<provider>/<model>\"` (the\n * agent's `provider` and `model` joined with `/`, not a provider-side\n * identifier).\n */\n pricing?: Record<string, { input: number; output: number }>;\n logger?: LoggerPort;\n}\n\nexport interface Intelligence {\n /** Get the composed language model for the given agent name */\n model: (agentName: string) => LanguageModel;\n}\n\n/**\n * Creates a composition root over AI SDK v7: resolves each agent's\n * `provider`/`model` pair into a fully instrumented `LanguageModel` — cost\n * tracking, optional fallback, and optional logging — cached per agent name.\n *\n * Registers the `@ai-sdk/otel` telemetry integration on first use (idempotent,\n * best-effort). The host app is expected to have already registered an\n * OpenTelemetry Node SDK (e.g. via `@jterrazz/telemetry`).\n *\n * @example\n * ```ts\n * const intelligence = createIntelligence({\n * providers: {\n * openrouter: { type: 'openrouter', apiKey: process.env.OPENROUTER_API_KEY },\n * },\n * agents: {\n * summarizer: {\n * provider: 'openrouter',\n * model: 'google/gemini-2.5-flash-lite',\n * fallback: { provider: 'openrouter', model: 'openai/gpt-4o-mini' },\n * },\n * },\n * pricing: {\n * 'openrouter/google/gemini-2.5-flash-lite': { input: 0.1, output: 0.4 },\n * },\n * logger,\n * });\n *\n * const model = intelligence.model('summarizer');\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createIntelligence(config: IntelligenceConfig): Intelligence {\n ensureTelemetryRegistered();\n\n const { agents, logger, pricing, providers } = config;\n\n const providerCache = new Map<string, ResolvedProvider>();\n const modelCache = new Map<string, LanguageModel>();\n\n function resolveProvider(providerKey: string): ResolvedProvider {\n let provider = providerCache.get(providerKey);\n if (!provider) {\n provider = createProvider(providers[providerKey]);\n providerCache.set(providerKey, provider);\n }\n return provider;\n }\n\n function buildModel(ref: ModelRef, agentName: string): LanguageModel {\n assertProviderExists(ref.provider, providers);\n\n const provider = resolveProvider(ref.provider);\n const baseModel = provider.model(ref.model) as LanguageModelV4;\n\n return wrapLanguageModel({\n model: baseModel,\n middleware: [\n createAgentMiddleware({ agentName }),\n createCostMiddleware({ pricing: pricing?.[`${ref.provider}/${ref.model}`] }),\n ],\n });\n }\n\n function buildAgentModel(agentName: string): LanguageModel {\n const agentConfig = agents[agentName];\n if (!agentConfig) {\n const available = Object.keys(agents).join(', ') || '(none configured)';\n throw new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n }\n\n const primary = buildModel(\n { model: agentConfig.model, provider: agentConfig.provider },\n agentName,\n );\n const composed = agentConfig.fallback\n ? createFallbackModel({\n fallback: buildModel(agentConfig.fallback, agentName),\n logger,\n primary,\n })\n : primary;\n\n if (!logger) {\n return composed;\n }\n\n return wrapLanguageModel({\n model: composed as LanguageModelV4,\n middleware: [createLoggingMiddleware({ logger })],\n });\n }\n\n return {\n model(agentName: string): LanguageModel {\n let model = modelCache.get(agentName);\n if (!model) {\n model = buildAgentModel(agentName);\n modelCache.set(agentName, model);\n }\n return model;\n },\n };\n}\n"],"x_google_ignoreList":[3],"mappings":";;;;;;;AAGA,MAAM,kBAAkB;;;;;;;;;;;;;;AAoBxB,SAAgB,sBAAsB,SAA0D;CAC5F,MAAM,EAAE,cAAc;CAEtB,MAAM,uBAA6B;EAC/B,IAAI;GACA,MAAM,OAAOA,mBAAAA,MAAM,cAAc;GACjC,IAAI,CAAC,MACD;GAEJ,KAAK,WAAW,SAAS;GACzB,KAAK,aAAa,iBAAiB,SAAS;EAChD,QAAQ,CAER;CACJ;CAEA,OAAO;EACH,sBAAsB;EACtB,cAAc,OAAO,EAAE,iBAAiB;GACpC,eAAe;GACf,OAAO,WAAW;EACtB;EACA,YAAY,OAAO,EAAE,eAAe;GAChC,eAAe;GACf,OAAO,SAAS;EACpB;CACJ;AACJ;;;AC9CA,MAAM,iBAAiB;AAiBvB,SAAS,YACL,kBACA,OACA,SACkB;CAClB,MAAM,aAAc,kBAAyD,YAAY,OACnF;CACN,IAAI,OAAO,eAAe,YAAY,aAAa,GAC/C,OAAO;CAGX,IAAI,SAAS;EACT,MAAM,cAAc,OAAO,aAAa,SAAS;EACjD,MAAM,eAAe,OAAO,cAAc,SAAS;EACnD,OACK,cAAc,MAAa,QAAQ,QAAS,eAAe,MAAa,QAAQ;CAEzF;AAGJ;AAEA,SAAS,WAAW,MAAgC;CAChD,IAAI,SAAS,KAAA,GACT;CAEJ,mBAAA,MAAM,cAAc,CAAC,EAAE,aAAa,gBAAgB,IAAI;AAC5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,qBAAqB,UAAiC,CAAC,GAA4B;CAC/F,MAAM,EAAE,YAAY;CAEpB,OAAO;EACH,sBAAsB;EACtB,cAAc,OAAO,EAAE,iBAAiB;GACpC,MAAM,SAAS,MAAM,WAAW;GAEhC,IAAI;IACA,WACI,YACI,OAAO,kBACP,OAAO,OACP,OACJ,CACJ;GACJ,QAAQ,CAER;GAEA,OAAO;EACX;EAEA,YAAY,OAAO,EAAE,eAAe;GAChC,MAAM,SAAS,MAAM,SAAS;GAE9B,IAAI;GACJ,IAAI;GAEJ,MAAM,kBAAkB,IAAI,gBAG1B;IACE,UAAU,OAAO,YAAY;KACzB,IAAI,MAAM,SAAS,UAAU;MACzB,cAAc,MAAM;MACpB,yBAAyB,MAAM;KAGnC;KACA,WAAW,QAAQ,KAAK;IAC5B;IACA,QAAQ;KACJ,IAAI;MACA,WAAW,YAAY,wBAAwB,aAAa,OAAO,CAAC;KACxE,QAAQ,CAER;IACJ;GACJ,CAAC;GAED,OAAO;IACH,GAAG;IACH,QAAQ,OAAO,OAAO,YAAY,eAAe;GACrD;EACJ;CACJ;AACJ;;;;;;AC7HA,SAAgB,wBACZ,SACuB;CACvB,MAAM,EAAE,QAAQ,UAAU,CAAC,MAAM;CACjC,MAAM,EAAE,QAAQ,eAAe,SAAS,gBAAgB,OAAO,eAAe,SAAS;CAEvF,OAAO;EACH,sBAAsB;EACtB,cAAc,OAAO,EAAE,YAAY,QAAQ,YAAY;GACnD,MAAM,YAAY,KAAK,IAAI;GAE3B,OAAO,MAAM,qBAAqB;IAC9B,OAAO,MAAM;IACb,GAAI,iBAAiB,EAAE,OAAO;GAClC,CAAC;GAED,IAAI;IACA,MAAM,SAAS,MAAM,WAAW;IAGhC,MAAM,cAAc,OAAO,QACtB,QAAQ,MAA2C,EAAE,SAAS,MAAM,CAAC,CACrE,KAAK,MAAM,EAAE,IAAI,CAAC,CAClB,KAAK,EAAE;IAEZ,OAAO,MAAM,wBAAwB;KACjC,OAAO,MAAM;KACb,YAAY,KAAK,IAAI,IAAI;KACzB,cAAc,OAAO;KACrB,GAAI,gBAAgB,EAAE,OAAO,OAAO,MAAM;KAC1C,GAAI,kBAAkB,EAAE,SAAS,YAAY;IACjD,CAAC;IAED,OAAO;GACX,SAAS,OAAO;IACZ,OAAO,MAAM,qBAAqB;KAC9B,OAAO,MAAM;KACb,YAAY,KAAK,IAAI,IAAI;KACzB,OAAO,iBAAiB,QAAQ,MAAM,UAAU;IACpD,CAAC;IACD,MAAM;GACV;EACJ;EAEA,YAAY,OAAO,EAAE,UAAU,QAAQ,YAAY;GAC/C,MAAM,YAAY,KAAK,IAAI;GAE3B,OAAO,MAAM,mBAAmB;IAC5B,OAAO,MAAM;IACb,GAAI,iBAAiB,EAAE,OAAO;GAClC,CAAC;GAED,IAAI;IACA,MAAM,SAAS,MAAM,SAAS;IAE9B,MAAM,SAAmB,CAAC;IAE1B,MAAM,kBAAkB,IAAI,gBAG1B;KACE,UAAU,OAAO,YAAY;MACzB,IAAI,kBAAkB,MAAM,SAAS,cACjC,OAAO,KAAK,MAAM,KAAK;MAE3B,WAAW,QAAQ,KAAK;KAC5B;KACA,QAAQ;MACJ,OAAO,MAAM,sBAAsB;OAC/B,OAAO,MAAM;OACb,YAAY,KAAK,IAAI,IAAI;OACzB,GAAI,kBAAkB,EAAE,SAAS,OAAO,KAAK,EAAE,EAAE;MACrD,CAAC;KACL;IACJ,CAAC;IAED,OAAO;KACH,sBAAsB;KACtB,GAAG;KACH,QAAQ,OAAO,OAAO,YAAY,eAAe;IACrD;GACJ,SAAS,OAAO;IACZ,OAAO,MAAM,mBAAmB;KAC5B,OAAO,MAAM;KACb,YAAY,KAAK,IAAI,IAAI;KACzB,OAAO,iBAAiB,QAAQ,MAAM,UAAU;IACpD,CAAC;IACD,MAAM;GACV;EACJ;CACJ;AACJ;;;AC1GA,IAAI,SAAS;AACb,IAAI,SAAS,OAAO,IAAI,MAAM;AAC9B,IAAI;AAAI,IAAA;AACR,IAAI,aAAa,MAAM,qBAAqB,KAAK,OAAO,KAAK,QAAQ,GAAA,CAAI;;;;;;;;;CASvE,YAAY,EACV,MAAM,QACN,SACA,SACC;EACD,MAAM,OAAO;EACb,KAAK,MAAM;EACX,KAAK,OAAO;EACZ,KAAK,QAAQ;CACf;;;;;;CAMA,OAAO,WAAW,OAAO;EACvB,OAAO,YAAY,UAAU,OAAO,MAAM;CAC5C;CACA,OAAO,UAAU,OAAO,UAAU;EAChC,MAAM,eAAe,OAAO,IAAI,QAAQ;EACxC,OAAO,SAAS,QAAQ,OAAO,UAAU,YAAY,gBAAgB,SAAS,OAAO,MAAM,kBAAkB,aAAa,MAAM,kBAAkB;CACpJ;AACF;AAGA,IAAI,OAAO;AACX,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;AACT,IAAI,eAAe,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CACtE,YAAY,EACV,SACA,KACA,mBACA,YACA,iBACA,cACA,OACA,cAAc,cAAc,SAAS,eAAe,OACpD,eAAe,OACf,eAAe,OACf,cAAc,MAEd,QACC;EACD,MAAM;GAAE;GAAM;GAAS;EAAM,CAAC;EAC9B,KAAK,OAAO;EACZ,KAAK,MAAM;EACX,KAAK,oBAAoB;EACzB,KAAK,aAAa;EAClB,KAAK,kBAAkB;EACvB,KAAK,eAAe;EACpB,KAAK,cAAc;EACnB,KAAK,OAAO;CACd;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACoB,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CAEhF,YAAY,EAAE,UAAU,0BAA0B,CAAC,GAAG;EACpD,MAAM;GAAE,MAAM;GAAO;EAAQ,CAAC;EAC9B,KAAK,OAAO;CACd;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,SAAS,gBAAgB,OAAO;CAC9B,IAAI,SAAS,MACX,OAAO;CAET,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,IAAI,iBAAiB,OACnB,OAAO,MAAM,SAAS;CAExB,OAAO,KAAK,UAAU,KAAK;AAC7B;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACkB,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CAC9E,YAAY,EACV,SACA,OACA,YACC;EACD,MAAM;GAAE,MAAM;GAAO;GAAS;EAAM,CAAC;EACrC,KAAK,OAAO;EACZ,KAAK,WAAW;CAClB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACgB,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CAC5E,YAAY,EACV,QACA,SACA,SACC;EACD,MAAM;GAAE,MAAM;GAAO,SAAS,mBAAmB;GAAW;EAAM,CAAC;EACnE,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACsB,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CAClF,YAAY,EACV,MACA,UAAU,0BAA0B,KAAK,UAAU,IAAI,EAAE,MACxD;EACD,MAAM;GAAE,MAAM;GAAO;EAAQ,CAAC;EAC9B,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACY,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CACxE,YAAY,EAAE,MAAM,SAAS;EAC3B,MAAM;GACJ,MAAM;GACN,SAAS,8BAA8B,KAAK;iBACjC,gBAAgB,KAAK;GAChC;EACF,CAAC;EACD,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACa,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CAEzE,YAAY,EAAE,WAAW;EACvB,MAAM;GAAE,MAAM;GAAO;EAAQ,CAAC;EAC9B,KAAK,OAAO;CACd;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,UAAU,mBAAmB;AACjC,IAAI,UAAU,OAAO,IAAI,OAAO;AAChC,IAAI;AAAK,IAAA;CACc,eAAe,MAAM,YAAY,MAAM,SAAS,IAAA,CAAK;CAE1E,YAAY,EAAE,WAAW;EACvB,MAAM;GAAE,MAAM;GAAO;EAAQ,CAAC;EAC9B,KAAK,OAAO;CACd;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,OAAO;CAC5C;AACF;AAGA,IAAI,QAAQ;AACZ,IAAI,WAAW,mBAAmB;AAClC,IAAI,WAAW,OAAO,IAAI,QAAQ;AAClC,IAAI;AAAM,IAAA;CACoB,eAAe,OAAO,YAAY,OAAO,UAAU,KAAA,CAAM;CAErF,YAAY,EACV,UAAU,4BACR,CAAC,GAAG;EACN,MAAM;GAAE,MAAM;GAAO;EAAQ,CAAC;EAC9B,KAAK,QAAQ;CACf;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,QAAQ;CAC7C;AACF;AAGA,IAAI,SAAS;AACb,IAAI,WAAW,mBAAmB;AAClC,IAAI,WAAW,OAAO,IAAI,QAAQ;AAClC,IAAI;AAAM,IAAA;CACa,eAAe,OAAO,YAAY,OAAO,UAAU,KAAA,CAAM;CAC9E,YAAY,EACV,YAAY,QACZ,SACA,WACA,UAAU,WAAW,UAAU,IAAI,aAClC;EACD,MAAM;GAAE,MAAM;GAAW;EAAQ,CAAC;EAClC,KAAK,QAAQ;EACb,KAAK,UAAU;EACf,KAAK,YAAY;CACnB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,QAAQ;CAC7C;AACF;AAGA,IAAI,SAAS;AACb,IAAI,WAAW,mBAAmB;AAClC,IAAI,WAAW,OAAO,IAAI,QAAQ;AAClC,IAAI;AAAM,IAAA;CACyB,eAAe,OAAO,YAAY,OAAO,UAAU,KAAA,CAAM;CAC1F,YAAY,EACV,UACA,WACA,UAAU,6CAA6C,SAAS,0BAA0B,OAAO,KAAK,SAAS,CAAC,CAAC,KAAK,IAAI,OACzH;EACD,MAAM;GAAE,MAAM;GAAQ;EAAQ,CAAC;EAC/B,KAAK,QAAQ;EACb,KAAK,WAAW;EAChB,KAAK,YAAY;CACnB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,QAAQ;CAC7C;AACF;AAGA,IAAI,SAAS;AACb,IAAI,WAAW,mBAAmB;AAClC,IAAI,WAAW,OAAO,IAAI,QAAQ;AAClC,IAAI;AAAM,IAAA;CAC+B,eAAe,OAAO,YAAY,OAAO,UAAU,KAAA,CAAM;CAChG,YAAY,SAAS;EACnB,MAAM;GACJ,MAAM;GACN,SAAS,oDAAoD,QAAQ,SAAS,UAAU,QAAQ,QAAQ,yBAAyB,QAAQ,qBAAqB,wBAAwB,QAAQ,OAAO,OAAO;EAC9M,CAAC;EACD,KAAK,QAAQ;EACb,KAAK,WAAW,QAAQ;EACxB,KAAK,UAAU,QAAQ;EACvB,KAAK,uBAAuB,QAAQ;EACpC,KAAK,SAAS,QAAQ;CACxB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,QAAQ;CAC7C;AACF;AAGA,IAAI,SAAS;AACb,IAAI,WAAW,mBAAmB;AAClC,IAAI,WAAW,OAAO,IAAI,QAAQ;AAClC,IAAI;AAAM,IAAA;CACgB,MAAM,8BAA8B,OAAO,YAAY,OAAO,UAAU,KAAA,CAAM;CACtG,YAAY,EACV,OACA,OACA,WACC;EACD,IAAI,gBAAgB;EACpB,IAAI,WAAW,OAAO,KAAK,IAAI,QAAQ,OACrC,iBAAiB,QAAQ,QAAQ;EAEnC,KAAK,WAAW,OAAO,KAAK,IAAI,QAAQ,gBAAgB,WAAW,OAAO,KAAK,IAAI,QAAQ,WAAW;GACpG,iBAAiB;GACjB,MAAM,QAAQ,CAAC;GACf,IAAI,QAAQ,YACV,MAAM,KAAK,QAAQ,UAAU;GAE/B,IAAI,QAAQ,UACV,MAAM,KAAK,QAAQ,QAAQ,SAAS,EAAE;GAExC,iBAAiB,MAAM,KAAK,IAAI;GAChC,iBAAiB;EACnB;EACA,MAAM;GACJ,MAAM;GACN,SAAS,GAAG,cAAc,WAAW,KAAK,UAAU,KAAK,EAAE;iBAChD,gBAAgB,KAAK;GAChC;EACF,CAAC;EACD,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,UAAU;CACjB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,QAAQ;CAC7C;;;;;;;;;;;;CAYA,OAAO,KAAK,EACV,OACA,OACA,WACC;EACD,IAAI,MAAM,MAAM;EAChB,IAAI,qBAAqB,WAAW,KAAK,KAAK,MAAM,UAAU,WAAW,OAAO,MAAM,YAAY,OAAO,KAAK,IAAI,KAAK,YAAY,WAAW,OAAO,KAAK,IAAI,QAAQ,YAAY,OAAO,MAAM,YAAY,OAAO,KAAK,IAAI,KAAK,iBAAiB,WAAW,OAAO,KAAK,IAAI,QAAQ,iBAAiB,KAAK,MAAM,YAAY,OAAO,KAAK,IAAI,GAAG,eAAe,WAAW,OAAO,KAAK,IAAI,QAAQ,WAC/X,OAAO;EAET,OAAO,IAAI,qBAAqB;GAAE;GAAO;GAAO;EAAQ,CAAC;CAC3D;AACF;AAGA,IAAI,SAAS;AACb,IAAI,WAAW,mBAAmB;AAClC,IAAI,WAAW,OAAO,IAAI,QAAQ;AAClC,IAAI;AAAM,IAAA;CAC0B,eAAe,OAAO,YAAY,OAAO,UAAU,KAAA,CAAM;CAC3F,YAAY,EACV,eACA,UAAU,IAAI,cAAc,mCAC3B;EACD,MAAM;GAAE,MAAM;GAAQ;EAAQ,CAAC;EAC/B,KAAK,QAAQ;EACb,KAAK,gBAAgB;CACvB;CACA,OAAO,WAAW,OAAO;EACvB,OAAO,WAAW,UAAU,OAAO,QAAQ;CAC7C;AACF;;;ACnXA,MAAM,6BAA6B;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ;AAEA,SAAS,iBAAiB,OAAyB;CAC/C,IAAI,aAAa,WAAW,KAAK,GAAG;EAChC,IAAI,OAAO,MAAM,eAAe,UAC5B,OAAO,MAAM,eAAe,OAAO,MAAM,cAAc;EAE3D,OAAO,MAAM;CACjB;CAEA,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACrE,OAAO,2BAA2B,MAAM,YAAY,QAAQ,KAAK,OAAO,CAAC;AAC7E;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,oBAAoB,SAA8C;CAC9E,MAAM,EAAE,SAAS,UAAU,WAAW;CACtC,MAAM,eAAe;CACrB,MAAM,gBAAgB;CAEtB,SAAS,YAAY,OAAsB;EACvC,QAAQ,KAAK,yBAAyB;GAClC,UAAU,CAAC,aAAa,SAAS,cAAc,OAAO;GACtD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAChE,CAAC;CACL;CAiCA,OAAO;EA9BH,sBAAsB;EACtB,UAAU,aAAa;EACvB,SAAS,aAAa;EACtB,eAAe,aAAa;EAE5B,MAAM,WAAW,aAAyC;GACtD,IAAI;IACA,OAAO,MAAM,aAAa,WAAW,WAAW;GACpD,SAAS,OAAO;IACZ,IAAI,CAAC,iBAAiB,KAAK,GACvB,MAAM;IAEV,YAAY,KAAK;IACjB,OAAO,cAAc,WAAW,WAAW;GAC/C;EACJ;EAEA,MAAM,SAAS,aAAyC;GACpD,IAAI;IACA,OAAO,MAAM,aAAa,SAAS,WAAW;GAClD,SAAS,OAAO;IACZ,IAAI,CAAC,iBAAiB,KAAK,GACvB,MAAM;IAEV,YAAY,KAAK;IACjB,OAAO,cAAc,SAAS,WAAW;GAC7C;EACJ;CAGO;AACf;;;AChGA,SAAS,iBAAiB,gBAAsE;CAC5F,IAAI,gBAAgB,SAAS,QACzB,OAAO;CAGX,MAAM,QAAQ,CAAC,4EAA4E;CAC3F,IAAI,eAAe,QACf,MAAM,KACF,uDACA,KAAK,UAAU,eAAe,MAAM,CACxC;CAEJ,OAAO,MAAM,KAAK,IAAI;AAC1B;AAEA,SAAS,wBACL,QACA,aACqB;CACrB,MAAM,gBAAgB,OAAO,eAAe,YAAY,QAAQ,SAAS,MAAM;CAC/E,IAAI,kBAAkB,IAClB,OAAO,CAAC,GAAG,QAAQ;EAAE,SAAS,CAAC;GAAE,MAAM;GAAa,MAAM;EAAO,CAAC;EAAG,MAAM;CAAO,CAAC;CAGvF,OAAO,OAAO,KAAK,SAAS,UAAU;EAClC,IAAI,UAAU,iBAAiB,QAAQ,SAAS,QAC5C,OAAO;EAMX,MAAM,gBAAgB,QAAQ,QAAQ,eAAe,SAAS,KAAK,SAAS,MAAM;EAClF,IAAI,kBAAkB,IAClB,OAAO;GACH,GAAG;GACH,SAAS,CAAC,GAAG,QAAQ,SAAS;IAAE,MAAM;IAAa,MAAM;GAAgB,CAAC;EAC9E;EAGJ,OAAO;GACH,GAAG;GACH,SAAS,QAAQ,QAAQ,KAAK,MAAM,cAAc;IAC9C,IAAI,cAAc,iBAAiB,KAAK,SAAS,QAC7C,OAAO;IAEX,OAAO;KAAE,GAAG;KAAM,MAAM,GAAG,KAAK,KAAK,MAAM;IAAc;GAC7D,CAAC;EACL;CACJ,CAAC;AACL;;;;;;;;;;;;;;;;AAiBA,SAAgB,oCAA6D;CACzE,OAAO;EACH,sBAAsB;EACtB,kBAAkB,EAAE,aAAa;GAC7B,MAAM,cAAc,iBAAiB,OAAO,cAAc;GAC1D,IAAI,CAAC,aACD,OAAO,QAAQ,QAAQ,MAAM;GAGjC,OAAO,QAAQ,QAAQ;IACnB,GAAG;IACH,QAAQ,wBAAwB,OAAO,QAAQ,WAAW;GAC9D,CAAC;EACL;CACJ;AACJ;;;;;;;;;;;;;;;;;;;;;ACjDA,SAAgB,sBAAsB,QAAwC;CAC1E,MAAM,UAAA,GAAA,eAAA,aAAA,CAAsB;EACxB,QAAQ,OAAO;EACf,SAAS,OAAO;CACpB,CAAC;CAED,OAAO,EACH,MAAM,IAA6B;EAI/B,QAAA,GAAA,GAAA,kBAAA,CAAyB;GACrB,OAAO,OAAO,KAAK,EAAE;GACrB,YAAY,CAAC,kCAAkC,IAAA,GAAA,GAAA,sBAAA,CAAyB,CAAC;EAC7E,CAAC;CACL,EACJ;AACJ;;;;;;;;;;;;;;;;;;;;;;ACbA,SAAgB,yBAAyB,QAA8C;CACnF,MAAM,cAAA,GAAA,4BAAA,iBAAA,CAA8B;EAChC,QAAQ,OAAO;EACf,SAAS,OAAO,UAAU;EAC1B,QAAQ,OAAO,UAAU;CAC7B,CAAC;CAED,OAAO,EACH,MAAM,IAA6B;EAC/B,OAAO,WAAW,EAAE;CACxB,EACJ;AACJ;;;AC7BA,IAAI,sBAAsB;;;;;;AAO1B,SAAS,4BAAkC;CACvC,IAAI,qBACA;CAEJ,sBAAsB;CAEtB,IAAI;EACA,CAAA,GAAA,GAAA,kBAAA,CAAkB,IAAIC,aAAAA,cAAc,CAAC;CACzC,QAAQ,CAER;AACJ;AAEA,SAAS,eAAe,QAA0C;CAC9D,QAAQ,OAAO,MAAf;EACI,KAAK,WACD,OAAO,sBAAsB,MAAM;EAEvC,KAAK,cACD,OAAO,yBAAyB,MAAM;CAE9C;AACJ;AAEA,SAAS,qBACL,aACA,WACI;CACJ,IAAI,UAAU,cACV;CAEJ,MAAM,YAAY,OAAO,KAAK,SAAS,CAAC,CAAC,KAAK,IAAI,KAAK;CACvD,MAAM,IAAI,MAAM,qBAAqB,YAAY,0BAA0B,UAAU,EAAE;AAC3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,SAAgB,mBAAmB,QAA0C;CACzE,0BAA0B;CAE1B,MAAM,EAAE,QAAQ,QAAQ,SAAS,cAAc;CAE/C,MAAM,gCAAgB,IAAI,IAA8B;CACxD,MAAM,6BAAa,IAAI,IAA2B;CAElD,SAAS,gBAAgB,aAAuC;EAC5D,IAAI,WAAW,cAAc,IAAI,WAAW;EAC5C,IAAI,CAAC,UAAU;GACX,WAAW,eAAe,UAAU,YAAY;GAChD,cAAc,IAAI,aAAa,QAAQ;EAC3C;EACA,OAAO;CACX;CAEA,SAAS,WAAW,KAAe,WAAkC;EACjE,qBAAqB,IAAI,UAAU,SAAS;EAK5C,QAAA,GAAA,GAAA,kBAAA,CAAyB;GACrB,OAJa,gBAAgB,IAAI,QACZ,CAAC,CAAC,MAAM,IAAI,KAGlB;GACf,YAAY,CACR,sBAAsB,EAAE,UAAU,CAAC,GACnC,qBAAqB,EAAE,SAAS,UAAU,GAAG,IAAI,SAAS,GAAG,IAAI,SAAS,CAAC,CAC/E;EACJ,CAAC;CACL;CAEA,SAAS,gBAAgB,WAAkC;EACvD,MAAM,cAAc,OAAO;EAC3B,IAAI,CAAC,aAAa;GACd,MAAM,YAAY,OAAO,KAAK,MAAM,CAAC,CAAC,KAAK,IAAI,KAAK;GACpD,MAAM,IAAI,MAAM,kBAAkB,UAAU,uBAAuB,UAAU,EAAE;EACnF;EAEA,MAAM,UAAU,WACZ;GAAE,OAAO,YAAY;GAAO,UAAU,YAAY;EAAS,GAC3D,SACJ;EACA,MAAM,WAAW,YAAY,WACvB,oBAAoB;GAChB,UAAU,WAAW,YAAY,UAAU,SAAS;GACpD;GACA;EACJ,CAAC,IACD;EAEN,IAAI,CAAC,QACD,OAAO;EAGX,QAAA,GAAA,GAAA,kBAAA,CAAyB;GACrB,OAAO;GACP,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;EACpD,CAAC;CACL;CAEA,OAAO,EACH,MAAM,WAAkC;EACpC,IAAI,QAAQ,WAAW,IAAI,SAAS;EACpC,IAAI,CAAC,OAAO;GACR,QAAQ,gBAAgB,SAAS;GACjC,WAAW,IAAI,WAAW,KAAK;EACnC;EACA,OAAO;CACX,EACJ;AACJ"}
|
package/dist/index.d.cts
CHANGED
|
@@ -135,6 +135,26 @@ interface Intelligence {
|
|
|
135
135
|
*/
|
|
136
136
|
declare function createIntelligence(config: IntelligenceConfig): Intelligence;
|
|
137
137
|
//#endregion
|
|
138
|
+
//#region src/middleware/agent.middleware.d.ts
|
|
139
|
+
interface AgentMiddlewareOptions {
|
|
140
|
+
/** The agent this model serves — becomes the generation's name in Langfuse */
|
|
141
|
+
agentName: string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Creates middleware that names the AI SDK's inference span after the agent.
|
|
145
|
+
*
|
|
146
|
+
* The AI SDK names that span `chat <model>` and only puts the agent identity
|
|
147
|
+
* (`gen_ai.agent.name`, from `experimental_telemetry.functionId`) on the
|
|
148
|
+
* parent `invoke_agent` span. Langfuse extracts model, usage and cost from
|
|
149
|
+
* the inference span alone, so a pipeline that forwards only that span would
|
|
150
|
+
* otherwise show every agent as "chat <model>". This runs inside the
|
|
151
|
+
* inference span's context (the AI SDK activates it for the provider call),
|
|
152
|
+
* so the active span is the right one.
|
|
153
|
+
*
|
|
154
|
+
* Never throws: all enrichment is best-effort.
|
|
155
|
+
*/
|
|
156
|
+
declare function createAgentMiddleware(options: AgentMiddlewareOptions): LanguageModelMiddleware;
|
|
157
|
+
//#endregion
|
|
138
158
|
//#region src/middleware/cost.middleware.d.ts
|
|
139
159
|
interface CostPricing {
|
|
140
160
|
/** USD per million input tokens */
|
|
@@ -143,15 +163,14 @@ interface CostPricing {
|
|
|
143
163
|
output: number;
|
|
144
164
|
}
|
|
145
165
|
interface CostMiddlewareOptions {
|
|
146
|
-
/** Full model reference, e.g. `'openrouter/google/gemini-2.5-flash-lite'` */
|
|
147
|
-
modelRef: string;
|
|
148
166
|
/** Fallback USD-per-million-token pricing, used when the provider doesn't report actual cost */
|
|
149
167
|
pricing?: CostPricing;
|
|
150
168
|
}
|
|
151
169
|
/**
|
|
152
|
-
* Creates middleware that
|
|
153
|
-
*
|
|
154
|
-
* (`gen_ai.
|
|
170
|
+
* Creates middleware that records the USD cost of a generation as
|
|
171
|
+
* `gen_ai.usage.cost` on the active OpenTelemetry span — the AI SDK's own
|
|
172
|
+
* inference span (`gen_ai.operation.name = chat`), which is what Langfuse
|
|
173
|
+
* ingests as a generation.
|
|
155
174
|
*
|
|
156
175
|
* Resolution order:
|
|
157
176
|
* 1. Actual cost reported by the provider (currently: OpenRouter's
|
|
@@ -159,9 +178,10 @@ interface CostMiddlewareOptions {
|
|
|
159
178
|
* 2. Estimated cost from `pricing` (USD per million input/output tokens),
|
|
160
179
|
* computed from the reported token usage.
|
|
161
180
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
181
|
+
* When neither is available nothing is written: `gen_ai.request.model` is
|
|
182
|
+
* left to the AI SDK (the bare model id), so Langfuse can still price the
|
|
183
|
+
* generation from its own model catalogue. Langfuse prioritizes
|
|
184
|
+
* `gen_ai.usage.cost` over that inference when both exist.
|
|
165
185
|
*
|
|
166
186
|
* Never throws: all enrichment is best-effort.
|
|
167
187
|
*
|
|
@@ -169,16 +189,11 @@ interface CostMiddlewareOptions {
|
|
|
169
189
|
* ```ts
|
|
170
190
|
* const model = wrapLanguageModel({
|
|
171
191
|
* model: provider.model('google/gemini-2.5-flash-lite'),
|
|
172
|
-
* middleware: [
|
|
173
|
-
* createCostMiddleware({
|
|
174
|
-
* modelRef: 'openrouter/google/gemini-2.5-flash-lite',
|
|
175
|
-
* pricing: { input: 0.1, output: 0.4 },
|
|
176
|
-
* }),
|
|
177
|
-
* ],
|
|
192
|
+
* middleware: [createCostMiddleware({ pricing: { input: 0.1, output: 0.4 } })],
|
|
178
193
|
* });
|
|
179
194
|
* ```
|
|
180
195
|
*/
|
|
181
|
-
declare function createCostMiddleware(options
|
|
196
|
+
declare function createCostMiddleware(options?: CostMiddlewareOptions): LanguageModelMiddleware;
|
|
182
197
|
//#endregion
|
|
183
198
|
//#region src/middleware/logging.middleware.d.ts
|
|
184
199
|
interface LoggingMiddlewareOptions {
|
|
@@ -238,5 +253,5 @@ interface FallbackModelOptions {
|
|
|
238
253
|
*/
|
|
239
254
|
declare function createFallbackModel(options: FallbackModelOptions): LanguageModel;
|
|
240
255
|
//#endregion
|
|
241
|
-
export { type AgentConfig, type CostMiddlewareOptions, type CostPricing, type FallbackModelOptions, type GatewayConfig, type GatewayProvider, type Intelligence, type IntelligenceConfig, type LoggingMiddlewareOptions, type OpenRouterConfig, type OpenRouterMetadata, type OpenRouterProvider, type ProviderConfig, createCostMiddleware, createFallbackModel, createGatewayProvider, createIntelligence, createLoggingMiddleware, createOpenRouterProvider, createSchemaInstructionMiddleware };
|
|
256
|
+
export { type AgentConfig, type AgentMiddlewareOptions, type CostMiddlewareOptions, type CostPricing, type FallbackModelOptions, type GatewayConfig, type GatewayProvider, type Intelligence, type IntelligenceConfig, type LoggingMiddlewareOptions, type OpenRouterConfig, type OpenRouterMetadata, type OpenRouterProvider, type ProviderConfig, createAgentMiddleware, createCostMiddleware, createFallbackModel, createGatewayProvider, createIntelligence, createLoggingMiddleware, createOpenRouterProvider, createSchemaInstructionMiddleware };
|
|
242
257
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -135,6 +135,26 @@ interface Intelligence {
|
|
|
135
135
|
*/
|
|
136
136
|
declare function createIntelligence(config: IntelligenceConfig): Intelligence;
|
|
137
137
|
//#endregion
|
|
138
|
+
//#region src/middleware/agent.middleware.d.ts
|
|
139
|
+
interface AgentMiddlewareOptions {
|
|
140
|
+
/** The agent this model serves — becomes the generation's name in Langfuse */
|
|
141
|
+
agentName: string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Creates middleware that names the AI SDK's inference span after the agent.
|
|
145
|
+
*
|
|
146
|
+
* The AI SDK names that span `chat <model>` and only puts the agent identity
|
|
147
|
+
* (`gen_ai.agent.name`, from `experimental_telemetry.functionId`) on the
|
|
148
|
+
* parent `invoke_agent` span. Langfuse extracts model, usage and cost from
|
|
149
|
+
* the inference span alone, so a pipeline that forwards only that span would
|
|
150
|
+
* otherwise show every agent as "chat <model>". This runs inside the
|
|
151
|
+
* inference span's context (the AI SDK activates it for the provider call),
|
|
152
|
+
* so the active span is the right one.
|
|
153
|
+
*
|
|
154
|
+
* Never throws: all enrichment is best-effort.
|
|
155
|
+
*/
|
|
156
|
+
declare function createAgentMiddleware(options: AgentMiddlewareOptions): LanguageModelMiddleware;
|
|
157
|
+
//#endregion
|
|
138
158
|
//#region src/middleware/cost.middleware.d.ts
|
|
139
159
|
interface CostPricing {
|
|
140
160
|
/** USD per million input tokens */
|
|
@@ -143,15 +163,14 @@ interface CostPricing {
|
|
|
143
163
|
output: number;
|
|
144
164
|
}
|
|
145
165
|
interface CostMiddlewareOptions {
|
|
146
|
-
/** Full model reference, e.g. `'openrouter/google/gemini-2.5-flash-lite'` */
|
|
147
|
-
modelRef: string;
|
|
148
166
|
/** Fallback USD-per-million-token pricing, used when the provider doesn't report actual cost */
|
|
149
167
|
pricing?: CostPricing;
|
|
150
168
|
}
|
|
151
169
|
/**
|
|
152
|
-
* Creates middleware that
|
|
153
|
-
*
|
|
154
|
-
* (`gen_ai.
|
|
170
|
+
* Creates middleware that records the USD cost of a generation as
|
|
171
|
+
* `gen_ai.usage.cost` on the active OpenTelemetry span — the AI SDK's own
|
|
172
|
+
* inference span (`gen_ai.operation.name = chat`), which is what Langfuse
|
|
173
|
+
* ingests as a generation.
|
|
155
174
|
*
|
|
156
175
|
* Resolution order:
|
|
157
176
|
* 1. Actual cost reported by the provider (currently: OpenRouter's
|
|
@@ -159,9 +178,10 @@ interface CostMiddlewareOptions {
|
|
|
159
178
|
* 2. Estimated cost from `pricing` (USD per million input/output tokens),
|
|
160
179
|
* computed from the reported token usage.
|
|
161
180
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
181
|
+
* When neither is available nothing is written: `gen_ai.request.model` is
|
|
182
|
+
* left to the AI SDK (the bare model id), so Langfuse can still price the
|
|
183
|
+
* generation from its own model catalogue. Langfuse prioritizes
|
|
184
|
+
* `gen_ai.usage.cost` over that inference when both exist.
|
|
165
185
|
*
|
|
166
186
|
* Never throws: all enrichment is best-effort.
|
|
167
187
|
*
|
|
@@ -169,16 +189,11 @@ interface CostMiddlewareOptions {
|
|
|
169
189
|
* ```ts
|
|
170
190
|
* const model = wrapLanguageModel({
|
|
171
191
|
* model: provider.model('google/gemini-2.5-flash-lite'),
|
|
172
|
-
* middleware: [
|
|
173
|
-
* createCostMiddleware({
|
|
174
|
-
* modelRef: 'openrouter/google/gemini-2.5-flash-lite',
|
|
175
|
-
* pricing: { input: 0.1, output: 0.4 },
|
|
176
|
-
* }),
|
|
177
|
-
* ],
|
|
192
|
+
* middleware: [createCostMiddleware({ pricing: { input: 0.1, output: 0.4 } })],
|
|
178
193
|
* });
|
|
179
194
|
* ```
|
|
180
195
|
*/
|
|
181
|
-
declare function createCostMiddleware(options
|
|
196
|
+
declare function createCostMiddleware(options?: CostMiddlewareOptions): LanguageModelMiddleware;
|
|
182
197
|
//#endregion
|
|
183
198
|
//#region src/middleware/logging.middleware.d.ts
|
|
184
199
|
interface LoggingMiddlewareOptions {
|
|
@@ -238,5 +253,5 @@ interface FallbackModelOptions {
|
|
|
238
253
|
*/
|
|
239
254
|
declare function createFallbackModel(options: FallbackModelOptions): LanguageModel;
|
|
240
255
|
//#endregion
|
|
241
|
-
export { type AgentConfig, type CostMiddlewareOptions, type CostPricing, type FallbackModelOptions, type GatewayConfig, type GatewayProvider, type Intelligence, type IntelligenceConfig, type LoggingMiddlewareOptions, type OpenRouterConfig, type OpenRouterMetadata, type OpenRouterProvider, type ProviderConfig, createCostMiddleware, createFallbackModel, createGatewayProvider, createIntelligence, createLoggingMiddleware, createOpenRouterProvider, createSchemaInstructionMiddleware };
|
|
256
|
+
export { type AgentConfig, type AgentMiddlewareOptions, type CostMiddlewareOptions, type CostPricing, type FallbackModelOptions, type GatewayConfig, type GatewayProvider, type Intelligence, type IntelligenceConfig, type LoggingMiddlewareOptions, type OpenRouterConfig, type OpenRouterMetadata, type OpenRouterProvider, type ProviderConfig, createAgentMiddleware, createCostMiddleware, createFallbackModel, createGatewayProvider, createIntelligence, createLoggingMiddleware, createOpenRouterProvider, createSchemaInstructionMiddleware };
|
|
242
257
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,46 @@ import { extractJsonMiddleware, registerTelemetry, wrapLanguageModel } from "ai"
|
|
|
3
3
|
import { trace } from "@opentelemetry/api";
|
|
4
4
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
5
5
|
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
6
|
+
//#region src/middleware/agent.middleware.ts
|
|
7
|
+
const AGENT_ATTRIBUTE = "gen_ai.agent.name";
|
|
8
|
+
/**
|
|
9
|
+
* Creates middleware that names the AI SDK's inference span after the agent.
|
|
10
|
+
*
|
|
11
|
+
* The AI SDK names that span `chat <model>` and only puts the agent identity
|
|
12
|
+
* (`gen_ai.agent.name`, from `experimental_telemetry.functionId`) on the
|
|
13
|
+
* parent `invoke_agent` span. Langfuse extracts model, usage and cost from
|
|
14
|
+
* the inference span alone, so a pipeline that forwards only that span would
|
|
15
|
+
* otherwise show every agent as "chat <model>". This runs inside the
|
|
16
|
+
* inference span's context (the AI SDK activates it for the provider call),
|
|
17
|
+
* so the active span is the right one.
|
|
18
|
+
*
|
|
19
|
+
* Never throws: all enrichment is best-effort.
|
|
20
|
+
*/
|
|
21
|
+
function createAgentMiddleware(options) {
|
|
22
|
+
const { agentName } = options;
|
|
23
|
+
const nameActiveSpan = () => {
|
|
24
|
+
try {
|
|
25
|
+
const span = trace.getActiveSpan();
|
|
26
|
+
if (!span) return;
|
|
27
|
+
span.updateName(agentName);
|
|
28
|
+
span.setAttribute(AGENT_ATTRIBUTE, agentName);
|
|
29
|
+
} catch {}
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
specificationVersion: "v4",
|
|
33
|
+
wrapGenerate: async ({ doGenerate }) => {
|
|
34
|
+
nameActiveSpan();
|
|
35
|
+
return doGenerate();
|
|
36
|
+
},
|
|
37
|
+
wrapStream: async ({ doStream }) => {
|
|
38
|
+
nameActiveSpan();
|
|
39
|
+
return doStream();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
6
44
|
//#region src/middleware/cost.middleware.ts
|
|
7
45
|
const COST_ATTRIBUTE = "gen_ai.usage.cost";
|
|
8
|
-
const MODEL_ATTRIBUTE = "gen_ai.request.model";
|
|
9
46
|
function resolveCost(providerMetadata, usage, pricing) {
|
|
10
47
|
const actualCost = providerMetadata?.openrouter?.usage?.cost;
|
|
11
48
|
if (typeof actualCost === "number" && actualCost > 0) return actualCost;
|
|
@@ -15,16 +52,15 @@ function resolveCost(providerMetadata, usage, pricing) {
|
|
|
15
52
|
return inputTokens / 1e6 * pricing.input + outputTokens / 1e6 * pricing.output;
|
|
16
53
|
}
|
|
17
54
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
span.setAttribute(MODEL_ATTRIBUTE, modelRef);
|
|
22
|
-
if (cost !== void 0) span.setAttribute(COST_ATTRIBUTE, cost);
|
|
55
|
+
function recordCost(cost) {
|
|
56
|
+
if (cost === void 0) return;
|
|
57
|
+
trace.getActiveSpan()?.setAttribute(COST_ATTRIBUTE, cost);
|
|
23
58
|
}
|
|
24
59
|
/**
|
|
25
|
-
* Creates middleware that
|
|
26
|
-
*
|
|
27
|
-
* (`gen_ai.
|
|
60
|
+
* Creates middleware that records the USD cost of a generation as
|
|
61
|
+
* `gen_ai.usage.cost` on the active OpenTelemetry span — the AI SDK's own
|
|
62
|
+
* inference span (`gen_ai.operation.name = chat`), which is what Langfuse
|
|
63
|
+
* ingests as a generation.
|
|
28
64
|
*
|
|
29
65
|
* Resolution order:
|
|
30
66
|
* 1. Actual cost reported by the provider (currently: OpenRouter's
|
|
@@ -32,9 +68,10 @@ function recordGeneration(modelRef, cost) {
|
|
|
32
68
|
* 2. Estimated cost from `pricing` (USD per million input/output tokens),
|
|
33
69
|
* computed from the reported token usage.
|
|
34
70
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
71
|
+
* When neither is available nothing is written: `gen_ai.request.model` is
|
|
72
|
+
* left to the AI SDK (the bare model id), so Langfuse can still price the
|
|
73
|
+
* generation from its own model catalogue. Langfuse prioritizes
|
|
74
|
+
* `gen_ai.usage.cost` over that inference when both exist.
|
|
38
75
|
*
|
|
39
76
|
* Never throws: all enrichment is best-effort.
|
|
40
77
|
*
|
|
@@ -42,23 +79,18 @@ function recordGeneration(modelRef, cost) {
|
|
|
42
79
|
* ```ts
|
|
43
80
|
* const model = wrapLanguageModel({
|
|
44
81
|
* model: provider.model('google/gemini-2.5-flash-lite'),
|
|
45
|
-
* middleware: [
|
|
46
|
-
* createCostMiddleware({
|
|
47
|
-
* modelRef: 'openrouter/google/gemini-2.5-flash-lite',
|
|
48
|
-
* pricing: { input: 0.1, output: 0.4 },
|
|
49
|
-
* }),
|
|
50
|
-
* ],
|
|
82
|
+
* middleware: [createCostMiddleware({ pricing: { input: 0.1, output: 0.4 } })],
|
|
51
83
|
* });
|
|
52
84
|
* ```
|
|
53
85
|
*/
|
|
54
|
-
function createCostMiddleware(options) {
|
|
55
|
-
const {
|
|
86
|
+
function createCostMiddleware(options = {}) {
|
|
87
|
+
const { pricing } = options;
|
|
56
88
|
return {
|
|
57
89
|
specificationVersion: "v4",
|
|
58
90
|
wrapGenerate: async ({ doGenerate }) => {
|
|
59
91
|
const result = await doGenerate();
|
|
60
92
|
try {
|
|
61
|
-
|
|
93
|
+
recordCost(resolveCost(result.providerMetadata, result.usage, pricing));
|
|
62
94
|
} catch {}
|
|
63
95
|
return result;
|
|
64
96
|
},
|
|
@@ -76,7 +108,7 @@ function createCostMiddleware(options) {
|
|
|
76
108
|
},
|
|
77
109
|
flush() {
|
|
78
110
|
try {
|
|
79
|
-
|
|
111
|
+
recordCost(resolveCost(finishProviderMetadata, finishUsage, pricing));
|
|
80
112
|
} catch {}
|
|
81
113
|
}
|
|
82
114
|
});
|
|
@@ -772,16 +804,11 @@ function createIntelligence(config) {
|
|
|
772
804
|
}
|
|
773
805
|
return provider;
|
|
774
806
|
}
|
|
775
|
-
function buildModel(ref) {
|
|
807
|
+
function buildModel(ref, agentName) {
|
|
776
808
|
assertProviderExists(ref.provider, providers);
|
|
777
|
-
const baseModel = resolveProvider(ref.provider).model(ref.model);
|
|
778
|
-
const pricingKey = `${ref.provider}/${ref.model}`;
|
|
779
809
|
return wrapLanguageModel({
|
|
780
|
-
model:
|
|
781
|
-
middleware: [createCostMiddleware({
|
|
782
|
-
modelRef: pricingKey,
|
|
783
|
-
pricing: pricing?.[pricingKey]
|
|
784
|
-
})]
|
|
810
|
+
model: resolveProvider(ref.provider).model(ref.model),
|
|
811
|
+
middleware: [createAgentMiddleware({ agentName }), createCostMiddleware({ pricing: pricing?.[`${ref.provider}/${ref.model}`] })]
|
|
785
812
|
});
|
|
786
813
|
}
|
|
787
814
|
function buildAgentModel(agentName) {
|
|
@@ -793,9 +820,9 @@ function createIntelligence(config) {
|
|
|
793
820
|
const primary = buildModel({
|
|
794
821
|
model: agentConfig.model,
|
|
795
822
|
provider: agentConfig.provider
|
|
796
|
-
});
|
|
823
|
+
}, agentName);
|
|
797
824
|
const composed = agentConfig.fallback ? createFallbackModel({
|
|
798
|
-
fallback: buildModel(agentConfig.fallback),
|
|
825
|
+
fallback: buildModel(agentConfig.fallback, agentName),
|
|
799
826
|
logger,
|
|
800
827
|
primary
|
|
801
828
|
}) : primary;
|
|
@@ -815,6 +842,6 @@ function createIntelligence(config) {
|
|
|
815
842
|
} };
|
|
816
843
|
}
|
|
817
844
|
//#endregion
|
|
818
|
-
export { createCostMiddleware, createFallbackModel, createGatewayProvider, createIntelligence, createLoggingMiddleware, createOpenRouterProvider, createSchemaInstructionMiddleware };
|
|
845
|
+
export { createAgentMiddleware, createCostMiddleware, createFallbackModel, createGatewayProvider, createIntelligence, createLoggingMiddleware, createOpenRouterProvider, createSchemaInstructionMiddleware };
|
|
819
846
|
|
|
820
847
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/middleware/cost.middleware.ts","../src/middleware/logging.middleware.ts","../node_modules/@ai-sdk/provider/dist/index.js","../src/model/fallback-model.ts","../src/middleware/schema-instruction.middleware.ts","../src/provider/gateway.provider.ts","../src/provider/openrouter.provider.ts","../src/factory/create-intelligence.ts"],"sourcesContent":["import type { LanguageModelV4StreamPart, LanguageModelV4Usage } from '@ai-sdk/provider';\nimport { trace } from '@opentelemetry/api';\nimport type { LanguageModelMiddleware } from 'ai';\n\nconst COST_ATTRIBUTE = 'gen_ai.usage.cost';\nconst MODEL_ATTRIBUTE = 'gen_ai.request.model';\n\ninterface OpenRouterCostMetadata {\n openrouter?: {\n usage?: {\n cost?: number;\n };\n };\n}\n\ninterface CostPricing {\n /** USD per million input tokens */\n input: number;\n /** USD per million output tokens */\n output: number;\n}\n\nfunction resolveCost(\n providerMetadata: Record<string, unknown> | undefined,\n usage: LanguageModelV4Usage | undefined,\n pricing: CostPricing | undefined,\n): number | undefined {\n const actualCost = (providerMetadata as OpenRouterCostMetadata | undefined)?.openrouter?.usage\n ?.cost;\n if (typeof actualCost === 'number' && actualCost > 0) {\n return actualCost;\n }\n\n if (pricing) {\n const inputTokens = usage?.inputTokens?.total ?? 0;\n const outputTokens = usage?.outputTokens?.total ?? 0;\n return (\n (inputTokens / 1_000_000) * pricing.input + (outputTokens / 1_000_000) * pricing.output\n );\n }\n\n return undefined;\n}\n\nfunction recordGeneration(modelRef: string, cost: number | undefined): void {\n const span = trace.getActiveSpan();\n if (!span) {\n return;\n }\n span.setAttribute(MODEL_ATTRIBUTE, modelRef);\n if (cost !== undefined) {\n span.setAttribute(COST_ATTRIBUTE, cost);\n }\n}\n\nexport type { CostPricing };\n\nexport interface CostMiddlewareOptions {\n /** Full model reference, e.g. `'openrouter/google/gemini-2.5-flash-lite'` */\n modelRef: string;\n /** Fallback USD-per-million-token pricing, used when the provider doesn't report actual cost */\n pricing?: CostPricing;\n}\n\n/**\n * Creates middleware that enriches the active OpenTelemetry span with the\n * model reference (`gen_ai.request.model`) and the USD cost\n * (`gen_ai.usage.cost`) of a generation.\n *\n * Resolution order:\n * 1. Actual cost reported by the provider (currently: OpenRouter's\n * `providerMetadata.openrouter.usage.cost`).\n * 2. Estimated cost from `pricing` (USD per million input/output tokens),\n * computed from the reported token usage.\n *\n * The `gen_ai.usage.cost` attribute is set on `trace.getActiveSpan()` because\n * that's the attribute Langfuse's OTel ingestion prioritizes over its own\n * cost inference (`langfuse.observation.cost_details` is buggy on ingestion).\n *\n * Never throws: all enrichment is best-effort.\n *\n * @example\n * ```ts\n * const model = wrapLanguageModel({\n * model: provider.model('google/gemini-2.5-flash-lite'),\n * middleware: [\n * createCostMiddleware({\n * modelRef: 'openrouter/google/gemini-2.5-flash-lite',\n * pricing: { input: 0.1, output: 0.4 },\n * }),\n * ],\n * });\n * ```\n */\nexport function createCostMiddleware(options: CostMiddlewareOptions): LanguageModelMiddleware {\n const { modelRef, pricing } = options;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate }) => {\n const result = await doGenerate();\n\n try {\n recordGeneration(\n modelRef,\n resolveCost(\n result.providerMetadata as Record<string, unknown> | undefined,\n result.usage,\n pricing,\n ),\n );\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n\n return result;\n },\n\n wrapStream: async ({ doStream }) => {\n const result = await doStream();\n\n let finishUsage: LanguageModelV4Usage | undefined;\n let finishProviderMetadata: Record<string, unknown> | undefined;\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'finish') {\n finishUsage = chunk.usage;\n finishProviderMetadata = chunk.providerMetadata as\n | Record<string, unknown>\n | undefined;\n }\n controller.enqueue(chunk);\n },\n flush() {\n try {\n recordGeneration(\n modelRef,\n resolveCost(finishProviderMetadata, finishUsage, pricing),\n );\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n },\n });\n\n return {\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n },\n };\n}\n","import type { LanguageModelV4StreamPart } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModelMiddleware } from 'ai';\n\nexport interface LoggingMiddlewareOptions {\n logger: LoggerPort;\n include?: {\n params?: boolean;\n content?: boolean;\n usage?: boolean;\n };\n}\n\n/**\n * Creates middleware that logs AI SDK requests and responses.\n */\nexport function createLoggingMiddleware(\n options: LoggingMiddlewareOptions,\n): LanguageModelMiddleware {\n const { logger, include = {} } = options;\n const { params: includeParams, content: includeContent, usage: includeUsage = true } = include;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.generate.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doGenerate();\n\n // Extract text from content\n const textContent = result.content\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n logger.debug('ai.generate.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n finishReason: result.finishReason,\n ...(includeUsage && { usage: result.usage }),\n ...(includeContent && { content: textContent }),\n });\n\n return result;\n } catch (error) {\n logger.error('ai.generate.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n\n wrapStream: async ({ doStream, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.stream.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doStream();\n\n const chunks: string[] = [];\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (includeContent && chunk.type === 'text-delta') {\n chunks.push(chunk.delta);\n }\n controller.enqueue(chunk);\n },\n flush() {\n logger.debug('ai.stream.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n ...(includeContent && { content: chunks.join('') }),\n });\n },\n });\n\n return {\n specificationVersion: 'v4',\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n } catch (error) {\n logger.error('ai.stream.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n };\n}\n","// src/errors/ai-sdk-error.ts\nvar marker = \"vercel.ai.error\";\nvar symbol = Symbol.for(marker);\nvar _a, _b;\nvar AISDKError = class _AISDKError extends (_b = Error, _a = symbol, _b) {\n /**\n * Creates an AI SDK Error.\n *\n * @param {Object} params - The parameters for creating the error.\n * @param {string} params.name - The name of the error.\n * @param {string} params.message - The error message.\n * @param {unknown} [params.cause] - The underlying cause of the error.\n */\n constructor({\n name: name15,\n message,\n cause\n }) {\n super(message);\n this[_a] = true;\n this.name = name15;\n this.cause = cause;\n }\n /**\n * Checks if the given error is an AI SDK Error.\n * @param {unknown} error - The error to check.\n * @returns {boolean} True if the error is an AI SDK Error, false otherwise.\n */\n static isInstance(error) {\n return _AISDKError.hasMarker(error, marker);\n }\n static hasMarker(error, marker16) {\n const markerSymbol = Symbol.for(marker16);\n return error != null && typeof error === \"object\" && markerSymbol in error && typeof error[markerSymbol] === \"boolean\" && error[markerSymbol] === true;\n }\n};\n\n// src/errors/api-call-error.ts\nvar name = \"AI_APICallError\";\nvar marker2 = `vercel.ai.error.${name}`;\nvar symbol2 = Symbol.for(marker2);\nvar _a2, _b2;\nvar APICallError = class extends (_b2 = AISDKError, _a2 = symbol2, _b2) {\n constructor({\n message,\n url,\n requestBodyValues,\n statusCode,\n responseHeaders,\n responseBody,\n cause,\n isRetryable = statusCode != null && (statusCode === 408 || // request timeout\n statusCode === 409 || // conflict\n statusCode === 429 || // too many requests\n statusCode >= 500),\n // server error\n data\n }) {\n super({ name, message, cause });\n this[_a2] = true;\n this.url = url;\n this.requestBodyValues = requestBodyValues;\n this.statusCode = statusCode;\n this.responseHeaders = responseHeaders;\n this.responseBody = responseBody;\n this.isRetryable = isRetryable;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker2);\n }\n};\n\n// src/errors/empty-response-body-error.ts\nvar name2 = \"AI_EmptyResponseBodyError\";\nvar marker3 = `vercel.ai.error.${name2}`;\nvar symbol3 = Symbol.for(marker3);\nvar _a3, _b3;\nvar EmptyResponseBodyError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) {\n // used in isInstance\n constructor({ message = \"Empty response body\" } = {}) {\n super({ name: name2, message });\n this[_a3] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker3);\n }\n};\n\n// src/errors/get-error-message.ts\nfunction getErrorMessage(error) {\n if (error == null) {\n return \"unknown error\";\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error instanceof Error) {\n return error.toString();\n }\n return JSON.stringify(error);\n}\n\n// src/errors/invalid-argument-error.ts\nvar name3 = \"AI_InvalidArgumentError\";\nvar marker4 = `vercel.ai.error.${name3}`;\nvar symbol4 = Symbol.for(marker4);\nvar _a4, _b4;\nvar InvalidArgumentError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) {\n constructor({\n message,\n cause,\n argument\n }) {\n super({ name: name3, message, cause });\n this[_a4] = true;\n this.argument = argument;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker4);\n }\n};\n\n// src/errors/invalid-prompt-error.ts\nvar name4 = \"AI_InvalidPromptError\";\nvar marker5 = `vercel.ai.error.${name4}`;\nvar symbol5 = Symbol.for(marker5);\nvar _a5, _b5;\nvar InvalidPromptError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) {\n constructor({\n prompt,\n message,\n cause\n }) {\n super({ name: name4, message: `Invalid prompt: ${message}`, cause });\n this[_a5] = true;\n this.prompt = prompt;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker5);\n }\n};\n\n// src/errors/invalid-response-data-error.ts\nvar name5 = \"AI_InvalidResponseDataError\";\nvar marker6 = `vercel.ai.error.${name5}`;\nvar symbol6 = Symbol.for(marker6);\nvar _a6, _b6;\nvar InvalidResponseDataError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) {\n constructor({\n data,\n message = `Invalid response data: ${JSON.stringify(data)}.`\n }) {\n super({ name: name5, message });\n this[_a6] = true;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker6);\n }\n};\n\n// src/errors/json-parse-error.ts\nvar name6 = \"AI_JSONParseError\";\nvar marker7 = `vercel.ai.error.${name6}`;\nvar symbol7 = Symbol.for(marker7);\nvar _a7, _b7;\nvar JSONParseError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) {\n constructor({ text, cause }) {\n super({\n name: name6,\n message: `JSON parsing failed: Text: ${text}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a7] = true;\n this.text = text;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker7);\n }\n};\n\n// src/errors/load-api-key-error.ts\nvar name7 = \"AI_LoadAPIKeyError\";\nvar marker8 = `vercel.ai.error.${name7}`;\nvar symbol8 = Symbol.for(marker8);\nvar _a8, _b8;\nvar LoadAPIKeyError = class extends (_b8 = AISDKError, _a8 = symbol8, _b8) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name7, message });\n this[_a8] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker8);\n }\n};\n\n// src/errors/load-setting-error.ts\nvar name8 = \"AI_LoadSettingError\";\nvar marker9 = `vercel.ai.error.${name8}`;\nvar symbol9 = Symbol.for(marker9);\nvar _a9, _b9;\nvar LoadSettingError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name8, message });\n this[_a9] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker9);\n }\n};\n\n// src/errors/no-content-generated-error.ts\nvar name9 = \"AI_NoContentGeneratedError\";\nvar marker10 = `vercel.ai.error.${name9}`;\nvar symbol10 = Symbol.for(marker10);\nvar _a10, _b10;\nvar NoContentGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) {\n // used in isInstance\n constructor({\n message = \"No content generated.\"\n } = {}) {\n super({ name: name9, message });\n this[_a10] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker10);\n }\n};\n\n// src/errors/no-such-model-error.ts\nvar name10 = \"AI_NoSuchModelError\";\nvar marker11 = `vercel.ai.error.${name10}`;\nvar symbol11 = Symbol.for(marker11);\nvar _a11, _b11;\nvar NoSuchModelError = class extends (_b11 = AISDKError, _a11 = symbol11, _b11) {\n constructor({\n errorName = name10,\n modelId,\n modelType,\n message = `No such ${modelType}: ${modelId}`\n }) {\n super({ name: errorName, message });\n this[_a11] = true;\n this.modelId = modelId;\n this.modelType = modelType;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker11);\n }\n};\n\n// src/errors/no-such-provider-reference-error.ts\nvar name11 = \"AI_NoSuchProviderReferenceError\";\nvar marker12 = `vercel.ai.error.${name11}`;\nvar symbol12 = Symbol.for(marker12);\nvar _a12, _b12;\nvar NoSuchProviderReferenceError = class extends (_b12 = AISDKError, _a12 = symbol12, _b12) {\n constructor({\n provider,\n reference,\n message = `No provider reference found for provider '${provider}'. Available providers: ${Object.keys(reference).join(\", \")}`\n }) {\n super({ name: name11, message });\n this[_a12] = true;\n this.provider = provider;\n this.reference = reference;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker12);\n }\n};\n\n// src/errors/too-many-embedding-values-for-call-error.ts\nvar name12 = \"AI_TooManyEmbeddingValuesForCallError\";\nvar marker13 = `vercel.ai.error.${name12}`;\nvar symbol13 = Symbol.for(marker13);\nvar _a13, _b13;\nvar TooManyEmbeddingValuesForCallError = class extends (_b13 = AISDKError, _a13 = symbol13, _b13) {\n constructor(options) {\n super({\n name: name12,\n message: `Too many values for a single embedding call. The ${options.provider} model \"${options.modelId}\" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`\n });\n this[_a13] = true;\n this.provider = options.provider;\n this.modelId = options.modelId;\n this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;\n this.values = options.values;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker13);\n }\n};\n\n// src/errors/type-validation-error.ts\nvar name13 = \"AI_TypeValidationError\";\nvar marker14 = `vercel.ai.error.${name13}`;\nvar symbol14 = Symbol.for(marker14);\nvar _a14, _b14;\nvar TypeValidationError = class _TypeValidationError extends (_b14 = AISDKError, _a14 = symbol14, _b14) {\n constructor({\n value,\n cause,\n context\n }) {\n let contextPrefix = \"Type validation failed\";\n if (context == null ? void 0 : context.field) {\n contextPrefix += ` for ${context.field}`;\n }\n if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) {\n contextPrefix += \" (\";\n const parts = [];\n if (context.entityName) {\n parts.push(context.entityName);\n }\n if (context.entityId) {\n parts.push(`id: \"${context.entityId}\"`);\n }\n contextPrefix += parts.join(\", \");\n contextPrefix += \")\";\n }\n super({\n name: name13,\n message: `${contextPrefix}: Value: ${JSON.stringify(value)}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a14] = true;\n this.value = value;\n this.context = context;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker14);\n }\n /**\n * Wraps an error into a TypeValidationError.\n * If the cause is already a TypeValidationError with the same value and context, it returns the cause.\n * Otherwise, it creates a new TypeValidationError.\n *\n * @param {Object} params - The parameters for wrapping the error.\n * @param {unknown} params.value - The value that failed validation.\n * @param {unknown} params.cause - The original error or cause of the validation failure.\n * @param {TypeValidationContext} params.context - Optional context about what is being validated.\n * @returns {TypeValidationError} A TypeValidationError instance.\n */\n static wrap({\n value,\n cause,\n context\n }) {\n var _a16, _b16, _c;\n if (_TypeValidationError.isInstance(cause) && cause.value === value && ((_a16 = cause.context) == null ? void 0 : _a16.field) === (context == null ? void 0 : context.field) && ((_b16 = cause.context) == null ? void 0 : _b16.entityName) === (context == null ? void 0 : context.entityName) && ((_c = cause.context) == null ? void 0 : _c.entityId) === (context == null ? void 0 : context.entityId)) {\n return cause;\n }\n return new _TypeValidationError({ value, cause, context });\n }\n};\n\n// src/errors/unsupported-functionality-error.ts\nvar name14 = \"AI_UnsupportedFunctionalityError\";\nvar marker15 = `vercel.ai.error.${name14}`;\nvar symbol15 = Symbol.for(marker15);\nvar _a15, _b15;\nvar UnsupportedFunctionalityError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) {\n constructor({\n functionality,\n message = `'${functionality}' functionality not supported.`\n }) {\n super({ name: name14, message });\n this[_a15] = true;\n this.functionality = functionality;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker15);\n }\n};\n\n// src/json-value/is-json.ts\nfunction isJSONValue(value) {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(isJSONValue);\n }\n if (typeof value === \"object\") {\n return Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n }\n return false;\n}\nfunction isJSONArray(value) {\n return Array.isArray(value) && value.every(isJSONValue);\n}\nfunction isJSONObject(value) {\n return value != null && typeof value === \"object\" && Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n}\nexport {\n AISDKError,\n APICallError,\n EmptyResponseBodyError,\n InvalidArgumentError,\n InvalidPromptError,\n InvalidResponseDataError,\n JSONParseError,\n LoadAPIKeyError,\n LoadSettingError,\n NoContentGeneratedError,\n NoSuchModelError,\n NoSuchProviderReferenceError,\n TooManyEmbeddingValuesForCallError,\n TypeValidationError,\n UnsupportedFunctionalityError,\n getErrorMessage,\n isJSONArray,\n isJSONObject,\n isJSONValue\n};\n//# sourceMappingURL=index.js.map","import {\n APICallError,\n type LanguageModelV4,\n type LanguageModelV4CallOptions,\n} from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModel } from 'ai';\n\nconst RETRYABLE_MESSAGE_PATTERNS = [\n /ECONNREFUSED/i,\n /ECONNRESET/i,\n /ETIMEDOUT/i,\n /EAI_AGAIN/i,\n /ENOTFOUND/i,\n /timed?\\s*out/i,\n /network/i,\n /fetch failed/i,\n];\n\nfunction isRetryableError(error: unknown): boolean {\n if (APICallError.isInstance(error)) {\n if (typeof error.statusCode === 'number') {\n return error.statusCode === 429 || error.statusCode >= 500;\n }\n return error.isRetryable;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport interface FallbackModelOptions {\n primary: LanguageModel;\n fallback: LanguageModel;\n logger?: LoggerPort;\n}\n\n/**\n * Creates a `LanguageModelV4` that transparently falls back to a secondary\n * model when the primary model fails with a retryable error (HTTP 429, 5xx,\n * network errors/timeouts). Non-retryable errors (400s, validation, abort)\n * propagate unchanged.\n *\n * This is a model, not a middleware — middleware cannot switch the\n * underlying model, only transform a single model's behavior.\n *\n * @example\n * ```ts\n * const model = createFallbackModel({\n * primary: provider.model('anthropic/claude-sonnet-4'),\n * fallback: provider.model('openai/gpt-4o-mini'),\n * logger,\n * });\n * ```\n */\nexport function createFallbackModel(options: FallbackModelOptions): LanguageModel {\n const { primary, fallback, logger } = options;\n const primaryModel = primary as LanguageModelV4;\n const fallbackModel = fallback as LanguageModelV4;\n\n function logFallback(error: unknown): void {\n logger?.warn('ai.fallback.triggered', {\n modelIds: [primaryModel.modelId, fallbackModel.modelId],\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const model: LanguageModelV4 = {\n specificationVersion: 'v4',\n provider: primaryModel.provider,\n modelId: primaryModel.modelId,\n supportedUrls: primaryModel.supportedUrls,\n\n async doGenerate(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doGenerate(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doGenerate(callOptions);\n }\n },\n\n async doStream(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doStream(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doStream(callOptions);\n }\n },\n };\n\n return model;\n}\n","import type { LanguageModelV4CallOptions, LanguageModelV4Prompt } from '@ai-sdk/provider';\nimport type { LanguageModelMiddleware } from 'ai';\n\nfunction buildInstruction(responseFormat: LanguageModelV4CallOptions['responseFormat']): string {\n if (responseFormat?.type !== 'json') {\n return '';\n }\n\n const lines = ['You must respond with valid JSON only — no prose, no markdown code fences.'];\n if (responseFormat.schema) {\n lines.push(\n 'The JSON must strictly conform to this JSON schema:',\n JSON.stringify(responseFormat.schema),\n );\n }\n return lines.join('\\n');\n}\n\nfunction appendToLastUserMessage(\n prompt: LanguageModelV4Prompt,\n instruction: string,\n): LanguageModelV4Prompt {\n const lastUserIndex = prompt.findLastIndex((message) => message.role === 'user');\n if (lastUserIndex === -1) {\n return [...prompt, { content: [{ text: instruction, type: 'text' }], role: 'user' }];\n }\n\n return prompt.map((message, index) => {\n if (index !== lastUserIndex || message.role !== 'user') {\n return message;\n }\n\n // Merge into the last text part rather than appending a new part:\n // A single-part text message serializes as a plain string, which\n // Proxies and prompt-matching tooling handle more reliably.\n const lastTextIndex = message.content.findLastIndex((part) => part.type === 'text');\n if (lastTextIndex === -1) {\n return {\n ...message,\n content: [...message.content, { text: instruction, type: 'text' as const }],\n };\n }\n\n return {\n ...message,\n content: message.content.map((part, partIndex) => {\n if (partIndex !== lastTextIndex || part.type !== 'text') {\n return part;\n }\n return { ...part, text: `${part.text}\\n\\n${instruction}` };\n }),\n };\n });\n}\n\n/**\n * Creates middleware that injects the JSON schema of a structured-output\n * request into the last user message.\n *\n * Some gateways silently drop the native structured-output field when\n * translating to their backend, so the model never sees the schema and\n * answers in free prose. This middleware re-states the schema as part of the\n * user message so structured output works regardless. It targets the user\n * message rather than a system message because gateways backed by cloaked\n * CLI agents bury injected system messages under their own persona prompt and\n * ignore them. The original `responseFormat` is left untouched: backends that\n * honor it get the native signal too.\n *\n * No-op for text generations (no `responseFormat`, or `type: 'text'`).\n */\nexport function createSchemaInstructionMiddleware(): LanguageModelMiddleware {\n return {\n specificationVersion: 'v4',\n transformParams: ({ params }) => {\n const instruction = buildInstruction(params.responseFormat);\n if (!instruction) {\n return Promise.resolve(params);\n }\n\n return Promise.resolve({\n ...params,\n prompt: appendToLastUserMessage(params.prompt, instruction),\n });\n },\n };\n}\n","import { createOpenAI } from '@ai-sdk/openai';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { extractJsonMiddleware, type LanguageModel, wrapLanguageModel } from 'ai';\n\nimport { createSchemaInstructionMiddleware } from '../middleware/schema-instruction.middleware.js';\n\nexport interface GatewayConfig {\n /** Base URL of the gateway's chat-completions endpoint */\n baseURL: string;\n /** API key for authentication, if required by the endpoint */\n apiKey?: string;\n}\n\nexport interface GatewayProvider {\n /** Get a language model instance for the given model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates a provider for gateways exposing a chat-completions API — any API\n * implementing the OpenAI chat completions spec.\n *\n * Every model returned is automatically wrapped with two safety nets for\n * gateways that don't support native structured output:\n * - `createSchemaInstructionMiddleware` injects the JSON schema into the\n * system prompt (some gateways silently drop `response_format`);\n * - `extractJsonMiddleware` strips markdown code fences from JSON responses.\n *\n * @example\n * ```ts\n * const provider = createGatewayProvider({ baseURL: 'https://gateway.example.com/v1' });\n * const model = provider.model('gpt-4o-mini');\n *\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createGatewayProvider(config: GatewayConfig): GatewayProvider {\n const openai = createOpenAI({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n // Use `.chat()` explicitly rather than the base callable, which\n // Targets the Responses API — most gateways only implement chat\n // Completions.\n return wrapLanguageModel({\n model: openai.chat(id),\n middleware: [createSchemaInstructionMiddleware(), extractJsonMiddleware()],\n });\n },\n };\n}\n","import type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport type { LanguageModel } from 'ai';\n\nexport interface OpenRouterMetadata {\n /** Application name, sent as the `X-OpenRouter-Title` header for dashboard attribution */\n application?: string;\n /** Application URL, sent as the `HTTP-Referer` header for dashboard attribution */\n website?: string;\n}\n\nexport interface OpenRouterConfig {\n apiKey: string;\n metadata?: OpenRouterMetadata;\n}\n\nexport interface OpenRouterProvider {\n /** Get a language model instance for the given OpenRouter model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates an OpenRouter provider for AI SDK models.\n *\n * Per-call options (reasoning effort, max tokens, etc.) are no longer\n * configured here — pass them at the call site via `providerOptions.openrouter`\n * on `generateText`/`streamText`.\n *\n * @example\n * ```ts\n * const provider = createOpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY });\n * const model = provider.model('anthropic/claude-sonnet-4-20250514');\n *\n * const { text } = await generateText({\n * model,\n * prompt: 'Hello!',\n * providerOptions: { openrouter: { reasoning: { effort: 'high' } } },\n * });\n * ```\n */\nexport function createOpenRouterProvider(config: OpenRouterConfig): OpenRouterProvider {\n const openrouter = createOpenRouter({\n apiKey: config.apiKey,\n appName: config.metadata?.application,\n appUrl: config.metadata?.website,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n return openrouter(id);\n },\n };\n}\n","import { OpenTelemetry } from '@ai-sdk/otel';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport { type LanguageModel, registerTelemetry, wrapLanguageModel } from 'ai';\n\nimport { createCostMiddleware } from '../middleware/cost.middleware.js';\nimport { createLoggingMiddleware } from '../middleware/logging.middleware.js';\nimport { createFallbackModel } from '../model/fallback-model.js';\nimport { createGatewayProvider, type GatewayConfig } from '../provider/gateway.provider.js';\nimport {\n createOpenRouterProvider,\n type OpenRouterConfig,\n} from '../provider/openrouter.provider.js';\n\ntype ProviderConfig =\n | (GatewayConfig & { type: 'gateway' })\n | (OpenRouterConfig & { type: 'openrouter' });\n\ninterface ResolvedProvider {\n model: (id: string) => LanguageModel;\n}\n\nlet telemetryRegistered = false;\n\n/**\n * Registers the AI SDK OpenTelemetry integration, once per process. Best\n * effort — if the host app has no OTel SDK configured, `@ai-sdk/otel` spans\n * are simply dropped rather than throwing.\n */\nfunction ensureTelemetryRegistered(): void {\n if (telemetryRegistered) {\n return;\n }\n telemetryRegistered = true;\n\n try {\n registerTelemetry(new OpenTelemetry());\n } catch {\n // Best-effort: telemetry registration must never break the app.\n }\n}\n\nfunction createProvider(config: ProviderConfig): ResolvedProvider {\n switch (config.type) {\n case 'gateway': {\n return createGatewayProvider(config);\n }\n case 'openrouter': {\n return createOpenRouterProvider(config);\n }\n }\n}\n\nfunction assertProviderExists(\n providerKey: string,\n providers: Record<string, ProviderConfig>,\n): void {\n if (providers[providerKey]) {\n return;\n }\n const available = Object.keys(providers).join(', ') || '(none configured)';\n throw new Error(`Unknown provider \"${providerKey}\". Available providers: ${available}.`);\n}\n\nexport type { ProviderConfig };\n\nexport interface ModelRef {\n /** Key into `providers` */\n provider: string;\n /** Technical model id passed through to the provider as-is */\n model: string;\n}\n\nexport interface AgentConfig extends ModelRef {\n /** Model used when the primary `provider`/`model` fails with a retryable error */\n fallback?: ModelRef;\n}\n\nexport interface IntelligenceConfig {\n providers: Record<string, ProviderConfig>;\n agents: Record<string, AgentConfig>;\n /**\n * USD-per-million-token pricing, keyed by `\"<provider>/<model>\"` (the\n * agent's `provider` and `model` joined with `/`, not a provider-side\n * identifier).\n */\n pricing?: Record<string, { input: number; output: number }>;\n logger?: LoggerPort;\n}\n\nexport interface Intelligence {\n /** Get the composed language model for the given agent name */\n model: (agentName: string) => LanguageModel;\n}\n\n/**\n * Creates a composition root over AI SDK v7: resolves each agent's\n * `provider`/`model` pair into a fully instrumented `LanguageModel` — cost\n * tracking, optional fallback, and optional logging — cached per agent name.\n *\n * Registers the `@ai-sdk/otel` telemetry integration on first use (idempotent,\n * best-effort). The host app is expected to have already registered an\n * OpenTelemetry Node SDK (e.g. via `@jterrazz/telemetry`).\n *\n * @example\n * ```ts\n * const intelligence = createIntelligence({\n * providers: {\n * openrouter: { type: 'openrouter', apiKey: process.env.OPENROUTER_API_KEY },\n * },\n * agents: {\n * summarizer: {\n * provider: 'openrouter',\n * model: 'google/gemini-2.5-flash-lite',\n * fallback: { provider: 'openrouter', model: 'openai/gpt-4o-mini' },\n * },\n * },\n * pricing: {\n * 'openrouter/google/gemini-2.5-flash-lite': { input: 0.1, output: 0.4 },\n * },\n * logger,\n * });\n *\n * const model = intelligence.model('summarizer');\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createIntelligence(config: IntelligenceConfig): Intelligence {\n ensureTelemetryRegistered();\n\n const { agents, logger, pricing, providers } = config;\n\n const providerCache = new Map<string, ResolvedProvider>();\n const modelCache = new Map<string, LanguageModel>();\n\n function resolveProvider(providerKey: string): ResolvedProvider {\n let provider = providerCache.get(providerKey);\n if (!provider) {\n provider = createProvider(providers[providerKey]);\n providerCache.set(providerKey, provider);\n }\n return provider;\n }\n\n function buildModel(ref: ModelRef): LanguageModel {\n assertProviderExists(ref.provider, providers);\n\n const provider = resolveProvider(ref.provider);\n const baseModel = provider.model(ref.model) as LanguageModelV4;\n const pricingKey = `${ref.provider}/${ref.model}`;\n\n return wrapLanguageModel({\n model: baseModel,\n middleware: [\n createCostMiddleware({ modelRef: pricingKey, pricing: pricing?.[pricingKey] }),\n ],\n });\n }\n\n function buildAgentModel(agentName: string): LanguageModel {\n const agentConfig = agents[agentName];\n if (!agentConfig) {\n const available = Object.keys(agents).join(', ') || '(none configured)';\n throw new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n }\n\n const primary = buildModel({ model: agentConfig.model, provider: agentConfig.provider });\n const composed = agentConfig.fallback\n ? createFallbackModel({\n fallback: buildModel(agentConfig.fallback),\n logger,\n primary,\n })\n : primary;\n\n if (!logger) {\n return composed;\n }\n\n return wrapLanguageModel({\n model: composed as LanguageModelV4,\n middleware: [createLoggingMiddleware({ logger })],\n });\n }\n\n return {\n model(agentName: string): LanguageModel {\n let model = modelCache.get(agentName);\n if (!model) {\n model = buildAgentModel(agentName);\n modelCache.set(agentName, model);\n }\n return model;\n },\n };\n}\n"],"x_google_ignoreList":[2],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/middleware/agent.middleware.ts","../src/middleware/cost.middleware.ts","../src/middleware/logging.middleware.ts","../node_modules/@ai-sdk/provider/dist/index.js","../src/model/fallback-model.ts","../src/middleware/schema-instruction.middleware.ts","../src/provider/gateway.provider.ts","../src/provider/openrouter.provider.ts","../src/factory/create-intelligence.ts"],"sourcesContent":["import { trace } from '@opentelemetry/api';\nimport type { LanguageModelMiddleware } from 'ai';\n\nconst AGENT_ATTRIBUTE = 'gen_ai.agent.name';\n\nexport interface AgentMiddlewareOptions {\n /** The agent this model serves — becomes the generation's name in Langfuse */\n agentName: string;\n}\n\n/**\n * Creates middleware that names the AI SDK's inference span after the agent.\n *\n * The AI SDK names that span `chat <model>` and only puts the agent identity\n * (`gen_ai.agent.name`, from `experimental_telemetry.functionId`) on the\n * parent `invoke_agent` span. Langfuse extracts model, usage and cost from\n * the inference span alone, so a pipeline that forwards only that span would\n * otherwise show every agent as \"chat <model>\". This runs inside the\n * inference span's context (the AI SDK activates it for the provider call),\n * so the active span is the right one.\n *\n * Never throws: all enrichment is best-effort.\n */\nexport function createAgentMiddleware(options: AgentMiddlewareOptions): LanguageModelMiddleware {\n const { agentName } = options;\n\n const nameActiveSpan = (): void => {\n try {\n const span = trace.getActiveSpan();\n if (!span) {\n return;\n }\n span.updateName(agentName);\n span.setAttribute(AGENT_ATTRIBUTE, agentName);\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n };\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate }) => {\n nameActiveSpan();\n return doGenerate();\n },\n wrapStream: async ({ doStream }) => {\n nameActiveSpan();\n return doStream();\n },\n };\n}\n","import type { LanguageModelV4StreamPart, LanguageModelV4Usage } from '@ai-sdk/provider';\nimport { trace } from '@opentelemetry/api';\nimport type { LanguageModelMiddleware } from 'ai';\n\nconst COST_ATTRIBUTE = 'gen_ai.usage.cost';\n\ninterface OpenRouterCostMetadata {\n openrouter?: {\n usage?: {\n cost?: number;\n };\n };\n}\n\ninterface CostPricing {\n /** USD per million input tokens */\n input: number;\n /** USD per million output tokens */\n output: number;\n}\n\nfunction resolveCost(\n providerMetadata: Record<string, unknown> | undefined,\n usage: LanguageModelV4Usage | undefined,\n pricing: CostPricing | undefined,\n): number | undefined {\n const actualCost = (providerMetadata as OpenRouterCostMetadata | undefined)?.openrouter?.usage\n ?.cost;\n if (typeof actualCost === 'number' && actualCost > 0) {\n return actualCost;\n }\n\n if (pricing) {\n const inputTokens = usage?.inputTokens?.total ?? 0;\n const outputTokens = usage?.outputTokens?.total ?? 0;\n return (\n (inputTokens / 1_000_000) * pricing.input + (outputTokens / 1_000_000) * pricing.output\n );\n }\n\n return undefined;\n}\n\nfunction recordCost(cost: number | undefined): void {\n if (cost === undefined) {\n return;\n }\n trace.getActiveSpan()?.setAttribute(COST_ATTRIBUTE, cost);\n}\n\nexport type { CostPricing };\n\nexport interface CostMiddlewareOptions {\n /** Fallback USD-per-million-token pricing, used when the provider doesn't report actual cost */\n pricing?: CostPricing;\n}\n\n/**\n * Creates middleware that records the USD cost of a generation as\n * `gen_ai.usage.cost` on the active OpenTelemetry span — the AI SDK's own\n * inference span (`gen_ai.operation.name = chat`), which is what Langfuse\n * ingests as a generation.\n *\n * Resolution order:\n * 1. Actual cost reported by the provider (currently: OpenRouter's\n * `providerMetadata.openrouter.usage.cost`).\n * 2. Estimated cost from `pricing` (USD per million input/output tokens),\n * computed from the reported token usage.\n *\n * When neither is available nothing is written: `gen_ai.request.model` is\n * left to the AI SDK (the bare model id), so Langfuse can still price the\n * generation from its own model catalogue. Langfuse prioritizes\n * `gen_ai.usage.cost` over that inference when both exist.\n *\n * Never throws: all enrichment is best-effort.\n *\n * @example\n * ```ts\n * const model = wrapLanguageModel({\n * model: provider.model('google/gemini-2.5-flash-lite'),\n * middleware: [createCostMiddleware({ pricing: { input: 0.1, output: 0.4 } })],\n * });\n * ```\n */\nexport function createCostMiddleware(options: CostMiddlewareOptions = {}): LanguageModelMiddleware {\n const { pricing } = options;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate }) => {\n const result = await doGenerate();\n\n try {\n recordCost(\n resolveCost(\n result.providerMetadata as Record<string, unknown> | undefined,\n result.usage,\n pricing,\n ),\n );\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n\n return result;\n },\n\n wrapStream: async ({ doStream }) => {\n const result = await doStream();\n\n let finishUsage: LanguageModelV4Usage | undefined;\n let finishProviderMetadata: Record<string, unknown> | undefined;\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'finish') {\n finishUsage = chunk.usage;\n finishProviderMetadata = chunk.providerMetadata as\n | Record<string, unknown>\n | undefined;\n }\n controller.enqueue(chunk);\n },\n flush() {\n try {\n recordCost(resolveCost(finishProviderMetadata, finishUsage, pricing));\n } catch {\n // Best-effort: telemetry enrichment must never break generation.\n }\n },\n });\n\n return {\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n },\n };\n}\n","import type { LanguageModelV4StreamPart } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModelMiddleware } from 'ai';\n\nexport interface LoggingMiddlewareOptions {\n logger: LoggerPort;\n include?: {\n params?: boolean;\n content?: boolean;\n usage?: boolean;\n };\n}\n\n/**\n * Creates middleware that logs AI SDK requests and responses.\n */\nexport function createLoggingMiddleware(\n options: LoggingMiddlewareOptions,\n): LanguageModelMiddleware {\n const { logger, include = {} } = options;\n const { params: includeParams, content: includeContent, usage: includeUsage = true } = include;\n\n return {\n specificationVersion: 'v4',\n wrapGenerate: async ({ doGenerate, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.generate.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doGenerate();\n\n // Extract text from content\n const textContent = result.content\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n logger.debug('ai.generate.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n finishReason: result.finishReason,\n ...(includeUsage && { usage: result.usage }),\n ...(includeContent && { content: textContent }),\n });\n\n return result;\n } catch (error) {\n logger.error('ai.generate.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n\n wrapStream: async ({ doStream, params, model }) => {\n const startTime = Date.now();\n\n logger.debug('ai.stream.start', {\n model: model.modelId,\n ...(includeParams && { params }),\n });\n\n try {\n const result = await doStream();\n\n const chunks: string[] = [];\n\n const transformStream = new TransformStream<\n LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\n >({\n transform(chunk, controller) {\n if (includeContent && chunk.type === 'text-delta') {\n chunks.push(chunk.delta);\n }\n controller.enqueue(chunk);\n },\n flush() {\n logger.debug('ai.stream.complete', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n ...(includeContent && { content: chunks.join('') }),\n });\n },\n });\n\n return {\n specificationVersion: 'v4',\n ...result,\n stream: result.stream.pipeThrough(transformStream),\n };\n } catch (error) {\n logger.error('ai.stream.error', {\n model: model.modelId,\n durationMs: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n }\n },\n };\n}\n","// src/errors/ai-sdk-error.ts\nvar marker = \"vercel.ai.error\";\nvar symbol = Symbol.for(marker);\nvar _a, _b;\nvar AISDKError = class _AISDKError extends (_b = Error, _a = symbol, _b) {\n /**\n * Creates an AI SDK Error.\n *\n * @param {Object} params - The parameters for creating the error.\n * @param {string} params.name - The name of the error.\n * @param {string} params.message - The error message.\n * @param {unknown} [params.cause] - The underlying cause of the error.\n */\n constructor({\n name: name15,\n message,\n cause\n }) {\n super(message);\n this[_a] = true;\n this.name = name15;\n this.cause = cause;\n }\n /**\n * Checks if the given error is an AI SDK Error.\n * @param {unknown} error - The error to check.\n * @returns {boolean} True if the error is an AI SDK Error, false otherwise.\n */\n static isInstance(error) {\n return _AISDKError.hasMarker(error, marker);\n }\n static hasMarker(error, marker16) {\n const markerSymbol = Symbol.for(marker16);\n return error != null && typeof error === \"object\" && markerSymbol in error && typeof error[markerSymbol] === \"boolean\" && error[markerSymbol] === true;\n }\n};\n\n// src/errors/api-call-error.ts\nvar name = \"AI_APICallError\";\nvar marker2 = `vercel.ai.error.${name}`;\nvar symbol2 = Symbol.for(marker2);\nvar _a2, _b2;\nvar APICallError = class extends (_b2 = AISDKError, _a2 = symbol2, _b2) {\n constructor({\n message,\n url,\n requestBodyValues,\n statusCode,\n responseHeaders,\n responseBody,\n cause,\n isRetryable = statusCode != null && (statusCode === 408 || // request timeout\n statusCode === 409 || // conflict\n statusCode === 429 || // too many requests\n statusCode >= 500),\n // server error\n data\n }) {\n super({ name, message, cause });\n this[_a2] = true;\n this.url = url;\n this.requestBodyValues = requestBodyValues;\n this.statusCode = statusCode;\n this.responseHeaders = responseHeaders;\n this.responseBody = responseBody;\n this.isRetryable = isRetryable;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker2);\n }\n};\n\n// src/errors/empty-response-body-error.ts\nvar name2 = \"AI_EmptyResponseBodyError\";\nvar marker3 = `vercel.ai.error.${name2}`;\nvar symbol3 = Symbol.for(marker3);\nvar _a3, _b3;\nvar EmptyResponseBodyError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) {\n // used in isInstance\n constructor({ message = \"Empty response body\" } = {}) {\n super({ name: name2, message });\n this[_a3] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker3);\n }\n};\n\n// src/errors/get-error-message.ts\nfunction getErrorMessage(error) {\n if (error == null) {\n return \"unknown error\";\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error instanceof Error) {\n return error.toString();\n }\n return JSON.stringify(error);\n}\n\n// src/errors/invalid-argument-error.ts\nvar name3 = \"AI_InvalidArgumentError\";\nvar marker4 = `vercel.ai.error.${name3}`;\nvar symbol4 = Symbol.for(marker4);\nvar _a4, _b4;\nvar InvalidArgumentError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) {\n constructor({\n message,\n cause,\n argument\n }) {\n super({ name: name3, message, cause });\n this[_a4] = true;\n this.argument = argument;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker4);\n }\n};\n\n// src/errors/invalid-prompt-error.ts\nvar name4 = \"AI_InvalidPromptError\";\nvar marker5 = `vercel.ai.error.${name4}`;\nvar symbol5 = Symbol.for(marker5);\nvar _a5, _b5;\nvar InvalidPromptError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) {\n constructor({\n prompt,\n message,\n cause\n }) {\n super({ name: name4, message: `Invalid prompt: ${message}`, cause });\n this[_a5] = true;\n this.prompt = prompt;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker5);\n }\n};\n\n// src/errors/invalid-response-data-error.ts\nvar name5 = \"AI_InvalidResponseDataError\";\nvar marker6 = `vercel.ai.error.${name5}`;\nvar symbol6 = Symbol.for(marker6);\nvar _a6, _b6;\nvar InvalidResponseDataError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) {\n constructor({\n data,\n message = `Invalid response data: ${JSON.stringify(data)}.`\n }) {\n super({ name: name5, message });\n this[_a6] = true;\n this.data = data;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker6);\n }\n};\n\n// src/errors/json-parse-error.ts\nvar name6 = \"AI_JSONParseError\";\nvar marker7 = `vercel.ai.error.${name6}`;\nvar symbol7 = Symbol.for(marker7);\nvar _a7, _b7;\nvar JSONParseError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) {\n constructor({ text, cause }) {\n super({\n name: name6,\n message: `JSON parsing failed: Text: ${text}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a7] = true;\n this.text = text;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker7);\n }\n};\n\n// src/errors/load-api-key-error.ts\nvar name7 = \"AI_LoadAPIKeyError\";\nvar marker8 = `vercel.ai.error.${name7}`;\nvar symbol8 = Symbol.for(marker8);\nvar _a8, _b8;\nvar LoadAPIKeyError = class extends (_b8 = AISDKError, _a8 = symbol8, _b8) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name7, message });\n this[_a8] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker8);\n }\n};\n\n// src/errors/load-setting-error.ts\nvar name8 = \"AI_LoadSettingError\";\nvar marker9 = `vercel.ai.error.${name8}`;\nvar symbol9 = Symbol.for(marker9);\nvar _a9, _b9;\nvar LoadSettingError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) {\n // used in isInstance\n constructor({ message }) {\n super({ name: name8, message });\n this[_a9] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker9);\n }\n};\n\n// src/errors/no-content-generated-error.ts\nvar name9 = \"AI_NoContentGeneratedError\";\nvar marker10 = `vercel.ai.error.${name9}`;\nvar symbol10 = Symbol.for(marker10);\nvar _a10, _b10;\nvar NoContentGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) {\n // used in isInstance\n constructor({\n message = \"No content generated.\"\n } = {}) {\n super({ name: name9, message });\n this[_a10] = true;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker10);\n }\n};\n\n// src/errors/no-such-model-error.ts\nvar name10 = \"AI_NoSuchModelError\";\nvar marker11 = `vercel.ai.error.${name10}`;\nvar symbol11 = Symbol.for(marker11);\nvar _a11, _b11;\nvar NoSuchModelError = class extends (_b11 = AISDKError, _a11 = symbol11, _b11) {\n constructor({\n errorName = name10,\n modelId,\n modelType,\n message = `No such ${modelType}: ${modelId}`\n }) {\n super({ name: errorName, message });\n this[_a11] = true;\n this.modelId = modelId;\n this.modelType = modelType;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker11);\n }\n};\n\n// src/errors/no-such-provider-reference-error.ts\nvar name11 = \"AI_NoSuchProviderReferenceError\";\nvar marker12 = `vercel.ai.error.${name11}`;\nvar symbol12 = Symbol.for(marker12);\nvar _a12, _b12;\nvar NoSuchProviderReferenceError = class extends (_b12 = AISDKError, _a12 = symbol12, _b12) {\n constructor({\n provider,\n reference,\n message = `No provider reference found for provider '${provider}'. Available providers: ${Object.keys(reference).join(\", \")}`\n }) {\n super({ name: name11, message });\n this[_a12] = true;\n this.provider = provider;\n this.reference = reference;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker12);\n }\n};\n\n// src/errors/too-many-embedding-values-for-call-error.ts\nvar name12 = \"AI_TooManyEmbeddingValuesForCallError\";\nvar marker13 = `vercel.ai.error.${name12}`;\nvar symbol13 = Symbol.for(marker13);\nvar _a13, _b13;\nvar TooManyEmbeddingValuesForCallError = class extends (_b13 = AISDKError, _a13 = symbol13, _b13) {\n constructor(options) {\n super({\n name: name12,\n message: `Too many values for a single embedding call. The ${options.provider} model \"${options.modelId}\" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`\n });\n this[_a13] = true;\n this.provider = options.provider;\n this.modelId = options.modelId;\n this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;\n this.values = options.values;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker13);\n }\n};\n\n// src/errors/type-validation-error.ts\nvar name13 = \"AI_TypeValidationError\";\nvar marker14 = `vercel.ai.error.${name13}`;\nvar symbol14 = Symbol.for(marker14);\nvar _a14, _b14;\nvar TypeValidationError = class _TypeValidationError extends (_b14 = AISDKError, _a14 = symbol14, _b14) {\n constructor({\n value,\n cause,\n context\n }) {\n let contextPrefix = \"Type validation failed\";\n if (context == null ? void 0 : context.field) {\n contextPrefix += ` for ${context.field}`;\n }\n if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) {\n contextPrefix += \" (\";\n const parts = [];\n if (context.entityName) {\n parts.push(context.entityName);\n }\n if (context.entityId) {\n parts.push(`id: \"${context.entityId}\"`);\n }\n contextPrefix += parts.join(\", \");\n contextPrefix += \")\";\n }\n super({\n name: name13,\n message: `${contextPrefix}: Value: ${JSON.stringify(value)}.\nError message: ${getErrorMessage(cause)}`,\n cause\n });\n this[_a14] = true;\n this.value = value;\n this.context = context;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker14);\n }\n /**\n * Wraps an error into a TypeValidationError.\n * If the cause is already a TypeValidationError with the same value and context, it returns the cause.\n * Otherwise, it creates a new TypeValidationError.\n *\n * @param {Object} params - The parameters for wrapping the error.\n * @param {unknown} params.value - The value that failed validation.\n * @param {unknown} params.cause - The original error or cause of the validation failure.\n * @param {TypeValidationContext} params.context - Optional context about what is being validated.\n * @returns {TypeValidationError} A TypeValidationError instance.\n */\n static wrap({\n value,\n cause,\n context\n }) {\n var _a16, _b16, _c;\n if (_TypeValidationError.isInstance(cause) && cause.value === value && ((_a16 = cause.context) == null ? void 0 : _a16.field) === (context == null ? void 0 : context.field) && ((_b16 = cause.context) == null ? void 0 : _b16.entityName) === (context == null ? void 0 : context.entityName) && ((_c = cause.context) == null ? void 0 : _c.entityId) === (context == null ? void 0 : context.entityId)) {\n return cause;\n }\n return new _TypeValidationError({ value, cause, context });\n }\n};\n\n// src/errors/unsupported-functionality-error.ts\nvar name14 = \"AI_UnsupportedFunctionalityError\";\nvar marker15 = `vercel.ai.error.${name14}`;\nvar symbol15 = Symbol.for(marker15);\nvar _a15, _b15;\nvar UnsupportedFunctionalityError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) {\n constructor({\n functionality,\n message = `'${functionality}' functionality not supported.`\n }) {\n super({ name: name14, message });\n this[_a15] = true;\n this.functionality = functionality;\n }\n static isInstance(error) {\n return AISDKError.hasMarker(error, marker15);\n }\n};\n\n// src/json-value/is-json.ts\nfunction isJSONValue(value) {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(isJSONValue);\n }\n if (typeof value === \"object\") {\n return Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n }\n return false;\n}\nfunction isJSONArray(value) {\n return Array.isArray(value) && value.every(isJSONValue);\n}\nfunction isJSONObject(value) {\n return value != null && typeof value === \"object\" && Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && (val === void 0 || isJSONValue(val))\n );\n}\nexport {\n AISDKError,\n APICallError,\n EmptyResponseBodyError,\n InvalidArgumentError,\n InvalidPromptError,\n InvalidResponseDataError,\n JSONParseError,\n LoadAPIKeyError,\n LoadSettingError,\n NoContentGeneratedError,\n NoSuchModelError,\n NoSuchProviderReferenceError,\n TooManyEmbeddingValuesForCallError,\n TypeValidationError,\n UnsupportedFunctionalityError,\n getErrorMessage,\n isJSONArray,\n isJSONObject,\n isJSONValue\n};\n//# sourceMappingURL=index.js.map","import {\n APICallError,\n type LanguageModelV4,\n type LanguageModelV4CallOptions,\n} from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport type { LanguageModel } from 'ai';\n\nconst RETRYABLE_MESSAGE_PATTERNS = [\n /ECONNREFUSED/i,\n /ECONNRESET/i,\n /ETIMEDOUT/i,\n /EAI_AGAIN/i,\n /ENOTFOUND/i,\n /timed?\\s*out/i,\n /network/i,\n /fetch failed/i,\n];\n\nfunction isRetryableError(error: unknown): boolean {\n if (APICallError.isInstance(error)) {\n if (typeof error.statusCode === 'number') {\n return error.statusCode === 429 || error.statusCode >= 500;\n }\n return error.isRetryable;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport interface FallbackModelOptions {\n primary: LanguageModel;\n fallback: LanguageModel;\n logger?: LoggerPort;\n}\n\n/**\n * Creates a `LanguageModelV4` that transparently falls back to a secondary\n * model when the primary model fails with a retryable error (HTTP 429, 5xx,\n * network errors/timeouts). Non-retryable errors (400s, validation, abort)\n * propagate unchanged.\n *\n * This is a model, not a middleware — middleware cannot switch the\n * underlying model, only transform a single model's behavior.\n *\n * @example\n * ```ts\n * const model = createFallbackModel({\n * primary: provider.model('anthropic/claude-sonnet-4'),\n * fallback: provider.model('openai/gpt-4o-mini'),\n * logger,\n * });\n * ```\n */\nexport function createFallbackModel(options: FallbackModelOptions): LanguageModel {\n const { primary, fallback, logger } = options;\n const primaryModel = primary as LanguageModelV4;\n const fallbackModel = fallback as LanguageModelV4;\n\n function logFallback(error: unknown): void {\n logger?.warn('ai.fallback.triggered', {\n modelIds: [primaryModel.modelId, fallbackModel.modelId],\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n const model: LanguageModelV4 = {\n specificationVersion: 'v4',\n provider: primaryModel.provider,\n modelId: primaryModel.modelId,\n supportedUrls: primaryModel.supportedUrls,\n\n async doGenerate(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doGenerate(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doGenerate(callOptions);\n }\n },\n\n async doStream(callOptions: LanguageModelV4CallOptions) {\n try {\n return await primaryModel.doStream(callOptions);\n } catch (error) {\n if (!isRetryableError(error)) {\n throw error;\n }\n logFallback(error);\n return fallbackModel.doStream(callOptions);\n }\n },\n };\n\n return model;\n}\n","import type { LanguageModelV4CallOptions, LanguageModelV4Prompt } from '@ai-sdk/provider';\nimport type { LanguageModelMiddleware } from 'ai';\n\nfunction buildInstruction(responseFormat: LanguageModelV4CallOptions['responseFormat']): string {\n if (responseFormat?.type !== 'json') {\n return '';\n }\n\n const lines = ['You must respond with valid JSON only — no prose, no markdown code fences.'];\n if (responseFormat.schema) {\n lines.push(\n 'The JSON must strictly conform to this JSON schema:',\n JSON.stringify(responseFormat.schema),\n );\n }\n return lines.join('\\n');\n}\n\nfunction appendToLastUserMessage(\n prompt: LanguageModelV4Prompt,\n instruction: string,\n): LanguageModelV4Prompt {\n const lastUserIndex = prompt.findLastIndex((message) => message.role === 'user');\n if (lastUserIndex === -1) {\n return [...prompt, { content: [{ text: instruction, type: 'text' }], role: 'user' }];\n }\n\n return prompt.map((message, index) => {\n if (index !== lastUserIndex || message.role !== 'user') {\n return message;\n }\n\n // Merge into the last text part rather than appending a new part:\n // A single-part text message serializes as a plain string, which\n // Proxies and prompt-matching tooling handle more reliably.\n const lastTextIndex = message.content.findLastIndex((part) => part.type === 'text');\n if (lastTextIndex === -1) {\n return {\n ...message,\n content: [...message.content, { text: instruction, type: 'text' as const }],\n };\n }\n\n return {\n ...message,\n content: message.content.map((part, partIndex) => {\n if (partIndex !== lastTextIndex || part.type !== 'text') {\n return part;\n }\n return { ...part, text: `${part.text}\\n\\n${instruction}` };\n }),\n };\n });\n}\n\n/**\n * Creates middleware that injects the JSON schema of a structured-output\n * request into the last user message.\n *\n * Some gateways silently drop the native structured-output field when\n * translating to their backend, so the model never sees the schema and\n * answers in free prose. This middleware re-states the schema as part of the\n * user message so structured output works regardless. It targets the user\n * message rather than a system message because gateways backed by cloaked\n * CLI agents bury injected system messages under their own persona prompt and\n * ignore them. The original `responseFormat` is left untouched: backends that\n * honor it get the native signal too.\n *\n * No-op for text generations (no `responseFormat`, or `type: 'text'`).\n */\nexport function createSchemaInstructionMiddleware(): LanguageModelMiddleware {\n return {\n specificationVersion: 'v4',\n transformParams: ({ params }) => {\n const instruction = buildInstruction(params.responseFormat);\n if (!instruction) {\n return Promise.resolve(params);\n }\n\n return Promise.resolve({\n ...params,\n prompt: appendToLastUserMessage(params.prompt, instruction),\n });\n },\n };\n}\n","import { createOpenAI } from '@ai-sdk/openai';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { extractJsonMiddleware, type LanguageModel, wrapLanguageModel } from 'ai';\n\nimport { createSchemaInstructionMiddleware } from '../middleware/schema-instruction.middleware.js';\n\nexport interface GatewayConfig {\n /** Base URL of the gateway's chat-completions endpoint */\n baseURL: string;\n /** API key for authentication, if required by the endpoint */\n apiKey?: string;\n}\n\nexport interface GatewayProvider {\n /** Get a language model instance for the given model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates a provider for gateways exposing a chat-completions API — any API\n * implementing the OpenAI chat completions spec.\n *\n * Every model returned is automatically wrapped with two safety nets for\n * gateways that don't support native structured output:\n * - `createSchemaInstructionMiddleware` injects the JSON schema into the\n * system prompt (some gateways silently drop `response_format`);\n * - `extractJsonMiddleware` strips markdown code fences from JSON responses.\n *\n * @example\n * ```ts\n * const provider = createGatewayProvider({ baseURL: 'https://gateway.example.com/v1' });\n * const model = provider.model('gpt-4o-mini');\n *\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createGatewayProvider(config: GatewayConfig): GatewayProvider {\n const openai = createOpenAI({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n // Use `.chat()` explicitly rather than the base callable, which\n // Targets the Responses API — most gateways only implement chat\n // Completions.\n return wrapLanguageModel({\n model: openai.chat(id),\n middleware: [createSchemaInstructionMiddleware(), extractJsonMiddleware()],\n });\n },\n };\n}\n","import type { LanguageModelV4 } from '@ai-sdk/provider';\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport type { LanguageModel } from 'ai';\n\nexport interface OpenRouterMetadata {\n /** Application name, sent as the `X-OpenRouter-Title` header for dashboard attribution */\n application?: string;\n /** Application URL, sent as the `HTTP-Referer` header for dashboard attribution */\n website?: string;\n}\n\nexport interface OpenRouterConfig {\n apiKey: string;\n metadata?: OpenRouterMetadata;\n}\n\nexport interface OpenRouterProvider {\n /** Get a language model instance for the given OpenRouter model id */\n model: (id: string) => LanguageModel;\n}\n\n/**\n * Creates an OpenRouter provider for AI SDK models.\n *\n * Per-call options (reasoning effort, max tokens, etc.) are no longer\n * configured here — pass them at the call site via `providerOptions.openrouter`\n * on `generateText`/`streamText`.\n *\n * @example\n * ```ts\n * const provider = createOpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY });\n * const model = provider.model('anthropic/claude-sonnet-4-20250514');\n *\n * const { text } = await generateText({\n * model,\n * prompt: 'Hello!',\n * providerOptions: { openrouter: { reasoning: { effort: 'high' } } },\n * });\n * ```\n */\nexport function createOpenRouterProvider(config: OpenRouterConfig): OpenRouterProvider {\n const openrouter = createOpenRouter({\n apiKey: config.apiKey,\n appName: config.metadata?.application,\n appUrl: config.metadata?.website,\n });\n\n return {\n model(id: string): LanguageModelV4 {\n return openrouter(id);\n },\n };\n}\n","import { OpenTelemetry } from '@ai-sdk/otel';\nimport type { LanguageModelV4 } from '@ai-sdk/provider';\nimport type { LoggerPort } from '@jterrazz/telemetry';\nimport { type LanguageModel, registerTelemetry, wrapLanguageModel } from 'ai';\n\nimport { createAgentMiddleware } from '../middleware/agent.middleware.js';\nimport { createCostMiddleware } from '../middleware/cost.middleware.js';\nimport { createLoggingMiddleware } from '../middleware/logging.middleware.js';\nimport { createFallbackModel } from '../model/fallback-model.js';\nimport { createGatewayProvider, type GatewayConfig } from '../provider/gateway.provider.js';\nimport {\n createOpenRouterProvider,\n type OpenRouterConfig,\n} from '../provider/openrouter.provider.js';\n\ntype ProviderConfig =\n | (GatewayConfig & { type: 'gateway' })\n | (OpenRouterConfig & { type: 'openrouter' });\n\ninterface ResolvedProvider {\n model: (id: string) => LanguageModel;\n}\n\nlet telemetryRegistered = false;\n\n/**\n * Registers the AI SDK OpenTelemetry integration, once per process. Best\n * effort — if the host app has no OTel SDK configured, `@ai-sdk/otel` spans\n * are simply dropped rather than throwing.\n */\nfunction ensureTelemetryRegistered(): void {\n if (telemetryRegistered) {\n return;\n }\n telemetryRegistered = true;\n\n try {\n registerTelemetry(new OpenTelemetry());\n } catch {\n // Best-effort: telemetry registration must never break the app.\n }\n}\n\nfunction createProvider(config: ProviderConfig): ResolvedProvider {\n switch (config.type) {\n case 'gateway': {\n return createGatewayProvider(config);\n }\n case 'openrouter': {\n return createOpenRouterProvider(config);\n }\n }\n}\n\nfunction assertProviderExists(\n providerKey: string,\n providers: Record<string, ProviderConfig>,\n): void {\n if (providers[providerKey]) {\n return;\n }\n const available = Object.keys(providers).join(', ') || '(none configured)';\n throw new Error(`Unknown provider \"${providerKey}\". Available providers: ${available}.`);\n}\n\nexport type { ProviderConfig };\n\nexport interface ModelRef {\n /** Key into `providers` */\n provider: string;\n /** Technical model id passed through to the provider as-is */\n model: string;\n}\n\nexport interface AgentConfig extends ModelRef {\n /** Model used when the primary `provider`/`model` fails with a retryable error */\n fallback?: ModelRef;\n}\n\nexport interface IntelligenceConfig {\n providers: Record<string, ProviderConfig>;\n agents: Record<string, AgentConfig>;\n /**\n * USD-per-million-token pricing, keyed by `\"<provider>/<model>\"` (the\n * agent's `provider` and `model` joined with `/`, not a provider-side\n * identifier).\n */\n pricing?: Record<string, { input: number; output: number }>;\n logger?: LoggerPort;\n}\n\nexport interface Intelligence {\n /** Get the composed language model for the given agent name */\n model: (agentName: string) => LanguageModel;\n}\n\n/**\n * Creates a composition root over AI SDK v7: resolves each agent's\n * `provider`/`model` pair into a fully instrumented `LanguageModel` — cost\n * tracking, optional fallback, and optional logging — cached per agent name.\n *\n * Registers the `@ai-sdk/otel` telemetry integration on first use (idempotent,\n * best-effort). The host app is expected to have already registered an\n * OpenTelemetry Node SDK (e.g. via `@jterrazz/telemetry`).\n *\n * @example\n * ```ts\n * const intelligence = createIntelligence({\n * providers: {\n * openrouter: { type: 'openrouter', apiKey: process.env.OPENROUTER_API_KEY },\n * },\n * agents: {\n * summarizer: {\n * provider: 'openrouter',\n * model: 'google/gemini-2.5-flash-lite',\n * fallback: { provider: 'openrouter', model: 'openai/gpt-4o-mini' },\n * },\n * },\n * pricing: {\n * 'openrouter/google/gemini-2.5-flash-lite': { input: 0.1, output: 0.4 },\n * },\n * logger,\n * });\n *\n * const model = intelligence.model('summarizer');\n * const { text } = await generateText({ model, prompt: 'Hello!' });\n * ```\n */\nexport function createIntelligence(config: IntelligenceConfig): Intelligence {\n ensureTelemetryRegistered();\n\n const { agents, logger, pricing, providers } = config;\n\n const providerCache = new Map<string, ResolvedProvider>();\n const modelCache = new Map<string, LanguageModel>();\n\n function resolveProvider(providerKey: string): ResolvedProvider {\n let provider = providerCache.get(providerKey);\n if (!provider) {\n provider = createProvider(providers[providerKey]);\n providerCache.set(providerKey, provider);\n }\n return provider;\n }\n\n function buildModel(ref: ModelRef, agentName: string): LanguageModel {\n assertProviderExists(ref.provider, providers);\n\n const provider = resolveProvider(ref.provider);\n const baseModel = provider.model(ref.model) as LanguageModelV4;\n\n return wrapLanguageModel({\n model: baseModel,\n middleware: [\n createAgentMiddleware({ agentName }),\n createCostMiddleware({ pricing: pricing?.[`${ref.provider}/${ref.model}`] }),\n ],\n });\n }\n\n function buildAgentModel(agentName: string): LanguageModel {\n const agentConfig = agents[agentName];\n if (!agentConfig) {\n const available = Object.keys(agents).join(', ') || '(none configured)';\n throw new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n }\n\n const primary = buildModel(\n { model: agentConfig.model, provider: agentConfig.provider },\n agentName,\n );\n const composed = agentConfig.fallback\n ? createFallbackModel({\n fallback: buildModel(agentConfig.fallback, agentName),\n logger,\n primary,\n })\n : primary;\n\n if (!logger) {\n return composed;\n }\n\n return wrapLanguageModel({\n model: composed as LanguageModelV4,\n middleware: [createLoggingMiddleware({ logger })],\n });\n }\n\n return {\n model(agentName: string): LanguageModel {\n let model = modelCache.get(agentName);\n if (!model) {\n model = buildAgentModel(agentName);\n modelCache.set(agentName, model);\n }\n return model;\n },\n };\n}\n"],"x_google_ignoreList":[3],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jterrazz/intelligence",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"author": "Jean-Baptiste Terrazzoni <contact@jterrazz.com>",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@ai-sdk/provider": "^4.0.3",
|
|
50
50
|
"@cspell/dict-companies": "^3.2.12",
|
|
51
51
|
"@cspell/dict-software-terms": "^5.2.4",
|
|
52
|
-
"@jterrazz/typescript": "^
|
|
52
|
+
"@jterrazz/typescript": "^9.0.0",
|
|
53
53
|
"@types/node": "^26.1.1",
|
|
54
54
|
"@types/nspell": "^2.1.6",
|
|
55
55
|
"ai": "^7.0.28",
|