@amplitude/ai 0.1.0 → 0.1.2
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/AGENTS.md +1 -1
- package/README.md +436 -6
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/patching.d.ts.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +4 -18
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/azure-openai.d.ts +3 -3
- package/dist/providers/azure-openai.d.ts.map +1 -1
- package/dist/providers/azure-openai.js +2 -2
- package/dist/providers/azure-openai.js.map +1 -1
- package/dist/providers/base.d.ts +11 -2
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js +32 -14
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/bedrock.d.ts.map +1 -1
- package/dist/providers/bedrock.js +13 -28
- package/dist/providers/bedrock.js.map +1 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +8 -27
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/mistral.d.ts.map +1 -1
- package/dist/providers/mistral.js +20 -24
- package/dist/providers/mistral.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +23 -41
- package/dist/providers/openai.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/streaming.d.ts +2 -0
- package/dist/utils/streaming.d.ts.map +1 -1
- package/dist/utils/streaming.js +10 -0
- package/dist/utils/streaming.js.map +1 -1
- package/llms-full.txt +1 -1
- package/llms.txt +1 -1
- package/mcp.schema.json +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tryRequire } from "../utils/resolve-module.js";
|
|
2
2
|
import { calculateCost } from "../utils/costs.js";
|
|
3
3
|
import { StreamingAccumulator } from "../utils/streaming.js";
|
|
4
|
-
import { BaseAIProvider, applySessionContext } from "./base.js";
|
|
4
|
+
import { BaseAIProvider, applySessionContext, contextFields } from "./base.js";
|
|
5
5
|
|
|
6
6
|
//#region src/providers/bedrock.ts
|
|
7
7
|
const _resolved = tryRequire("@aws-sdk/client-bedrock-runtime");
|
|
@@ -42,16 +42,11 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
42
42
|
} catch {}
|
|
43
43
|
const ctx = applySessionContext();
|
|
44
44
|
this._track({
|
|
45
|
-
|
|
45
|
+
...contextFields(ctx),
|
|
46
46
|
modelName: modelId,
|
|
47
47
|
provider: "bedrock",
|
|
48
48
|
responseContent: extracted.text,
|
|
49
49
|
latencyMs,
|
|
50
|
-
sessionId: ctx.sessionId,
|
|
51
|
-
traceId: ctx.traceId,
|
|
52
|
-
turnId: ctx.turnId ?? void 0,
|
|
53
|
-
agentId: ctx.agentId,
|
|
54
|
-
env: ctx.env,
|
|
55
50
|
inputTokens: extracted.inputTokens,
|
|
56
51
|
outputTokens: extracted.outputTokens,
|
|
57
52
|
totalTokens: extracted.totalTokens,
|
|
@@ -69,15 +64,11 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
69
64
|
const latencyMs = performance.now() - startTime;
|
|
70
65
|
const ctx = applySessionContext();
|
|
71
66
|
this._track({
|
|
72
|
-
|
|
67
|
+
...contextFields(ctx),
|
|
73
68
|
modelName: modelId,
|
|
74
69
|
provider: "bedrock",
|
|
75
70
|
responseContent: "",
|
|
76
71
|
latencyMs,
|
|
77
|
-
sessionId: ctx.sessionId,
|
|
78
|
-
traceId: ctx.traceId,
|
|
79
|
-
agentId: ctx.agentId,
|
|
80
|
-
env: ctx.env,
|
|
81
72
|
isError: true,
|
|
82
73
|
errorMessage: error instanceof Error ? error.message : String(error)
|
|
83
74
|
});
|
|
@@ -99,19 +90,15 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
99
90
|
if (!_isAsyncIterable(stream)) throw new Error("Bedrock stream response is not AsyncIterable");
|
|
100
91
|
return {
|
|
101
92
|
...response,
|
|
102
|
-
stream: this._wrapConverseStream(modelId, params, stream)
|
|
93
|
+
stream: this._wrapConverseStream(modelId, params, stream, ctx)
|
|
103
94
|
};
|
|
104
95
|
} catch (error) {
|
|
105
96
|
this._track({
|
|
106
|
-
|
|
97
|
+
...contextFields(ctx),
|
|
107
98
|
modelName: modelId,
|
|
108
99
|
provider: "bedrock",
|
|
109
100
|
responseContent: "",
|
|
110
101
|
latencyMs: performance.now() - startTime,
|
|
111
|
-
sessionId: ctx.sessionId,
|
|
112
|
-
traceId: ctx.traceId,
|
|
113
|
-
agentId: ctx.agentId,
|
|
114
|
-
env: ctx.env,
|
|
115
102
|
isError: true,
|
|
116
103
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
117
104
|
isStreaming: true
|
|
@@ -122,10 +109,9 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
122
109
|
get client() {
|
|
123
110
|
return this._client;
|
|
124
111
|
}
|
|
125
|
-
async *_wrapConverseStream(modelId, params, stream) {
|
|
112
|
+
async *_wrapConverseStream(modelId, params, stream, ctx) {
|
|
126
113
|
const accumulator = new StreamingAccumulator();
|
|
127
114
|
accumulator.model = modelId;
|
|
128
|
-
const ctx = applySessionContext();
|
|
129
115
|
try {
|
|
130
116
|
for await (const rawEvent of stream) {
|
|
131
117
|
const event = rawEvent;
|
|
@@ -141,7 +127,9 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
141
127
|
accumulator.setUsage({
|
|
142
128
|
inputTokens: usage?.inputTokens,
|
|
143
129
|
outputTokens: usage?.outputTokens,
|
|
144
|
-
totalTokens: usage?.totalTokens
|
|
130
|
+
totalTokens: usage?.totalTokens,
|
|
131
|
+
cacheReadTokens: usage?.cacheReadInputTokens,
|
|
132
|
+
cacheCreationTokens: usage?.cacheWriteInputTokens
|
|
145
133
|
});
|
|
146
134
|
yield rawEvent;
|
|
147
135
|
}
|
|
@@ -156,20 +144,17 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
156
144
|
costUsd = calculateCost({
|
|
157
145
|
modelName,
|
|
158
146
|
inputTokens: state.inputTokens,
|
|
159
|
-
outputTokens: state.outputTokens
|
|
147
|
+
outputTokens: state.outputTokens,
|
|
148
|
+
cacheReadInputTokens: state.cacheReadTokens ?? 0,
|
|
149
|
+
cacheCreationInputTokens: state.cacheCreationTokens ?? 0
|
|
160
150
|
});
|
|
161
151
|
} catch {}
|
|
162
152
|
this._track({
|
|
163
|
-
|
|
153
|
+
...contextFields(ctx),
|
|
164
154
|
modelName,
|
|
165
155
|
provider: "bedrock",
|
|
166
156
|
responseContent: state.content,
|
|
167
157
|
latencyMs: accumulator.elapsedMs,
|
|
168
|
-
sessionId: ctx.sessionId,
|
|
169
|
-
traceId: ctx.traceId,
|
|
170
|
-
turnId: ctx.turnId ?? void 0,
|
|
171
|
-
agentId: ctx.agentId,
|
|
172
|
-
env: ctx.env,
|
|
173
158
|
inputTokens: state.inputTokens,
|
|
174
159
|
outputTokens: state.outputTokens,
|
|
175
160
|
totalTokens: state.totalTokens,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock.js","names":["_BedrockModule: Record<string, unknown> | null","costUsd: number | null"],"sources":["../../src/providers/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock provider wrapper with automatic tracking.\n *\n * Wraps the AWS SDK BedrockRuntimeClient's converse command.\n */\n\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport type { AmplitudeOrAI, BedrockConverseResponse } from '../types.js';\nimport { calculateCost } from '../utils/costs.js';\nimport { tryRequire } from '../utils/resolve-module.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\nimport { applySessionContext, BaseAIProvider } from './base.js';\n\nconst _resolved = tryRequire('@aws-sdk/client-bedrock-runtime');\nexport const BEDROCK_AVAILABLE = _resolved != null;\nconst _BedrockModule: Record<string, unknown> | null = _resolved;\n\nexport { _BedrockModule };\n\nexport interface BedrockOptions {\n amplitude: AmplitudeOrAI;\n client: unknown;\n privacyConfig?: PrivacyConfig | null;\n /** Pass the `@aws-sdk/client-bedrock-runtime` module directly to bypass `tryRequire` (required in bundler environments). */\n bedrockModule?: unknown;\n}\n\nexport class Bedrock extends BaseAIProvider {\n private _client: unknown;\n private _bedrockMod: Record<string, unknown> | null;\n\n constructor(options: BedrockOptions) {\n super({\n amplitude: options.amplitude,\n privacyConfig: options.privacyConfig,\n providerName: 'bedrock',\n });\n this._client = options.client;\n this._bedrockMod =\n (options.bedrockModule as Record<string, unknown> | null) ??\n _BedrockModule;\n }\n\n async converse(params: Record<string, unknown>): Promise<unknown> {\n const client = this._client as {\n send: (command: unknown) => Promise<unknown>;\n };\n const modelId = String(params.modelId ?? 'unknown');\n\n if (this._bedrockMod == null) {\n throw new Error(\n '@aws-sdk/client-bedrock-runtime is required. Install it with: npm install @aws-sdk/client-bedrock-runtime — or pass the module directly via the bedrockModule option.',\n );\n }\n\n const ConverseCommand = this._bedrockMod.ConverseCommand as new (\n opts: Record<string, unknown>,\n ) => unknown;\n\n const command = new ConverseCommand(params);\n const startTime = performance.now();\n\n try {\n const response = await client.send(command);\n const latencyMs = performance.now() - startTime;\n\n const extracted = extractBedrockResponse(response);\n let costUsd: number | null = null;\n if (extracted.inputTokens != null && extracted.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName: modelId,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n cacheReadInputTokens: extracted.cacheReadTokens ?? 0,\n cacheCreationInputTokens: extracted.cacheWriteTokens ?? 0,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n const ctx = applySessionContext();\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: modelId,\n provider: 'bedrock',\n responseContent: extracted.text,\n latencyMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n turnId: ctx.turnId ?? undefined,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n totalTokens: extracted.totalTokens,\n totalCostUsd: costUsd,\n finishReason: extracted.stopReason,\n toolCalls:\n extracted.toolCalls.length > 0 ? extracted.toolCalls : undefined,\n systemPrompt: extracted.systemPrompt,\n temperature: extracted.temperature,\n topP: extracted.topP,\n maxOutputTokens: extracted.maxOutputTokens,\n isStreaming: false,\n });\n\n return response;\n } catch (error) {\n const latencyMs = performance.now() - startTime;\n const ctx = applySessionContext();\n\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: modelId,\n provider: 'bedrock',\n responseContent: '',\n latencyMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n\n throw error;\n }\n }\n\n async converseStream(params: Record<string, unknown>): Promise<unknown> {\n const modelId = String(params.modelId ?? 'unknown');\n const ctx = applySessionContext();\n const startTime = performance.now();\n try {\n const client = this._client as {\n send: (command: unknown) => Promise<unknown>;\n };\n if (this._bedrockMod == null) {\n throw new Error(\n '@aws-sdk/client-bedrock-runtime is required. Install it with: npm install @aws-sdk/client-bedrock-runtime — or pass the module directly via the bedrockModule option.',\n );\n }\n\n const ConverseStreamCommand = this._bedrockMod.ConverseStreamCommand as\n | (new (opts: Record<string, unknown>) => unknown)\n | undefined;\n if (ConverseStreamCommand == null) {\n throw new Error('Bedrock SDK does not expose ConverseStreamCommand');\n }\n\n const command = new ConverseStreamCommand(params);\n const response = (await client.send(command)) as Record<string, unknown>;\n const stream = response.stream as AsyncIterable<unknown> | undefined;\n if (!_isAsyncIterable(stream)) {\n throw new Error('Bedrock stream response is not AsyncIterable');\n }\n\n return {\n ...response,\n stream: this._wrapConverseStream(modelId, params, stream),\n };\n } catch (error) {\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: modelId,\n provider: 'bedrock',\n responseContent: '',\n latencyMs: performance.now() - startTime,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n isStreaming: true,\n });\n throw error;\n }\n }\n\n get client(): unknown {\n return this._client;\n }\n\n private async *_wrapConverseStream(\n modelId: string,\n params: Record<string, unknown>,\n stream: AsyncIterable<unknown>,\n ): AsyncGenerator<unknown> {\n const accumulator = new StreamingAccumulator();\n accumulator.model = modelId;\n const ctx = applySessionContext();\n\n try {\n for await (const rawEvent of stream) {\n const event = rawEvent as Record<string, unknown>;\n const contentBlockDelta = event.contentBlockDelta as\n | Record<string, unknown>\n | undefined;\n const delta = contentBlockDelta?.delta as\n | Record<string, unknown>\n | undefined;\n if (delta?.text != null) {\n accumulator.addContent(String(delta.text));\n }\n\n const contentBlockStart = event.contentBlockStart as\n | Record<string, unknown>\n | undefined;\n const start = contentBlockStart?.start as\n | Record<string, unknown>\n | undefined;\n if (start?.toolUse != null) {\n accumulator.addToolCall(start.toolUse as Record<string, unknown>);\n }\n\n const messageStart = event.messageStart as\n | Record<string, unknown>\n | undefined;\n if (messageStart?.model != null) {\n accumulator.model = String(messageStart.model);\n }\n\n const messageStop = event.messageStop as\n | Record<string, unknown>\n | undefined;\n if (messageStop?.stopReason != null) {\n accumulator.finishReason = String(messageStop.stopReason);\n }\n\n const metadata = event.metadata as Record<string, unknown> | undefined;\n const usage = metadata?.usage as Record<string, unknown> | undefined;\n accumulator.setUsage({\n inputTokens: usage?.inputTokens as number | undefined,\n outputTokens: usage?.outputTokens as number | undefined,\n totalTokens: usage?.totalTokens as number | undefined,\n });\n\n yield rawEvent;\n }\n } catch (error) {\n accumulator.setError(\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n } finally {\n const state = accumulator.getState();\n const modelName = String(accumulator.model ?? modelId);\n let costUsd: number | null = null;\n if (state.inputTokens != null && state.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName,\n provider: 'bedrock',\n responseContent: state.content,\n latencyMs: accumulator.elapsedMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n turnId: ctx.turnId ?? undefined,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n totalCostUsd: costUsd,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : undefined,\n systemPrompt: extractSystemPromptFromParams(params),\n temperature: (\n params.inferenceConfig as Record<string, unknown> | undefined\n )?.temperature as number | undefined,\n topP: (params.inferenceConfig as Record<string, unknown> | undefined)\n ?.topP as number | undefined,\n maxOutputTokens: (\n params.inferenceConfig as Record<string, unknown> | undefined\n )?.maxTokens as number | undefined,\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n isError: state.isError,\n errorMessage: state.errorMessage,\n });\n }\n }\n}\n\nexport function extractBedrockResponse(response: unknown): {\n text: string;\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n stopReason?: string;\n toolCalls: Array<Record<string, unknown>>;\n systemPrompt?: string;\n temperature?: number;\n topP?: number;\n maxOutputTokens?: number;\n} {\n const resp = response as BedrockConverseResponse;\n const content = resp.output?.message?.content;\n const textBlock = content?.find(\n (b) => (b as Record<string, unknown>).text != null,\n ) as { text?: string } | undefined;\n const toolCalls = content\n ?.filter((b) => (b as Record<string, unknown>).toolUse != null)\n .map(\n (b) => (b as Record<string, unknown>).toolUse as Record<string, unknown>,\n );\n const usage = resp.usage;\n const respAny = resp as Record<string, unknown>;\n const metrics = respAny.metrics as Record<string, unknown> | undefined;\n const additionalModelResponseFields =\n respAny.additionalModelResponseFields as\n | Record<string, unknown>\n | undefined;\n const inferenceConfig = respAny.inferenceConfig as\n | Record<string, unknown>\n | undefined;\n const system = respAny.system as Array<Record<string, unknown>> | undefined;\n const systemPrompt =\n Array.isArray(system) && system.length > 0\n ? system\n .map((s) => String((s as Record<string, unknown>).text ?? ''))\n .join('')\n : undefined;\n\n return {\n text: String(textBlock?.text ?? ''),\n inputTokens: usage?.inputTokens,\n outputTokens: usage?.outputTokens,\n totalTokens: usage?.totalTokens,\n cacheReadTokens: (usage as Record<string, unknown> | undefined)\n ?.cacheReadInputTokens as number | undefined,\n cacheWriteTokens: (usage as Record<string, unknown> | undefined)\n ?.cacheWriteInputTokens as number | undefined,\n stopReason: resp.stopReason,\n toolCalls: toolCalls ?? [],\n systemPrompt,\n temperature:\n (inferenceConfig?.temperature as number | undefined) ??\n (additionalModelResponseFields?.temperature as number | undefined),\n topP:\n (inferenceConfig?.topP as number | undefined) ??\n (additionalModelResponseFields?.topP as number | undefined),\n maxOutputTokens:\n (inferenceConfig?.maxTokens as number | undefined) ??\n (metrics?.maxOutputTokens as number | undefined),\n };\n}\n\nfunction extractSystemPromptFromParams(\n params: Record<string, unknown>,\n): string | undefined {\n const system = params.system as Array<Record<string, unknown>> | undefined;\n if (!Array.isArray(system) || system.length === 0) return undefined;\n return system.map((s) => String(s.text ?? '')).join('');\n}\n\nfunction _isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value != null &&\n typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] ===\n 'function'\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bedrock.js","names":["_BedrockModule: Record<string, unknown> | null","costUsd: number | null"],"sources":["../../src/providers/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock provider wrapper with automatic tracking.\n *\n * Wraps the AWS SDK BedrockRuntimeClient's converse command.\n */\n\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport type { AmplitudeOrAI, BedrockConverseResponse } from '../types.js';\nimport { calculateCost } from '../utils/costs.js';\nimport { tryRequire } from '../utils/resolve-module.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\nimport { applySessionContext, BaseAIProvider, contextFields } from './base.js';\n\nconst _resolved = tryRequire('@aws-sdk/client-bedrock-runtime');\nexport const BEDROCK_AVAILABLE = _resolved != null;\nconst _BedrockModule: Record<string, unknown> | null = _resolved;\n\nexport { _BedrockModule };\n\nexport interface BedrockOptions {\n amplitude: AmplitudeOrAI;\n client: unknown;\n privacyConfig?: PrivacyConfig | null;\n /** Pass the `@aws-sdk/client-bedrock-runtime` module directly to bypass `tryRequire` (required in bundler environments). */\n bedrockModule?: unknown;\n}\n\nexport class Bedrock extends BaseAIProvider {\n private _client: unknown;\n private _bedrockMod: Record<string, unknown> | null;\n\n constructor(options: BedrockOptions) {\n super({\n amplitude: options.amplitude,\n privacyConfig: options.privacyConfig,\n providerName: 'bedrock',\n });\n this._client = options.client;\n this._bedrockMod =\n (options.bedrockModule as Record<string, unknown> | null) ??\n _BedrockModule;\n }\n\n async converse(params: Record<string, unknown>): Promise<unknown> {\n const client = this._client as {\n send: (command: unknown) => Promise<unknown>;\n };\n const modelId = String(params.modelId ?? 'unknown');\n\n if (this._bedrockMod == null) {\n throw new Error(\n '@aws-sdk/client-bedrock-runtime is required. Install it with: npm install @aws-sdk/client-bedrock-runtime — or pass the module directly via the bedrockModule option.',\n );\n }\n\n const ConverseCommand = this._bedrockMod.ConverseCommand as new (\n opts: Record<string, unknown>,\n ) => unknown;\n\n const command = new ConverseCommand(params);\n const startTime = performance.now();\n\n try {\n const response = await client.send(command);\n const latencyMs = performance.now() - startTime;\n\n const extracted = extractBedrockResponse(response);\n let costUsd: number | null = null;\n if (extracted.inputTokens != null && extracted.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName: modelId,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n cacheReadInputTokens: extracted.cacheReadTokens ?? 0,\n cacheCreationInputTokens: extracted.cacheWriteTokens ?? 0,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n const ctx = applySessionContext();\n this._track({\n ...contextFields(ctx),\n modelName: modelId,\n provider: 'bedrock',\n responseContent: extracted.text,\n latencyMs,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n totalTokens: extracted.totalTokens,\n totalCostUsd: costUsd,\n finishReason: extracted.stopReason,\n toolCalls:\n extracted.toolCalls.length > 0 ? extracted.toolCalls : undefined,\n systemPrompt: extracted.systemPrompt,\n temperature: extracted.temperature,\n topP: extracted.topP,\n maxOutputTokens: extracted.maxOutputTokens,\n isStreaming: false,\n });\n\n return response;\n } catch (error) {\n const latencyMs = performance.now() - startTime;\n const ctx = applySessionContext();\n\n this._track({\n ...contextFields(ctx),\n modelName: modelId,\n provider: 'bedrock',\n responseContent: '',\n latencyMs,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n\n throw error;\n }\n }\n\n async converseStream(params: Record<string, unknown>): Promise<unknown> {\n const modelId = String(params.modelId ?? 'unknown');\n const ctx = applySessionContext();\n const startTime = performance.now();\n try {\n const client = this._client as {\n send: (command: unknown) => Promise<unknown>;\n };\n if (this._bedrockMod == null) {\n throw new Error(\n '@aws-sdk/client-bedrock-runtime is required. Install it with: npm install @aws-sdk/client-bedrock-runtime — or pass the module directly via the bedrockModule option.',\n );\n }\n\n const ConverseStreamCommand = this._bedrockMod.ConverseStreamCommand as\n | (new (opts: Record<string, unknown>) => unknown)\n | undefined;\n if (ConverseStreamCommand == null) {\n throw new Error('Bedrock SDK does not expose ConverseStreamCommand');\n }\n\n const command = new ConverseStreamCommand(params);\n const response = (await client.send(command)) as Record<string, unknown>;\n const stream = response.stream as AsyncIterable<unknown> | undefined;\n if (!_isAsyncIterable(stream)) {\n throw new Error('Bedrock stream response is not AsyncIterable');\n }\n\n return {\n ...response,\n stream: this._wrapConverseStream(modelId, params, stream, ctx),\n };\n } catch (error) {\n this._track({\n ...contextFields(ctx),\n modelName: modelId,\n provider: 'bedrock',\n responseContent: '',\n latencyMs: performance.now() - startTime,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n isStreaming: true,\n });\n throw error;\n }\n }\n\n get client(): unknown {\n return this._client;\n }\n\n private async *_wrapConverseStream(\n modelId: string,\n params: Record<string, unknown>,\n stream: AsyncIterable<unknown>,\n ctx: ReturnType<typeof applySessionContext>,\n ): AsyncGenerator<unknown> {\n const accumulator = new StreamingAccumulator();\n accumulator.model = modelId;\n\n try {\n for await (const rawEvent of stream) {\n const event = rawEvent as Record<string, unknown>;\n const contentBlockDelta = event.contentBlockDelta as\n | Record<string, unknown>\n | undefined;\n const delta = contentBlockDelta?.delta as\n | Record<string, unknown>\n | undefined;\n if (delta?.text != null) {\n accumulator.addContent(String(delta.text));\n }\n\n const contentBlockStart = event.contentBlockStart as\n | Record<string, unknown>\n | undefined;\n const start = contentBlockStart?.start as\n | Record<string, unknown>\n | undefined;\n if (start?.toolUse != null) {\n accumulator.addToolCall(start.toolUse as Record<string, unknown>);\n }\n\n const messageStart = event.messageStart as\n | Record<string, unknown>\n | undefined;\n if (messageStart?.model != null) {\n accumulator.model = String(messageStart.model);\n }\n\n const messageStop = event.messageStop as\n | Record<string, unknown>\n | undefined;\n if (messageStop?.stopReason != null) {\n accumulator.finishReason = String(messageStop.stopReason);\n }\n\n const metadata = event.metadata as Record<string, unknown> | undefined;\n const usage = metadata?.usage as Record<string, unknown> | undefined;\n accumulator.setUsage({\n inputTokens: usage?.inputTokens as number | undefined,\n outputTokens: usage?.outputTokens as number | undefined,\n totalTokens: usage?.totalTokens as number | undefined,\n cacheReadTokens: usage?.cacheReadInputTokens as number | undefined,\n cacheCreationTokens: usage?.cacheWriteInputTokens as number | undefined,\n });\n\n yield rawEvent;\n }\n } catch (error) {\n accumulator.setError(\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n } finally {\n const state = accumulator.getState();\n const modelName = String(accumulator.model ?? modelId);\n let costUsd: number | null = null;\n if (state.inputTokens != null && state.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n cacheReadInputTokens: state.cacheReadTokens ?? 0,\n cacheCreationInputTokens: state.cacheCreationTokens ?? 0,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._track({\n ...contextFields(ctx),\n modelName,\n provider: 'bedrock',\n responseContent: state.content,\n latencyMs: accumulator.elapsedMs,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n totalCostUsd: costUsd,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : undefined,\n systemPrompt: extractSystemPromptFromParams(params),\n temperature: (\n params.inferenceConfig as Record<string, unknown> | undefined\n )?.temperature as number | undefined,\n topP: (params.inferenceConfig as Record<string, unknown> | undefined)\n ?.topP as number | undefined,\n maxOutputTokens: (\n params.inferenceConfig as Record<string, unknown> | undefined\n )?.maxTokens as number | undefined,\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n isError: state.isError,\n errorMessage: state.errorMessage,\n });\n }\n }\n}\n\nexport function extractBedrockResponse(response: unknown): {\n text: string;\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n stopReason?: string;\n toolCalls: Array<Record<string, unknown>>;\n systemPrompt?: string;\n temperature?: number;\n topP?: number;\n maxOutputTokens?: number;\n} {\n const resp = response as BedrockConverseResponse;\n const content = resp.output?.message?.content;\n const textBlock = content?.find(\n (b) => (b as Record<string, unknown>).text != null,\n ) as { text?: string } | undefined;\n const toolCalls = content\n ?.filter((b) => (b as Record<string, unknown>).toolUse != null)\n .map(\n (b) => (b as Record<string, unknown>).toolUse as Record<string, unknown>,\n );\n const usage = resp.usage;\n const respAny = resp as Record<string, unknown>;\n const metrics = respAny.metrics as Record<string, unknown> | undefined;\n const additionalModelResponseFields =\n respAny.additionalModelResponseFields as\n | Record<string, unknown>\n | undefined;\n const inferenceConfig = respAny.inferenceConfig as\n | Record<string, unknown>\n | undefined;\n const system = respAny.system as Array<Record<string, unknown>> | undefined;\n const systemPrompt =\n Array.isArray(system) && system.length > 0\n ? system\n .map((s) => String((s as Record<string, unknown>).text ?? ''))\n .join('')\n : undefined;\n\n return {\n text: String(textBlock?.text ?? ''),\n inputTokens: usage?.inputTokens,\n outputTokens: usage?.outputTokens,\n totalTokens: usage?.totalTokens,\n cacheReadTokens: (usage as Record<string, unknown> | undefined)\n ?.cacheReadInputTokens as number | undefined,\n cacheWriteTokens: (usage as Record<string, unknown> | undefined)\n ?.cacheWriteInputTokens as number | undefined,\n stopReason: resp.stopReason,\n toolCalls: toolCalls ?? [],\n systemPrompt,\n temperature:\n (inferenceConfig?.temperature as number | undefined) ??\n (additionalModelResponseFields?.temperature as number | undefined),\n topP:\n (inferenceConfig?.topP as number | undefined) ??\n (additionalModelResponseFields?.topP as number | undefined),\n maxOutputTokens:\n (inferenceConfig?.maxTokens as number | undefined) ??\n (metrics?.maxOutputTokens as number | undefined),\n };\n}\n\nfunction extractSystemPromptFromParams(\n params: Record<string, unknown>,\n): string | undefined {\n const system = params.system as Array<Record<string, unknown>> | undefined;\n if (!Array.isArray(system) || system.length === 0) return undefined;\n return system.map((s) => String(s.text ?? '')).join('');\n}\n\nfunction _isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value != null &&\n typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] ===\n 'function'\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","names":[],"sources":["../../src/providers/gemini.ts"],"sourcesContent":[],"mappings":";;;;;;AAaM,cADO,gBACQ,EAAA,OAAM;AAI3B,cAJM,aAIwB,EAJT,MAKR,CAAA,MAAA,EAAA,OAEK,CAAA,GAAA,IAAA;AAQK,UAXN,aAAA,CAWM;EAuBX,SAAA,EAjCC,aAiCD;EACP,MAAA,CAAA,EAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","names":[],"sources":["../../src/providers/gemini.ts"],"sourcesContent":[],"mappings":";;;;;;AAaM,cADO,gBACQ,EAAA,OAAM;AAI3B,cAJM,aAIwB,EAJT,MAKR,CAAA,MAAA,EAAA,OAEK,CAAA,GAAA,IAAA;AAQK,UAXN,aAAA,CAWM;EAuBX,SAAA,EAjCC,aAiCD;EACP,MAAA,CAAA,EAAA,MAAA;EAyEO,aAAA,CAAA,EAzGM,aAyGN,GAAA,IAAA;EACP;EArGuB,YAAA,CAAA,EAAA,OAAA;;AAwPZ,cAxPH,MAAA,SAAe,cAAA,CA8PV;;uBA3PK;yCAuBX,0BACP;+CAyEO,0BACP;;;;iBAmJW,qBAAA;;;;;;kBAME,MAAM"}
|
package/dist/providers/gemini.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tryRequire } from "../utils/resolve-module.js";
|
|
2
2
|
import { calculateCost } from "../utils/costs.js";
|
|
3
3
|
import { StreamingAccumulator } from "../utils/streaming.js";
|
|
4
|
-
import { BaseAIProvider, applySessionContext } from "./base.js";
|
|
4
|
+
import { BaseAIProvider, applySessionContext, contextFields } from "./base.js";
|
|
5
5
|
|
|
6
6
|
//#region src/providers/gemini.ts
|
|
7
7
|
const _resolved = tryRequire("@google/generative-ai");
|
|
@@ -38,16 +38,11 @@ var Gemini = class extends BaseAIProvider {
|
|
|
38
38
|
} catch {}
|
|
39
39
|
const ctx = applySessionContext();
|
|
40
40
|
this._track({
|
|
41
|
-
|
|
41
|
+
...contextFields(ctx),
|
|
42
42
|
modelName: model,
|
|
43
43
|
provider: "gemini",
|
|
44
44
|
responseContent: extracted.text,
|
|
45
45
|
latencyMs,
|
|
46
|
-
sessionId: ctx.sessionId,
|
|
47
|
-
traceId: ctx.traceId,
|
|
48
|
-
turnId: ctx.turnId ?? void 0,
|
|
49
|
-
agentId: ctx.agentId,
|
|
50
|
-
env: ctx.env,
|
|
51
46
|
inputTokens: extracted.inputTokens,
|
|
52
47
|
outputTokens: extracted.outputTokens,
|
|
53
48
|
totalTokens: extracted.totalTokens,
|
|
@@ -65,15 +60,11 @@ var Gemini = class extends BaseAIProvider {
|
|
|
65
60
|
const latencyMs = performance.now() - startTime;
|
|
66
61
|
const ctx = applySessionContext();
|
|
67
62
|
this._track({
|
|
68
|
-
|
|
63
|
+
...contextFields(ctx),
|
|
69
64
|
modelName: model,
|
|
70
65
|
provider: "gemini",
|
|
71
66
|
responseContent: "",
|
|
72
67
|
latencyMs,
|
|
73
|
-
sessionId: ctx.sessionId,
|
|
74
|
-
traceId: ctx.traceId,
|
|
75
|
-
agentId: ctx.agentId,
|
|
76
|
-
env: ctx.env,
|
|
77
68
|
isError: true,
|
|
78
69
|
errorMessage: error instanceof Error ? error.message : String(error)
|
|
79
70
|
});
|
|
@@ -93,19 +84,15 @@ var Gemini = class extends BaseAIProvider {
|
|
|
93
84
|
if (!_isAsyncIterable(stream)) throw new Error("Gemini stream response is not AsyncIterable");
|
|
94
85
|
return {
|
|
95
86
|
...streamResponse,
|
|
96
|
-
stream: this._wrapStream(model, params, stream, finalResponse)
|
|
87
|
+
stream: this._wrapStream(model, params, stream, finalResponse, ctx)
|
|
97
88
|
};
|
|
98
89
|
} catch (error) {
|
|
99
90
|
this._track({
|
|
100
|
-
|
|
91
|
+
...contextFields(ctx),
|
|
101
92
|
modelName: model,
|
|
102
93
|
provider: "gemini",
|
|
103
94
|
responseContent: "",
|
|
104
95
|
latencyMs: performance.now() - startTime,
|
|
105
|
-
sessionId: ctx.sessionId,
|
|
106
|
-
traceId: ctx.traceId,
|
|
107
|
-
agentId: ctx.agentId,
|
|
108
|
-
env: ctx.env,
|
|
109
96
|
isError: true,
|
|
110
97
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
111
98
|
isStreaming: true
|
|
@@ -116,9 +103,8 @@ var Gemini = class extends BaseAIProvider {
|
|
|
116
103
|
get client() {
|
|
117
104
|
return this._client;
|
|
118
105
|
}
|
|
119
|
-
async *_wrapStream(model, params, stream, finalResponse) {
|
|
106
|
+
async *_wrapStream(model, params, stream, finalResponse, ctx) {
|
|
120
107
|
const accumulator = new StreamingAccumulator();
|
|
121
|
-
const ctx = applySessionContext();
|
|
122
108
|
try {
|
|
123
109
|
for await (const chunk of stream) {
|
|
124
110
|
const extracted = extractGeminiResponse(chunk);
|
|
@@ -144,7 +130,7 @@ var Gemini = class extends BaseAIProvider {
|
|
|
144
130
|
totalTokens: extractedFinal.totalTokens
|
|
145
131
|
});
|
|
146
132
|
if (extractedFinal.finishReason != null) accumulator.finishReason = String(extractedFinal.finishReason);
|
|
147
|
-
if (Array.isArray(extractedFinal.functionCalls)) for (const fc of extractedFinal.functionCalls) accumulator.addToolCall(fc);
|
|
133
|
+
if (Array.isArray(extractedFinal.functionCalls) && accumulator.toolCalls.length === 0) for (const fc of extractedFinal.functionCalls) accumulator.addToolCall(fc);
|
|
148
134
|
} catch {}
|
|
149
135
|
const state = accumulator.getState();
|
|
150
136
|
let costUsd = null;
|
|
@@ -156,16 +142,11 @@ var Gemini = class extends BaseAIProvider {
|
|
|
156
142
|
});
|
|
157
143
|
} catch {}
|
|
158
144
|
this._track({
|
|
159
|
-
|
|
145
|
+
...contextFields(ctx),
|
|
160
146
|
modelName: model,
|
|
161
147
|
provider: "gemini",
|
|
162
148
|
responseContent: state.content,
|
|
163
149
|
latencyMs: accumulator.elapsedMs,
|
|
164
|
-
sessionId: ctx.sessionId,
|
|
165
|
-
traceId: ctx.traceId,
|
|
166
|
-
turnId: ctx.turnId ?? void 0,
|
|
167
|
-
agentId: ctx.agentId,
|
|
168
|
-
env: ctx.env,
|
|
169
150
|
inputTokens: state.inputTokens,
|
|
170
151
|
outputTokens: state.outputTokens,
|
|
171
152
|
totalTokens: state.totalTokens,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","names":["_GeminiModule: Record<string, unknown> | null","costUsd: number | null"],"sources":["../../src/providers/gemini.ts"],"sourcesContent":["/**\n * Google Gemini provider wrapper with automatic tracking.\n */\n\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport type { AmplitudeOrAI, GeminiResponse } from '../types.js';\nimport { calculateCost } from '../utils/costs.js';\nimport { tryRequire } from '../utils/resolve-module.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\nimport { applySessionContext, BaseAIProvider } from './base.js';\n\nconst _resolved = tryRequire('@google/generative-ai');\nexport const GEMINI_AVAILABLE = _resolved != null;\nconst _GeminiModule: Record<string, unknown> | null = _resolved;\n\nexport { _GeminiModule };\n\nexport interface GeminiOptions {\n amplitude: AmplitudeOrAI;\n apiKey?: string;\n privacyConfig?: PrivacyConfig | null;\n /** Pass the `@google/generative-ai` module directly to bypass `tryRequire` (required in bundler environments). */\n geminiModule?: unknown;\n}\n\nexport class Gemini extends BaseAIProvider {\n private _client: unknown;\n\n constructor(options: GeminiOptions) {\n super({\n amplitude: options.amplitude,\n privacyConfig: options.privacyConfig,\n providerName: 'gemini',\n });\n\n const mod =\n (options.geminiModule as Record<string, unknown> | null) ?? _GeminiModule;\n if (mod == null) {\n throw new Error(\n '@google/generative-ai package is required. Install it with: npm install @google/generative-ai — or pass the module directly via the geminiModule option.',\n );\n }\n\n const GoogleGenAI = mod.GoogleGenerativeAI as new (\n apiKey: string,\n ) => unknown;\n this._client = new GoogleGenAI(options.apiKey ?? '');\n }\n\n async generateContent(\n model: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const clientObj = this._client as Record<string, unknown>;\n const getModel = clientObj.getGenerativeModel as (\n opts: Record<string, unknown>,\n ) => Record<string, unknown>;\n const genModel = getModel.call(this._client, { model });\n const generateFn = genModel.generateContent as (\n ...args: unknown[]\n ) => Promise<unknown>;\n\n const startTime = performance.now();\n\n try {\n const response = await generateFn.call(genModel, params);\n const latencyMs = performance.now() - startTime;\n\n const extracted = extractGeminiResponse(response);\n let costUsd: number | null = null;\n if (extracted.inputTokens != null && extracted.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName: model,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n const ctx = applySessionContext();\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: model,\n provider: 'gemini',\n responseContent: extracted.text,\n latencyMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n turnId: ctx.turnId ?? undefined,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n totalTokens: extracted.totalTokens,\n totalCostUsd: costUsd,\n finishReason: extracted.finishReason,\n toolCalls: extracted.functionCalls?.length\n ? extracted.functionCalls\n : undefined,\n systemPrompt: extractGeminiSystemPrompt(params),\n temperature: extractGeminiTemperature(params),\n topP: extractGeminiTopP(params),\n maxOutputTokens: extractGeminiMaxOutputTokens(params),\n isStreaming: false,\n });\n\n return response;\n } catch (error) {\n const latencyMs = performance.now() - startTime;\n const ctx = applySessionContext();\n\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: model,\n provider: 'gemini',\n responseContent: '',\n latencyMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n\n throw error;\n }\n }\n\n async generateContentStream(\n model: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const ctx = applySessionContext();\n const startTime = performance.now();\n try {\n const clientObj = this._client as Record<string, unknown>;\n const getModel = clientObj.getGenerativeModel as (\n opts: Record<string, unknown>,\n ) => Record<string, unknown>;\n const genModel = getModel.call(this._client, { model });\n const streamFn = genModel.generateContentStream as\n | ((...args: unknown[]) => Promise<unknown>)\n | undefined;\n if (typeof streamFn !== 'function') {\n throw new Error('Gemini SDK does not expose generateContentStream');\n }\n\n const response = await streamFn.call(genModel, params);\n const streamResponse = response as Record<string, unknown>;\n const stream = streamResponse.stream as\n | AsyncIterable<unknown>\n | undefined;\n const finalResponse = streamResponse.response as\n | Promise<unknown>\n | undefined;\n\n if (!_isAsyncIterable(stream)) {\n throw new Error('Gemini stream response is not AsyncIterable');\n }\n\n return {\n ...streamResponse,\n stream: this._wrapStream(model, params, stream, finalResponse),\n };\n } catch (error) {\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: model,\n provider: 'gemini',\n responseContent: '',\n latencyMs: performance.now() - startTime,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n isStreaming: true,\n });\n throw error;\n }\n }\n\n get client(): unknown {\n return this._client;\n }\n\n private async *_wrapStream(\n model: string,\n params: Record<string, unknown>,\n stream: AsyncIterable<unknown>,\n finalResponse?: Promise<unknown>,\n ): AsyncGenerator<unknown> {\n const accumulator = new StreamingAccumulator();\n const ctx = applySessionContext();\n\n try {\n for await (const chunk of stream) {\n const extracted = extractGeminiResponse(chunk);\n if (extracted.text) accumulator.addContent(extracted.text);\n if (Array.isArray(extracted.functionCalls)) {\n for (const fc of extracted.functionCalls) accumulator.addToolCall(fc);\n }\n if (extracted.finishReason != null) {\n accumulator.finishReason = String(extracted.finishReason);\n }\n accumulator.setUsage({\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n totalTokens: extracted.totalTokens,\n });\n yield chunk;\n }\n } catch (error) {\n accumulator.setError(\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n } finally {\n if (finalResponse != null) {\n try {\n const extractedFinal = extractGeminiResponse(await finalResponse);\n accumulator.setUsage({\n inputTokens: extractedFinal.inputTokens,\n outputTokens: extractedFinal.outputTokens,\n totalTokens: extractedFinal.totalTokens,\n });\n if (extractedFinal.finishReason != null) {\n accumulator.finishReason = String(extractedFinal.finishReason);\n }\n if (Array.isArray(extractedFinal.functionCalls)) {\n for (const fc of extractedFinal.functionCalls) {\n accumulator.addToolCall(fc);\n }\n }\n } catch {\n // best-effort final response extraction\n }\n }\n\n const state = accumulator.getState();\n let costUsd: number | null = null;\n if (state.inputTokens != null && state.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName: model,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._track({\n userId: ctx.userId ?? 'unknown',\n modelName: model,\n provider: 'gemini',\n responseContent: state.content,\n latencyMs: accumulator.elapsedMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n turnId: ctx.turnId ?? undefined,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n totalCostUsd: costUsd,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : undefined,\n systemPrompt: extractGeminiSystemPrompt(params),\n temperature: extractGeminiTemperature(params),\n topP: extractGeminiTopP(params),\n maxOutputTokens: extractGeminiMaxOutputTokens(params),\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n isError: state.isError,\n errorMessage: state.errorMessage,\n });\n }\n }\n}\n\nexport function extractGeminiResponse(response: unknown): {\n text: string;\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n finishReason?: string;\n functionCalls?: Array<Record<string, unknown>>;\n} {\n const resp = response as GeminiResponse;\n const respObj = resp.response ?? resp;\n let text = '';\n if (typeof respObj.text === 'function') {\n try {\n text = String(respObj.text());\n } catch {\n // text() throws when the response has no candidates (e.g. safety block)\n }\n }\n const usage = respObj.usageMetadata;\n\n const candidate = respObj.candidates?.[0];\n const finishReason = candidate?.finishReason;\n\n const parts = candidate?.content?.parts;\n const functionCalls = parts\n ?.filter((p) => p.functionCall != null)\n .map((p) => p.functionCall as Record<string, unknown>);\n\n return {\n text,\n inputTokens: usage?.promptTokenCount,\n outputTokens: usage?.candidatesTokenCount,\n totalTokens: usage?.totalTokenCount,\n finishReason,\n functionCalls: functionCalls?.length ? functionCalls : undefined,\n };\n}\n\nfunction extractGeminiSystemPrompt(\n params: Record<string, unknown>,\n): string | undefined {\n const systemInstruction =\n (params.systemInstruction as string | undefined) ??\n ((params.generationConfig as Record<string, unknown> | undefined)\n ?.systemInstruction as string | undefined);\n return systemInstruction;\n}\n\nfunction extractGeminiTemperature(\n params: Record<string, unknown>,\n): number | undefined {\n return (params.generationConfig as Record<string, unknown> | undefined)\n ?.temperature as number | undefined;\n}\n\nfunction extractGeminiTopP(\n params: Record<string, unknown>,\n): number | undefined {\n return (params.generationConfig as Record<string, unknown> | undefined)\n ?.topP as number | undefined;\n}\n\nfunction extractGeminiMaxOutputTokens(\n params: Record<string, unknown>,\n): number | undefined {\n return (params.generationConfig as Record<string, unknown> | undefined)\n ?.maxOutputTokens as number | undefined;\n}\n\nfunction _isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value != null &&\n typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] ===\n 'function'\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gemini.js","names":["_GeminiModule: Record<string, unknown> | null","costUsd: number | null"],"sources":["../../src/providers/gemini.ts"],"sourcesContent":["/**\n * Google Gemini provider wrapper with automatic tracking.\n */\n\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport type { AmplitudeOrAI, GeminiResponse } from '../types.js';\nimport { calculateCost } from '../utils/costs.js';\nimport { tryRequire } from '../utils/resolve-module.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\nimport { applySessionContext, BaseAIProvider, contextFields } from './base.js';\n\nconst _resolved = tryRequire('@google/generative-ai');\nexport const GEMINI_AVAILABLE = _resolved != null;\nconst _GeminiModule: Record<string, unknown> | null = _resolved;\n\nexport { _GeminiModule };\n\nexport interface GeminiOptions {\n amplitude: AmplitudeOrAI;\n apiKey?: string;\n privacyConfig?: PrivacyConfig | null;\n /** Pass the `@google/generative-ai` module directly to bypass `tryRequire` (required in bundler environments). */\n geminiModule?: unknown;\n}\n\nexport class Gemini extends BaseAIProvider {\n private _client: unknown;\n\n constructor(options: GeminiOptions) {\n super({\n amplitude: options.amplitude,\n privacyConfig: options.privacyConfig,\n providerName: 'gemini',\n });\n\n const mod =\n (options.geminiModule as Record<string, unknown> | null) ?? _GeminiModule;\n if (mod == null) {\n throw new Error(\n '@google/generative-ai package is required. Install it with: npm install @google/generative-ai — or pass the module directly via the geminiModule option.',\n );\n }\n\n const GoogleGenAI = mod.GoogleGenerativeAI as new (\n apiKey: string,\n ) => unknown;\n this._client = new GoogleGenAI(options.apiKey ?? '');\n }\n\n async generateContent(\n model: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const clientObj = this._client as Record<string, unknown>;\n const getModel = clientObj.getGenerativeModel as (\n opts: Record<string, unknown>,\n ) => Record<string, unknown>;\n const genModel = getModel.call(this._client, { model });\n const generateFn = genModel.generateContent as (\n ...args: unknown[]\n ) => Promise<unknown>;\n\n const startTime = performance.now();\n\n try {\n const response = await generateFn.call(genModel, params);\n const latencyMs = performance.now() - startTime;\n\n const extracted = extractGeminiResponse(response);\n let costUsd: number | null = null;\n if (extracted.inputTokens != null && extracted.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName: model,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n const ctx = applySessionContext();\n this._track({\n ...contextFields(ctx),\n modelName: model,\n provider: 'gemini',\n responseContent: extracted.text,\n latencyMs,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n totalTokens: extracted.totalTokens,\n totalCostUsd: costUsd,\n finishReason: extracted.finishReason,\n toolCalls: extracted.functionCalls?.length\n ? extracted.functionCalls\n : undefined,\n systemPrompt: extractGeminiSystemPrompt(params),\n temperature: extractGeminiTemperature(params),\n topP: extractGeminiTopP(params),\n maxOutputTokens: extractGeminiMaxOutputTokens(params),\n isStreaming: false,\n });\n\n return response;\n } catch (error) {\n const latencyMs = performance.now() - startTime;\n const ctx = applySessionContext();\n\n this._track({\n ...contextFields(ctx),\n modelName: model,\n provider: 'gemini',\n responseContent: '',\n latencyMs,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n\n throw error;\n }\n }\n\n async generateContentStream(\n model: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const ctx = applySessionContext();\n const startTime = performance.now();\n try {\n const clientObj = this._client as Record<string, unknown>;\n const getModel = clientObj.getGenerativeModel as (\n opts: Record<string, unknown>,\n ) => Record<string, unknown>;\n const genModel = getModel.call(this._client, { model });\n const streamFn = genModel.generateContentStream as\n | ((...args: unknown[]) => Promise<unknown>)\n | undefined;\n if (typeof streamFn !== 'function') {\n throw new Error('Gemini SDK does not expose generateContentStream');\n }\n\n const response = await streamFn.call(genModel, params);\n const streamResponse = response as Record<string, unknown>;\n const stream = streamResponse.stream as\n | AsyncIterable<unknown>\n | undefined;\n const finalResponse = streamResponse.response as\n | Promise<unknown>\n | undefined;\n\n if (!_isAsyncIterable(stream)) {\n throw new Error('Gemini stream response is not AsyncIterable');\n }\n\n return {\n ...streamResponse,\n stream: this._wrapStream(model, params, stream, finalResponse, ctx),\n };\n } catch (error) {\n this._track({\n ...contextFields(ctx),\n modelName: model,\n provider: 'gemini',\n responseContent: '',\n latencyMs: performance.now() - startTime,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n isStreaming: true,\n });\n throw error;\n }\n }\n\n get client(): unknown {\n return this._client;\n }\n\n private async *_wrapStream(\n model: string,\n params: Record<string, unknown>,\n stream: AsyncIterable<unknown>,\n finalResponse: Promise<unknown> | undefined,\n ctx: ReturnType<typeof applySessionContext>,\n ): AsyncGenerator<unknown> {\n const accumulator = new StreamingAccumulator();\n\n try {\n for await (const chunk of stream) {\n const extracted = extractGeminiResponse(chunk);\n if (extracted.text) accumulator.addContent(extracted.text);\n if (Array.isArray(extracted.functionCalls)) {\n for (const fc of extracted.functionCalls) accumulator.addToolCall(fc);\n }\n if (extracted.finishReason != null) {\n accumulator.finishReason = String(extracted.finishReason);\n }\n accumulator.setUsage({\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n totalTokens: extracted.totalTokens,\n });\n yield chunk;\n }\n } catch (error) {\n accumulator.setError(\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n } finally {\n if (finalResponse != null) {\n try {\n const extractedFinal = extractGeminiResponse(await finalResponse);\n accumulator.setUsage({\n inputTokens: extractedFinal.inputTokens,\n outputTokens: extractedFinal.outputTokens,\n totalTokens: extractedFinal.totalTokens,\n });\n if (extractedFinal.finishReason != null) {\n accumulator.finishReason = String(extractedFinal.finishReason);\n }\n if (\n Array.isArray(extractedFinal.functionCalls) &&\n accumulator.toolCalls.length === 0\n ) {\n for (const fc of extractedFinal.functionCalls) {\n accumulator.addToolCall(fc);\n }\n }\n } catch {\n // best-effort final response extraction\n }\n }\n\n const state = accumulator.getState();\n let costUsd: number | null = null;\n if (state.inputTokens != null && state.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName: model,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._track({\n ...contextFields(ctx),\n modelName: model,\n provider: 'gemini',\n responseContent: state.content,\n latencyMs: accumulator.elapsedMs,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n totalCostUsd: costUsd,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : undefined,\n systemPrompt: extractGeminiSystemPrompt(params),\n temperature: extractGeminiTemperature(params),\n topP: extractGeminiTopP(params),\n maxOutputTokens: extractGeminiMaxOutputTokens(params),\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n isError: state.isError,\n errorMessage: state.errorMessage,\n });\n }\n }\n}\n\nexport function extractGeminiResponse(response: unknown): {\n text: string;\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n finishReason?: string;\n functionCalls?: Array<Record<string, unknown>>;\n} {\n const resp = response as GeminiResponse;\n const respObj = resp.response ?? resp;\n let text = '';\n if (typeof respObj.text === 'function') {\n try {\n text = String(respObj.text());\n } catch {\n // text() throws when the response has no candidates (e.g. safety block)\n }\n }\n const usage = respObj.usageMetadata;\n\n const candidate = respObj.candidates?.[0];\n const finishReason = candidate?.finishReason;\n\n const parts = candidate?.content?.parts;\n const functionCalls = parts\n ?.filter((p) => p.functionCall != null)\n .map((p) => p.functionCall as Record<string, unknown>);\n\n return {\n text,\n inputTokens: usage?.promptTokenCount,\n outputTokens: usage?.candidatesTokenCount,\n totalTokens: usage?.totalTokenCount,\n finishReason,\n functionCalls: functionCalls?.length ? functionCalls : undefined,\n };\n}\n\nfunction extractGeminiSystemPrompt(\n params: Record<string, unknown>,\n): string | undefined {\n const systemInstruction =\n (params.systemInstruction as string | undefined) ??\n ((params.generationConfig as Record<string, unknown> | undefined)\n ?.systemInstruction as string | undefined);\n return systemInstruction;\n}\n\nfunction extractGeminiTemperature(\n params: Record<string, unknown>,\n): number | undefined {\n return (params.generationConfig as Record<string, unknown> | undefined)\n ?.temperature as number | undefined;\n}\n\nfunction extractGeminiTopP(\n params: Record<string, unknown>,\n): number | undefined {\n return (params.generationConfig as Record<string, unknown> | undefined)\n ?.topP as number | undefined;\n}\n\nfunction extractGeminiMaxOutputTokens(\n params: Record<string, unknown>,\n): number | undefined {\n return (params.generationConfig as Record<string, unknown> | undefined)\n ?.maxOutputTokens as number | undefined;\n}\n\nfunction _isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value != null &&\n typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] ===\n 'function'\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mistral.d.ts","names":[],"sources":["../../src/providers/mistral.ts"],"sourcesContent":[],"mappings":";;;;;;AAaM,cADO,iBACS,
|
|
1
|
+
{"version":3,"file":"mistral.d.ts","names":[],"sources":["../../src/providers/mistral.ts"],"sourcesContent":[],"mappings":";;;;;;AAaM,cADO,iBACS,EAAA,OAAM;AAI5B,cAJM,cAIyB,EAJT,MAKT,CAAA,MAAA,EAAA,OAEK,CAAA,GAAA,IAAA;AAOD,UAVA,cAAA,CAUA;EAEM,SAAA,EAXV,aAWU;EAJM,MAAA,CAAA,EAAA,MAAA;EAAc,aAAA,CAAA,EALzB,aAKyB,GAAA,IAAA;EAoC9B;EAI2B,aAAA,CAAA,EAAA,OAAA;;AAQW,cAhDtC,OAAA,SAAgB,cAAA,CAgDsB;EAkF5B,QAAA,OAAA;EAA0B,SAAA,IAAA,EAhIhC,WAgIgC;EAAO,WAAA,CAAA,OAAA,EA9HjC,cA8HiC;;;cA9F3C,WAAA;;;wCAI2B;mBAQf,0BAA0B;iBAkF5B,0BAA0B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tryRequire } from "../utils/resolve-module.js";
|
|
2
2
|
import { calculateCost } from "../utils/costs.js";
|
|
3
3
|
import { StreamingAccumulator } from "../utils/streaming.js";
|
|
4
|
-
import { BaseAIProvider, applySessionContext } from "./base.js";
|
|
4
|
+
import { BaseAIProvider, applySessionContext, contextFields } from "./base.js";
|
|
5
5
|
|
|
6
6
|
//#region src/providers/mistral.ts
|
|
7
7
|
const _resolved = tryRequire("@mistralai/mistralai");
|
|
@@ -58,16 +58,11 @@ var WrappedChat = class {
|
|
|
58
58
|
});
|
|
59
59
|
} catch {}
|
|
60
60
|
this._trackFn({
|
|
61
|
-
|
|
61
|
+
...contextFields(ctx),
|
|
62
62
|
modelName,
|
|
63
63
|
provider: "mistral",
|
|
64
64
|
responseContent: extractMistralContent(choice?.message?.content),
|
|
65
65
|
latencyMs,
|
|
66
|
-
sessionId: ctx.sessionId,
|
|
67
|
-
traceId: ctx.traceId,
|
|
68
|
-
turnId: ctx.turnId ?? void 0,
|
|
69
|
-
agentId: ctx.agentId,
|
|
70
|
-
env: ctx.env,
|
|
71
66
|
inputTokens: usage?.prompt_tokens,
|
|
72
67
|
outputTokens: usage?.completion_tokens,
|
|
73
68
|
totalTokens: usage?.total_tokens,
|
|
@@ -84,15 +79,11 @@ var WrappedChat = class {
|
|
|
84
79
|
} catch (error) {
|
|
85
80
|
const latencyMs = performance.now() - startTime;
|
|
86
81
|
this._trackFn({
|
|
87
|
-
|
|
82
|
+
...contextFields(ctx),
|
|
88
83
|
modelName: String(params.model ?? "unknown"),
|
|
89
84
|
provider: "mistral",
|
|
90
85
|
responseContent: "",
|
|
91
86
|
latencyMs,
|
|
92
|
-
sessionId: ctx.sessionId,
|
|
93
|
-
traceId: ctx.traceId,
|
|
94
|
-
agentId: ctx.agentId,
|
|
95
|
-
env: ctx.env,
|
|
96
87
|
isError: true,
|
|
97
88
|
errorMessage: error instanceof Error ? error.message : String(error)
|
|
98
89
|
});
|
|
@@ -111,15 +102,11 @@ var WrappedChat = class {
|
|
|
111
102
|
return this._wrapStream(response, params, ctx);
|
|
112
103
|
} catch (error) {
|
|
113
104
|
this._trackFn({
|
|
114
|
-
|
|
105
|
+
...contextFields(ctx),
|
|
115
106
|
modelName: String(params.model ?? "unknown"),
|
|
116
107
|
provider: "mistral",
|
|
117
108
|
responseContent: "",
|
|
118
109
|
latencyMs: performance.now() - startTime,
|
|
119
|
-
sessionId: ctx.sessionId,
|
|
120
|
-
traceId: ctx.traceId,
|
|
121
|
-
agentId: ctx.agentId,
|
|
122
|
-
env: ctx.env,
|
|
123
110
|
isError: true,
|
|
124
111
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
125
112
|
isStreaming: true
|
|
@@ -139,7 +126,21 @@ var WrappedChat = class {
|
|
|
139
126
|
const content = delta?.content ?? message?.content;
|
|
140
127
|
if (typeof content === "string" && content.length > 0) accumulator.addContent(content);
|
|
141
128
|
const toolCalls = delta?.tool_calls ?? message?.tool_calls;
|
|
142
|
-
if (Array.isArray(toolCalls)) for (const call of toolCalls)
|
|
129
|
+
if (Array.isArray(toolCalls)) for (const call of toolCalls) {
|
|
130
|
+
const idx = call.index;
|
|
131
|
+
const id = call.id;
|
|
132
|
+
const fn = call.function;
|
|
133
|
+
if (idx != null && id && fn?.name != null) accumulator.setToolCallAt(idx, {
|
|
134
|
+
type: "function",
|
|
135
|
+
id,
|
|
136
|
+
function: {
|
|
137
|
+
name: fn.name,
|
|
138
|
+
arguments: fn.arguments ?? ""
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
else if (idx != null && fn?.arguments) accumulator.appendToolCallArgs(idx, fn.arguments);
|
|
142
|
+
else accumulator.addToolCall(call);
|
|
143
|
+
}
|
|
143
144
|
const finishReason = choices?.[0]?.finish_reason;
|
|
144
145
|
if (finishReason != null) accumulator.finishReason = String(finishReason);
|
|
145
146
|
const usage = c.usage;
|
|
@@ -165,16 +166,11 @@ var WrappedChat = class {
|
|
|
165
166
|
});
|
|
166
167
|
} catch {}
|
|
167
168
|
this._trackFn({
|
|
168
|
-
|
|
169
|
+
...contextFields(sessionCtx),
|
|
169
170
|
modelName,
|
|
170
171
|
provider: "mistral",
|
|
171
172
|
responseContent: state.content,
|
|
172
173
|
latencyMs: accumulator.elapsedMs,
|
|
173
|
-
sessionId: sessionCtx.sessionId,
|
|
174
|
-
traceId: sessionCtx.traceId,
|
|
175
|
-
turnId: sessionCtx.turnId ?? void 0,
|
|
176
|
-
agentId: sessionCtx.agentId,
|
|
177
|
-
env: sessionCtx.env,
|
|
178
174
|
inputTokens: state.inputTokens,
|
|
179
175
|
outputTokens: state.outputTokens,
|
|
180
176
|
totalTokens: state.totalTokens,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mistral.js","names":["_MistralModule: Record<string, unknown> | null","clientOpts: Record<string, unknown>","costUsd: number | null"],"sources":["../../src/providers/mistral.ts"],"sourcesContent":["/**\n * Mistral AI provider wrapper with automatic tracking.\n */\n\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport type { AmplitudeOrAI, MistralChatResponse, TrackFn } from '../types.js';\nimport { calculateCost } from '../utils/costs.js';\nimport { tryRequire } from '../utils/resolve-module.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\nimport { applySessionContext, BaseAIProvider } from './base.js';\n\nconst _resolved = tryRequire('@mistralai/mistralai');\nexport const MISTRAL_AVAILABLE = _resolved != null;\nconst _MistralModule: Record<string, unknown> | null = _resolved;\n\nexport { _MistralModule };\n\nexport interface MistralOptions {\n amplitude: AmplitudeOrAI;\n apiKey?: string;\n privacyConfig?: PrivacyConfig | null;\n /** Pass the `@mistralai/mistralai` module directly to bypass `tryRequire` (required in bundler environments). */\n mistralModule?: unknown;\n}\n\nexport class Mistral extends BaseAIProvider {\n private _client: unknown;\n readonly chat: WrappedChat;\n\n constructor(options: MistralOptions) {\n super({\n amplitude: options.amplitude,\n privacyConfig: options.privacyConfig,\n providerName: 'mistral',\n });\n\n const mod =\n (options.mistralModule as Record<string, unknown> | null) ??\n _MistralModule;\n if (mod == null) {\n throw new Error(\n '@mistralai/mistralai package is required. Install it with: npm install @mistralai/mistralai — or pass the module directly via the mistralModule option.',\n );\n }\n\n const MistralSDK = (mod.Mistral ??\n mod.MistralClient ??\n mod.default) as new (opts: Record<string, unknown>) => unknown;\n\n const clientOpts: Record<string, unknown> = {};\n if (options.apiKey) clientOpts.apiKey = options.apiKey;\n\n this._client = new MistralSDK(clientOpts);\n this.chat = new WrappedChat(this._client, this.trackFn());\n }\n\n get client(): unknown {\n return this._client;\n }\n}\n\nexport class WrappedChat {\n private _client: unknown;\n private _trackFn: TrackFn;\n\n constructor(client: unknown, trackFn: TrackFn) {\n this._client = client;\n this._trackFn =\n typeof trackFn === 'function'\n ? trackFn\n : (trackFn as unknown as { trackFn(): TrackFn }).trackFn();\n }\n\n async complete(params: Record<string, unknown>): Promise<unknown> {\n const clientObj = this._client as Record<string, unknown>;\n const chat = clientObj.chat as Record<string, unknown>;\n const completeFn = chat.complete as (\n ...args: unknown[]\n ) => Promise<unknown>;\n\n const startTime = performance.now();\n const ctx = applySessionContext();\n\n try {\n const response = await completeFn.call(chat, params);\n if (\n (params.stream === true || chat.stream != null) &&\n _isAsyncIterable(response)\n ) {\n return this._wrapStream(\n response as AsyncIterable<unknown>,\n params,\n ctx,\n );\n }\n const latencyMs = performance.now() - startTime;\n\n const resp = response as MistralChatResponse;\n const choice = resp.choices?.[0];\n const usage = resp.usage;\n const modelName = String(resp.model ?? params.model ?? 'unknown');\n const toolCalls = (\n choice?.message as { tool_calls?: Array<Record<string, unknown>> }\n )?.tool_calls;\n\n let costUsd: number | null = null;\n if (usage?.prompt_tokens != null && usage?.completion_tokens != null) {\n try {\n costUsd = calculateCost({\n modelName,\n inputTokens: usage.prompt_tokens,\n outputTokens: usage.completion_tokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._trackFn({\n userId: ctx.userId ?? 'unknown',\n modelName,\n provider: 'mistral',\n responseContent: extractMistralContent(choice?.message?.content),\n latencyMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n turnId: ctx.turnId ?? undefined,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens: usage?.prompt_tokens,\n outputTokens: usage?.completion_tokens,\n totalTokens: usage?.total_tokens,\n totalCostUsd: costUsd,\n finishReason: choice?.finish_reason,\n toolCalls: toolCalls ?? undefined,\n systemPrompt: extractMistralSystemPrompt(params),\n temperature: params.temperature as number | undefined,\n topP: params.top_p as number | undefined,\n maxOutputTokens: params.max_tokens as number | undefined,\n isStreaming: false,\n });\n\n return response;\n } catch (error) {\n const latencyMs = performance.now() - startTime;\n\n this._trackFn({\n userId: ctx.userId ?? 'unknown',\n modelName: String(params.model ?? 'unknown'),\n provider: 'mistral',\n responseContent: '',\n latencyMs,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n\n throw error;\n }\n }\n\n async stream(params: Record<string, unknown>): Promise<unknown> {\n const ctx = applySessionContext();\n const startTime = performance.now();\n try {\n const clientObj = this._client as Record<string, unknown>;\n const chat = clientObj.chat as Record<string, unknown>;\n const streamFn = chat.stream as\n | ((...args: unknown[]) => Promise<unknown>)\n | undefined;\n if (typeof streamFn !== 'function') {\n throw new Error('Mistral SDK does not expose chat.stream');\n }\n\n const response = await streamFn.call(chat, params);\n if (!_isAsyncIterable(response)) {\n throw new Error('Mistral stream response is not AsyncIterable');\n }\n return this._wrapStream(response as AsyncIterable<unknown>, params, ctx);\n } catch (error) {\n this._trackFn({\n userId: ctx.userId ?? 'unknown',\n modelName: String(params.model ?? 'unknown'),\n provider: 'mistral',\n responseContent: '',\n latencyMs: performance.now() - startTime,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n isStreaming: true,\n });\n throw error;\n }\n }\n\n private async *_wrapStream(\n stream: AsyncIterable<unknown>,\n params: Record<string, unknown>,\n sessionCtx: ReturnType<typeof applySessionContext>,\n ): AsyncGenerator<unknown> {\n const accumulator = new StreamingAccumulator();\n accumulator.model = String(params.model ?? 'unknown');\n\n try {\n for await (const chunk of stream) {\n const c = chunk as Record<string, unknown>;\n const choices = c.choices as Array<Record<string, unknown>> | undefined;\n const delta = choices?.[0]?.delta as\n | Record<string, unknown>\n | undefined;\n const message = choices?.[0]?.message as\n | Record<string, unknown>\n | undefined;\n\n const content =\n (delta?.content as string | undefined) ??\n (message?.content as string | undefined);\n if (typeof content === 'string' && content.length > 0) {\n accumulator.addContent(content);\n }\n\n const toolCalls =\n (delta?.tool_calls as Array<Record<string, unknown>> | undefined) ??\n (message?.tool_calls as Array<Record<string, unknown>> | undefined);\n if (Array.isArray(toolCalls)) {\n for (const call of toolCalls) accumulator.addToolCall(call);\n }\n\n const finishReason = choices?.[0]?.finish_reason;\n if (finishReason != null)\n accumulator.finishReason = String(finishReason);\n\n const usage = c.usage as Record<string, unknown> | undefined;\n accumulator.setUsage({\n inputTokens: usage?.prompt_tokens as number | undefined,\n outputTokens: usage?.completion_tokens as number | undefined,\n totalTokens: usage?.total_tokens as number | undefined,\n });\n\n yield chunk;\n }\n } catch (error) {\n accumulator.setError(\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n } finally {\n const state = accumulator.getState();\n const modelName = String(accumulator.model ?? params.model ?? 'unknown');\n let costUsd: number | null = null;\n if (state.inputTokens != null && state.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._trackFn({\n userId: sessionCtx.userId ?? 'unknown',\n modelName,\n provider: 'mistral',\n responseContent: state.content,\n latencyMs: accumulator.elapsedMs,\n sessionId: sessionCtx.sessionId,\n traceId: sessionCtx.traceId,\n turnId: sessionCtx.turnId ?? undefined,\n agentId: sessionCtx.agentId,\n env: sessionCtx.env,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n totalCostUsd: costUsd,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : undefined,\n systemPrompt: extractMistralSystemPrompt(params),\n temperature: params.temperature as number | undefined,\n topP: params.top_p as number | undefined,\n maxOutputTokens: params.max_tokens as number | undefined,\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n isError: state.isError,\n errorMessage: state.errorMessage,\n });\n }\n }\n}\n\nfunction extractMistralContent(content: unknown): string {\n if (typeof content === 'string') return content;\n if (content == null) return '';\n if (Array.isArray(content)) {\n return content\n .map((chunk) => {\n if (typeof chunk === 'string') return chunk;\n if (typeof chunk === 'object' && chunk != null) {\n return String((chunk as Record<string, unknown>).text ?? '');\n }\n return '';\n })\n .filter(Boolean)\n .join('');\n }\n return String(content);\n}\n\nfunction extractMistralSystemPrompt(\n params: Record<string, unknown>,\n): string | undefined {\n const messages = params.messages as\n | Array<Record<string, unknown>>\n | undefined;\n if (!Array.isArray(messages)) return undefined;\n const systemMessage = messages.find((m) => m.role === 'system');\n return typeof systemMessage?.content === 'string'\n ? systemMessage.content\n : undefined;\n}\n\nfunction _isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value != null &&\n typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] ===\n 'function'\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mistral.js","names":["_MistralModule: Record<string, unknown> | null","clientOpts: Record<string, unknown>","costUsd: number | null"],"sources":["../../src/providers/mistral.ts"],"sourcesContent":["/**\n * Mistral AI provider wrapper with automatic tracking.\n */\n\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport type { AmplitudeOrAI, MistralChatResponse, TrackFn } from '../types.js';\nimport { calculateCost } from '../utils/costs.js';\nimport { tryRequire } from '../utils/resolve-module.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\nimport { applySessionContext, BaseAIProvider, contextFields } from './base.js';\n\nconst _resolved = tryRequire('@mistralai/mistralai');\nexport const MISTRAL_AVAILABLE = _resolved != null;\nconst _MistralModule: Record<string, unknown> | null = _resolved;\n\nexport { _MistralModule };\n\nexport interface MistralOptions {\n amplitude: AmplitudeOrAI;\n apiKey?: string;\n privacyConfig?: PrivacyConfig | null;\n /** Pass the `@mistralai/mistralai` module directly to bypass `tryRequire` (required in bundler environments). */\n mistralModule?: unknown;\n}\n\nexport class Mistral extends BaseAIProvider {\n private _client: unknown;\n readonly chat: WrappedChat;\n\n constructor(options: MistralOptions) {\n super({\n amplitude: options.amplitude,\n privacyConfig: options.privacyConfig,\n providerName: 'mistral',\n });\n\n const mod =\n (options.mistralModule as Record<string, unknown> | null) ??\n _MistralModule;\n if (mod == null) {\n throw new Error(\n '@mistralai/mistralai package is required. Install it with: npm install @mistralai/mistralai — or pass the module directly via the mistralModule option.',\n );\n }\n\n const MistralSDK = (mod.Mistral ??\n mod.MistralClient ??\n mod.default) as new (opts: Record<string, unknown>) => unknown;\n\n const clientOpts: Record<string, unknown> = {};\n if (options.apiKey) clientOpts.apiKey = options.apiKey;\n\n this._client = new MistralSDK(clientOpts);\n this.chat = new WrappedChat(this._client, this.trackFn());\n }\n\n get client(): unknown {\n return this._client;\n }\n}\n\nexport class WrappedChat {\n private _client: unknown;\n private _trackFn: TrackFn;\n\n constructor(client: unknown, trackFn: TrackFn) {\n this._client = client;\n this._trackFn =\n typeof trackFn === 'function'\n ? trackFn\n : (trackFn as unknown as { trackFn(): TrackFn }).trackFn();\n }\n\n async complete(params: Record<string, unknown>): Promise<unknown> {\n const clientObj = this._client as Record<string, unknown>;\n const chat = clientObj.chat as Record<string, unknown>;\n const completeFn = chat.complete as (\n ...args: unknown[]\n ) => Promise<unknown>;\n\n const startTime = performance.now();\n const ctx = applySessionContext();\n\n try {\n const response = await completeFn.call(chat, params);\n if (\n (params.stream === true || chat.stream != null) &&\n _isAsyncIterable(response)\n ) {\n return this._wrapStream(\n response as AsyncIterable<unknown>,\n params,\n ctx,\n );\n }\n const latencyMs = performance.now() - startTime;\n\n const resp = response as MistralChatResponse;\n const choice = resp.choices?.[0];\n const usage = resp.usage;\n const modelName = String(resp.model ?? params.model ?? 'unknown');\n const toolCalls = (\n choice?.message as { tool_calls?: Array<Record<string, unknown>> }\n )?.tool_calls;\n\n let costUsd: number | null = null;\n if (usage?.prompt_tokens != null && usage?.completion_tokens != null) {\n try {\n costUsd = calculateCost({\n modelName,\n inputTokens: usage.prompt_tokens,\n outputTokens: usage.completion_tokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._trackFn({\n ...contextFields(ctx),\n modelName,\n provider: 'mistral',\n responseContent: extractMistralContent(choice?.message?.content),\n latencyMs,\n inputTokens: usage?.prompt_tokens,\n outputTokens: usage?.completion_tokens,\n totalTokens: usage?.total_tokens,\n totalCostUsd: costUsd,\n finishReason: choice?.finish_reason,\n toolCalls: toolCalls ?? undefined,\n systemPrompt: extractMistralSystemPrompt(params),\n temperature: params.temperature as number | undefined,\n topP: params.top_p as number | undefined,\n maxOutputTokens: params.max_tokens as number | undefined,\n isStreaming: false,\n });\n\n return response;\n } catch (error) {\n const latencyMs = performance.now() - startTime;\n\n this._trackFn({\n ...contextFields(ctx),\n modelName: String(params.model ?? 'unknown'),\n provider: 'mistral',\n responseContent: '',\n latencyMs,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n\n throw error;\n }\n }\n\n async stream(params: Record<string, unknown>): Promise<unknown> {\n const ctx = applySessionContext();\n const startTime = performance.now();\n try {\n const clientObj = this._client as Record<string, unknown>;\n const chat = clientObj.chat as Record<string, unknown>;\n const streamFn = chat.stream as\n | ((...args: unknown[]) => Promise<unknown>)\n | undefined;\n if (typeof streamFn !== 'function') {\n throw new Error('Mistral SDK does not expose chat.stream');\n }\n\n const response = await streamFn.call(chat, params);\n if (!_isAsyncIterable(response)) {\n throw new Error('Mistral stream response is not AsyncIterable');\n }\n return this._wrapStream(response as AsyncIterable<unknown>, params, ctx);\n } catch (error) {\n this._trackFn({\n ...contextFields(ctx),\n modelName: String(params.model ?? 'unknown'),\n provider: 'mistral',\n responseContent: '',\n latencyMs: performance.now() - startTime,\n isError: true,\n errorMessage: error instanceof Error ? error.message : String(error),\n isStreaming: true,\n });\n throw error;\n }\n }\n\n private async *_wrapStream(\n stream: AsyncIterable<unknown>,\n params: Record<string, unknown>,\n sessionCtx: ReturnType<typeof applySessionContext>,\n ): AsyncGenerator<unknown> {\n const accumulator = new StreamingAccumulator();\n accumulator.model = String(params.model ?? 'unknown');\n\n try {\n for await (const chunk of stream) {\n const c = chunk as Record<string, unknown>;\n const choices = c.choices as Array<Record<string, unknown>> | undefined;\n const delta = choices?.[0]?.delta as\n | Record<string, unknown>\n | undefined;\n const message = choices?.[0]?.message as\n | Record<string, unknown>\n | undefined;\n\n const content =\n (delta?.content as string | undefined) ??\n (message?.content as string | undefined);\n if (typeof content === 'string' && content.length > 0) {\n accumulator.addContent(content);\n }\n\n const toolCalls =\n (delta?.tool_calls as Array<Record<string, unknown>> | undefined) ??\n (message?.tool_calls as Array<Record<string, unknown>> | undefined);\n if (Array.isArray(toolCalls)) {\n for (const call of toolCalls) {\n const idx = call.index as number | undefined;\n const id = call.id as string | undefined;\n const fn = call.function as Record<string, unknown> | undefined;\n if (idx != null && id && fn?.name != null) {\n accumulator.setToolCallAt(idx, {\n type: 'function',\n id,\n function: {\n name: fn.name,\n arguments: ((fn.arguments as string) ?? ''),\n },\n });\n } else if (idx != null && fn?.arguments) {\n accumulator.appendToolCallArgs(idx, fn.arguments as string);\n } else {\n accumulator.addToolCall(call);\n }\n }\n }\n\n const finishReason = choices?.[0]?.finish_reason;\n if (finishReason != null)\n accumulator.finishReason = String(finishReason);\n\n const usage = c.usage as Record<string, unknown> | undefined;\n accumulator.setUsage({\n inputTokens: usage?.prompt_tokens as number | undefined,\n outputTokens: usage?.completion_tokens as number | undefined,\n totalTokens: usage?.total_tokens as number | undefined,\n });\n\n yield chunk;\n }\n } catch (error) {\n accumulator.setError(\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n } finally {\n const state = accumulator.getState();\n const modelName = String(accumulator.model ?? params.model ?? 'unknown');\n let costUsd: number | null = null;\n if (state.inputTokens != null && state.outputTokens != null) {\n try {\n costUsd = calculateCost({\n modelName,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._trackFn({\n ...contextFields(sessionCtx),\n modelName,\n provider: 'mistral',\n responseContent: state.content,\n latencyMs: accumulator.elapsedMs,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n totalCostUsd: costUsd,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : undefined,\n systemPrompt: extractMistralSystemPrompt(params),\n temperature: params.temperature as number | undefined,\n topP: params.top_p as number | undefined,\n maxOutputTokens: params.max_tokens as number | undefined,\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n isError: state.isError,\n errorMessage: state.errorMessage,\n });\n }\n }\n}\n\nfunction extractMistralContent(content: unknown): string {\n if (typeof content === 'string') return content;\n if (content == null) return '';\n if (Array.isArray(content)) {\n return content\n .map((chunk) => {\n if (typeof chunk === 'string') return chunk;\n if (typeof chunk === 'object' && chunk != null) {\n return String((chunk as Record<string, unknown>).text ?? '');\n }\n return '';\n })\n .filter(Boolean)\n .join('');\n }\n return String(content);\n}\n\nfunction extractMistralSystemPrompt(\n params: Record<string, unknown>,\n): string | undefined {\n const messages = params.messages as\n | Array<Record<string, unknown>>\n | undefined;\n if (!Array.isArray(messages)) return undefined;\n const systemMessage = messages.find((m) => m.role === 'system');\n return typeof systemMessage?.content === 'string'\n ? systemMessage.content\n : undefined;\n}\n\nfunction _isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value != null &&\n typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] ===\n 'function'\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","names":[],"sources":["../../src/providers/openai.ts"],"sourcesContent":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","names":[],"sources":["../../src/providers/openai.ts"],"sourcesContent":[],"mappings":";;;;;;AAoDiB,cAnBJ,gBAmBI,EAAA,OAAA;cAlBX,aAmBgB,EAnBD,MAmBC,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;AA6CN,UA5DC,aAAA,CA4DD;EAhDN,SAAA,EAXG,aAWH;EAAc,MAAA,CAAA,EAAA,MAAA;EAqDX,OAAA,CAAA,EAAA,MAAW;EACA,aAAA,CAAA,EA9DN,aA8DM,GAAA,IAAA;EAIX,gBAAA,CAAA,EAAA,OAAA;EACE;EACI,YAAA,CAAA,EAAA,OAAA;;AAeN,cA7EA,MA6EkB,CAAA,gBA5Eb,MA4Ea,CAAA,MAAA,EAAA,OAAA,CAAA,GA5Ea,MA4Eb,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,SA3ErB,cAAA,CA2EqB;EAClB,QAAA,OAAA;EAQI,SAAA,IAAA,EAlFA,WAkFA;EACJ,SAAA,SAAA,EAlFS,gBAkFT;EACE,QAAA,iBAAA;EACI,WAAA,CAAA,OAAA,EAjFI,aAiFJ;EAgBP,IAAA,MAAA,CAAA,CAAA,EAvDI,OAuDJ;;AAEC,cApDA,WAAA,CAoDA;EAAyB,SAAA,WAAA,EAnDd,kBAmDc;EAAjC,WAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,EA/CQ,OA+CR,EAAA,SAAA,EA9CU,aA8CV,EAAA,aAAA,EA7Cc,aA6Cd,GAAA,IAAA,EAAA,gBAAA,EAAA,OAAA;;AAyGoB,cAvIZ,kBAAA,CAuIY;EACZ,SAAA,EAvIA,MAuIA,CAAA,MAAA,EAAA,OAAA,CAAA;EAAyB,QAAA,QAAA;EAAjC,QAAA,UAAA;EAAO,QAAA,cAAA;EA2LC,QAAA,iBAAgB;EAChB,QAAA,aAAA;EASA,WAAA,CAAA,WAAA,EApUI,MAoUJ,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAnUA,OAmUA,EAAA,SAAA,EAlUE,aAkUF,EAAA,aAAA,EAjUM,aAiUN,GAAA,IAAA,EAAA,gBAAA,EAAA,OAAA,EAAA,YAAA,CAAA,EAAA,MAAA;EACE,MAAA,CAAA,MAAA,EAlTH,MAkTG,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,kBAAA,CAAA,EAjTU,oBAiTV,CAAA,EAhTV,OAgTU,CAhTF,sBAgTE,GAhTuB,aAgTvB,CAAA,OAAA,CAAA,CAAA;EACI,KAAA,CAAA,MAAA,EAzMP,MAyMO,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,kBAAA,CAAA,EAxMM,oBAwMN,CAAA,EAvMd,OAuMc,CAvMN,sBAuMM,GAvMmB,aAuMnB,CAAA,OAAA,CAAA,CAAA;EAkBP,QAAA,WAAA;EACa,QAAA,mBAAA;EACZ,QAAA,mBAAA;;AAAR,cAhCQ,gBAAA,CAgCR;EAkFO,SAAA,EAjHC,MAiHD,CAAA,MAAA,EAAA,OAAA,CAAA;EACa,QAAA,QAAA;EACZ,QAAA,UAAA;EAAR,QAAA,cAAA;EAAO,QAAA,iBAAA;EA2KI,QAAA,aAAA;wCArRH,oBACE,8BACI;iBAkBP,8CACa,uBACpB,QAAQ,iBAAiB;iBAkFlB,8CACa,uBACpB,QAAQ;;;;;iBA2KG,mBAAA,SACN"}
|