@amplitude/ai 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +3 -1
- package/README.md +44 -15
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/integrations/anthropic-tools.js +2 -1
- package/dist/integrations/anthropic-tools.js.map +1 -1
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +35 -5
- package/dist/integrations/langchain.js.map +1 -1
- package/dist/integrations/llamaindex.d.ts.map +1 -1
- package/dist/integrations/llamaindex.js +27 -4
- package/dist/integrations/llamaindex.js.map +1 -1
- package/dist/integrations/openai-agents.js +5 -1
- package/dist/integrations/openai-agents.js.map +1 -1
- package/dist/integrations/opentelemetry.d.ts.map +1 -1
- package/dist/integrations/opentelemetry.js +2 -1
- package/dist/integrations/opentelemetry.js.map +1 -1
- package/dist/mcp/patterns.d.ts.map +1 -1
- package/dist/mcp/patterns.js +6 -0
- package/dist/mcp/patterns.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/validate-file.js +1 -1
- package/dist/mcp/validate-file.js.map +1 -1
- package/dist/patching.d.ts.map +1 -1
- package/dist/patching.js +7 -1
- package/dist/patching.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +11 -20
- 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 +16 -29
- package/dist/providers/bedrock.js.map +1 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +12 -29
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/mistral.d.ts.map +1 -1
- package/dist/providers/mistral.js +24 -26
- package/dist/providers/mistral.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +37 -45
- package/dist/providers/openai.js.map +1 -1
- package/dist/session.d.ts +23 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +44 -1
- package/dist/session.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/costs.d.ts +46 -5
- package/dist/utils/costs.d.ts.map +1 -1
- package/dist/utils/costs.js +115 -26
- package/dist/utils/costs.js.map +1 -1
- package/dist/utils/providers.d.ts +6 -1
- package/dist/utils/providers.d.ts.map +1 -1
- package/dist/utils/providers.js +9 -3
- package/dist/utils/providers.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 +17 -1
- package/llms.txt +1 -1
- package/mcp.schema.json +1 -1
- package/package.json +1 -1
package/dist/providers/base.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PrivacyConfig } from "../core/privacy.js";
|
|
2
|
-
import { AmplitudeLike, AmplitudeOrAI, TrackFn } from "../types.js";
|
|
2
|
+
import { AmplitudeLike, AmplitudeOrAI, TrackCallOptions, TrackFn } from "../types.js";
|
|
3
3
|
import { TrackAiMessageOptions } from "../core/tracking.js";
|
|
4
4
|
import { StreamingAccumulator } from "../utils/streaming.js";
|
|
5
5
|
|
|
@@ -22,6 +22,8 @@ interface ProviderTrackOptions {
|
|
|
22
22
|
agentId?: string | null;
|
|
23
23
|
parentAgentId?: string | null;
|
|
24
24
|
customerOrgId?: string | null;
|
|
25
|
+
agentVersion?: string | null;
|
|
26
|
+
context?: Record<string, unknown> | null;
|
|
25
27
|
env?: string | null;
|
|
26
28
|
groups?: Record<string, unknown> | null;
|
|
27
29
|
eventProperties?: Record<string, unknown> | null;
|
|
@@ -39,6 +41,13 @@ interface ProviderTrackOptions {
|
|
|
39
41
|
declare function applySessionContext(overrides?: ProviderTrackOptions): ProviderTrackOptions & {
|
|
40
42
|
userId: string;
|
|
41
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Extract all context fields from a resolved ProviderTrackOptions into a
|
|
46
|
+
* flat object suitable for spreading into _trackFn() / _track() calls.
|
|
47
|
+
* Ensures all 13 context fields propagate consistently.
|
|
48
|
+
*/
|
|
49
|
+
type TrackContextFields = Pick<TrackCallOptions, 'userId' | 'sessionId' | 'traceId' | 'turnId' | 'agentId' | 'parentAgentId' | 'customerOrgId' | 'agentVersion' | 'context' | 'env' | 'groups' | 'eventProperties'>;
|
|
50
|
+
declare function contextFields(ctx: ProviderTrackOptions): TrackContextFields;
|
|
42
51
|
declare abstract class BaseAIProvider {
|
|
43
52
|
protected _amplitude: AmplitudeLike;
|
|
44
53
|
protected _privacyConfig: PrivacyConfig | null;
|
|
@@ -66,5 +75,5 @@ declare class SimpleStreamingTracker {
|
|
|
66
75
|
finalize(overrides?: ProviderTrackOptions): string;
|
|
67
76
|
}
|
|
68
77
|
//#endregion
|
|
69
|
-
export { BaseAIProvider, ProviderTrackOptions, SimpleStreamingTracker, applySessionContext };
|
|
78
|
+
export { BaseAIProvider, ProviderTrackOptions, SimpleStreamingTracker, TrackContextFields, applySessionContext, contextFields };
|
|
70
79
|
//# sourceMappingURL=base.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/providers/base.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/providers/base.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA2DA;AAgDA;AAgBA;AAiBA;;;;AAOoB,UAjHH,oBAAA,CAiHG;EAQU,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAL,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAmCZ,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAKe,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAsB,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAKrC,aAAA,CAAA,EAAA,MAAA,GAAsB,IAAA;EAEX,aAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAIA,YAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAeK,OAAA,CAAA,EAlLjB,MAkLiB,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;EAAX,GAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAQM,MAAA,CAAA,EAxLb,MAwLa,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;EAIF,eAAA,CAAA,EA3LF,MA2LE,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;EAAyB;;;;;;;;;;;iBA9K/B,mBAAA,aACH,uBACV;;;;;;;;KA8CS,kBAAA,GAAqB,KAC/B;iBAec,aAAA,MAAmB,uBAAuB;uBAiBpC,cAAA;wBACE;4BACI;;;eAIb;oBACK;;;yBAQK,KAAK;aAmCjB;4BAKe;;cAKf,sBAAA;;wBAEW;;;wBAIA;;;kBAeN,WAAW;;wBAQL;uBAIF"}
|
package/dist/providers/base.js
CHANGED
|
@@ -25,10 +25,14 @@ function applySessionContext(overrides = {}) {
|
|
|
25
25
|
if (!result.agentId) result.agentId = ctx.agentId;
|
|
26
26
|
if (!result.parentAgentId) result.parentAgentId = ctx.parentAgentId;
|
|
27
27
|
if (!result.customerOrgId) result.customerOrgId = ctx.customerOrgId;
|
|
28
|
+
if (!result.agentVersion) result.agentVersion = ctx.agentVersion;
|
|
29
|
+
if (!result.context) result.context = ctx.context;
|
|
28
30
|
if (!result.env) result.env = ctx.env;
|
|
29
31
|
if (!result.groups) result.groups = ctx.groups;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
if (result.turnId == null) {
|
|
33
|
+
const turnId = ctx.nextTurnId();
|
|
34
|
+
if (turnId != null) result.turnId = turnId;
|
|
35
|
+
}
|
|
32
36
|
const existingEp = result.eventProperties;
|
|
33
37
|
const ep = existingEp != null ? { ...existingEp } : {};
|
|
34
38
|
if (ctx.idleTimeoutMinutes != null && !(PROP_IDLE_TIMEOUT_MINUTES in ep)) ep[PROP_IDLE_TIMEOUT_MINUTES] = ctx.idleTimeoutMinutes;
|
|
@@ -37,6 +41,22 @@ function applySessionContext(overrides = {}) {
|
|
|
37
41
|
}
|
|
38
42
|
return result;
|
|
39
43
|
}
|
|
44
|
+
function contextFields(ctx) {
|
|
45
|
+
return {
|
|
46
|
+
userId: ctx.userId ?? "unknown",
|
|
47
|
+
sessionId: ctx.sessionId,
|
|
48
|
+
traceId: ctx.traceId,
|
|
49
|
+
turnId: ctx.turnId ?? void 0,
|
|
50
|
+
agentId: ctx.agentId,
|
|
51
|
+
parentAgentId: ctx.parentAgentId,
|
|
52
|
+
customerOrgId: ctx.customerOrgId,
|
|
53
|
+
agentVersion: ctx.agentVersion,
|
|
54
|
+
context: ctx.context,
|
|
55
|
+
env: ctx.env,
|
|
56
|
+
groups: ctx.groups,
|
|
57
|
+
eventProperties: ctx.eventProperties
|
|
58
|
+
};
|
|
59
|
+
}
|
|
40
60
|
var BaseAIProvider = class {
|
|
41
61
|
_amplitude;
|
|
42
62
|
_privacyConfig;
|
|
@@ -55,8 +75,11 @@ var BaseAIProvider = class {
|
|
|
55
75
|
agentId: opts.agentId,
|
|
56
76
|
parentAgentId: opts.parentAgentId,
|
|
57
77
|
customerOrgId: opts.customerOrgId,
|
|
78
|
+
agentVersion: opts.agentVersion,
|
|
79
|
+
context: opts.context,
|
|
58
80
|
env: opts.env,
|
|
59
|
-
groups: opts.groups
|
|
81
|
+
groups: opts.groups,
|
|
82
|
+
eventProperties: opts.eventProperties
|
|
60
83
|
});
|
|
61
84
|
return trackAiMessage({
|
|
62
85
|
...opts,
|
|
@@ -68,8 +91,11 @@ var BaseAIProvider = class {
|
|
|
68
91
|
agentId: merged.agentId ?? opts.agentId,
|
|
69
92
|
parentAgentId: merged.parentAgentId ?? opts.parentAgentId,
|
|
70
93
|
customerOrgId: merged.customerOrgId ?? opts.customerOrgId,
|
|
94
|
+
agentVersion: merged.agentVersion ?? opts.agentVersion,
|
|
95
|
+
context: merged.context ?? opts.context,
|
|
71
96
|
env: merged.env ?? opts.env,
|
|
72
97
|
groups: merged.groups ?? opts.groups,
|
|
98
|
+
eventProperties: merged.eventProperties ?? opts.eventProperties,
|
|
73
99
|
privacyConfig: this._privacyConfig
|
|
74
100
|
});
|
|
75
101
|
}
|
|
@@ -109,7 +135,7 @@ var SimpleStreamingTracker = class {
|
|
|
109
135
|
finalize(overrides = {}) {
|
|
110
136
|
const state = this.accumulator.getState();
|
|
111
137
|
return this._trackFn({
|
|
112
|
-
|
|
138
|
+
...contextFields(overrides),
|
|
113
139
|
modelName: this._modelName,
|
|
114
140
|
provider: this._providerName,
|
|
115
141
|
responseContent: state.content,
|
|
@@ -123,19 +149,11 @@ var SimpleStreamingTracker = class {
|
|
|
123
149
|
finishReason: state.finishReason,
|
|
124
150
|
toolCalls: state.toolCalls.length > 0 ? state.toolCalls : null,
|
|
125
151
|
providerTtfbMs: state.ttfbMs,
|
|
126
|
-
isStreaming: true
|
|
127
|
-
sessionId: overrides.sessionId,
|
|
128
|
-
traceId: overrides.traceId,
|
|
129
|
-
turnId: overrides.turnId ?? void 0,
|
|
130
|
-
agentId: overrides.agentId,
|
|
131
|
-
parentAgentId: overrides.parentAgentId,
|
|
132
|
-
customerOrgId: overrides.customerOrgId,
|
|
133
|
-
env: overrides.env,
|
|
134
|
-
groups: overrides.groups
|
|
152
|
+
isStreaming: true
|
|
135
153
|
});
|
|
136
154
|
}
|
|
137
155
|
};
|
|
138
156
|
|
|
139
157
|
//#endregion
|
|
140
|
-
export { BaseAIProvider, SimpleStreamingTracker, applySessionContext };
|
|
158
|
+
export { BaseAIProvider, SimpleStreamingTracker, applySessionContext, contextFields };
|
|
141
159
|
//# sourceMappingURL=base.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":["result: Record<string, unknown>"],"sources":["../../src/providers/base.ts"],"sourcesContent":["/**\n * Base class for AI provider wrappers.\n *\n * Provides shared tracking logic and session context integration.\n */\n\nimport { getActiveContext } from '../context.js';\nimport {\n PROP_IDLE_TIMEOUT_MINUTES,\n PROP_SESSION_REPLAY_ID,\n} from '../core/constants.js';\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport {\n trackAiMessage,\n type TrackAiMessageOptions,\n} from '../core/tracking.js';\nimport {\n resolveAmplitude,\n type AmplitudeLike,\n type AmplitudeOrAI,\n type TrackCallOptions,\n type TrackFn,\n} from '../types.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\n\n/**\n * Per-call context overrides for provider wrappers.\n *\n * Pass as the second argument to wrapped provider methods\n * (e.g., `openai.chat.completions.create(params, overrides)`)\n * to set Amplitude tracking context for that specific call.\n * Any fields left `null`/`undefined` are filled from the\n * active `SessionContext` via `AsyncLocalStorage`.\n */\nexport interface ProviderTrackOptions {\n userId?: string | null;\n sessionId?: string | null;\n traceId?: string | null;\n turnId?: number | null;\n agentId?: string | null;\n parentAgentId?: string | null;\n customerOrgId?: string | null;\n env?: string | null;\n groups?: Record<string, unknown> | null;\n eventProperties?: Record<string, unknown> | null;\n /**\n * Controls whether provider wrappers auto-track user input payloads.\n * Set to false when you already call `trackUserMessage()` explicitly.\n */\n trackInputMessages?: boolean;\n}\n\n/**\n * Apply session context fields from AsyncLocalStorage to tracking options.\n * Returns a merged set of fields with explicit values taking precedence.\n * Also injects idle_timeout_minutes and session_replay_id from the context.\n */\nexport function applySessionContext(\n overrides: ProviderTrackOptions = {},\n): ProviderTrackOptions & { userId: string } {\n const ctx = getActiveContext();\n const result: Record<string, unknown> = { ...overrides };\n\n if (ctx != null) {\n if (!result.userId) result.userId = ctx.userId;\n if (!result.sessionId) result.sessionId = ctx.sessionId;\n if (!result.traceId) result.traceId = ctx.traceId;\n if (!result.agentId) result.agentId = ctx.agentId;\n if (!result.parentAgentId) result.parentAgentId = ctx.parentAgentId;\n if (!result.customerOrgId) result.customerOrgId = ctx.customerOrgId;\n if (!result.env) result.env = ctx.env;\n if (!result.groups) result.groups = ctx.groups;\n\n const turnId = ctx.nextTurnId();\n if (turnId != null && result.turnId == null) result.turnId = turnId;\n\n const existingEp = result.eventProperties as Record<string, unknown> | null;\n const ep = existingEp != null ? { ...existingEp } : {};\n if (ctx.idleTimeoutMinutes != null && !(PROP_IDLE_TIMEOUT_MINUTES in ep)) {\n ep[PROP_IDLE_TIMEOUT_MINUTES] = ctx.idleTimeoutMinutes;\n }\n if (\n ctx.deviceId &&\n ctx.browserSessionId &&\n !(PROP_SESSION_REPLAY_ID in ep)\n ) {\n ep[PROP_SESSION_REPLAY_ID] = `${ctx.deviceId}/${ctx.browserSessionId}`;\n }\n if (Object.keys(ep).length > 0) {\n result.eventProperties = ep;\n }\n }\n\n return result as unknown as ProviderTrackOptions & { userId: string };\n}\n\nexport abstract class BaseAIProvider {\n protected _amplitude: AmplitudeLike;\n protected _privacyConfig: PrivacyConfig | null;\n readonly _providerName: string;\n\n constructor(options: {\n amplitude: AmplitudeOrAI;\n privacyConfig?: PrivacyConfig | null;\n providerName: string;\n }) {\n this._amplitude = resolveAmplitude(options.amplitude);\n this._privacyConfig = options.privacyConfig ?? null;\n this._providerName = options.providerName;\n }\n\n protected _track(opts: Omit<TrackAiMessageOptions, 'amplitude'>): string {\n const merged = applySessionContext({\n userId: opts.userId,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: opts.turnId,\n agentId: opts.agentId,\n parentAgentId: opts.parentAgentId,\n customerOrgId: opts.customerOrgId,\n env: opts.env,\n groups: opts.groups,\n });\n\n return trackAiMessage({\n ...opts,\n amplitude: this._amplitude,\n userId: merged.userId ?? opts.userId,\n sessionId: merged.sessionId ?? opts.sessionId,\n traceId: merged.traceId ?? opts.traceId,\n turnId: merged.turnId ?? opts.turnId,\n agentId: merged.agentId ?? opts.agentId,\n parentAgentId: merged.parentAgentId ?? opts.parentAgentId,\n customerOrgId: merged.customerOrgId ?? opts.customerOrgId,\n env: merged.env ?? opts.env,\n groups: merged.groups ?? opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackFn(): TrackFn {\n return (opts: TrackCallOptions) =>\n this._track(opts as Omit<TrackAiMessageOptions, 'amplitude'>);\n }\n\n createStreamingTracker(): SimpleStreamingTracker {\n return new SimpleStreamingTracker(this);\n }\n}\n\nexport class SimpleStreamingTracker {\n private _trackFn: TrackFn;\n readonly accumulator: StreamingAccumulator;\n private _modelName = 'unknown';\n private _providerName: string;\n\n constructor(provider: BaseAIProvider) {\n this._trackFn = provider.trackFn();\n this._providerName = provider._providerName;\n this.accumulator = new StreamingAccumulator();\n }\n\n setModel(model: string): void {\n this._modelName = model;\n this.accumulator.model = model;\n }\n\n addContent(chunk: string): void {\n this.accumulator.addContent(chunk);\n }\n\n setUsage(usage: Parameters<StreamingAccumulator['setUsage']>[0]): void {\n this.accumulator.setUsage(usage);\n }\n\n setFinishReason(reason: string): void {\n this.accumulator.finishReason = reason;\n }\n\n addToolCall(toolCall: Record<string, unknown>): void {\n this.accumulator.addToolCall(toolCall);\n }\n\n finalize(overrides: ProviderTrackOptions = {}): string {\n const state = this.accumulator.getState();\n\n return this._trackFn({\n userId: overrides.userId ?? 'unknown',\n modelName: this._modelName,\n provider: this._providerName,\n responseContent: state.content,\n latencyMs: this.accumulator.elapsedMs,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n reasoningTokens: state.reasoningTokens,\n cacheReadInputTokens: state.cacheReadTokens,\n cacheCreationInputTokens: state.cacheCreationTokens,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : null,\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n sessionId: overrides.sessionId,\n traceId: overrides.traceId,\n turnId: overrides.turnId ?? undefined,\n agentId: overrides.agentId,\n parentAgentId: overrides.parentAgentId,\n customerOrgId: overrides.customerOrgId,\n env: overrides.env,\n groups: overrides.groups,\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","names":["result: Record<string, unknown>"],"sources":["../../src/providers/base.ts"],"sourcesContent":["/**\n * Base class for AI provider wrappers.\n *\n * Provides shared tracking logic and session context integration.\n */\n\nimport { getActiveContext } from '../context.js';\nimport {\n PROP_IDLE_TIMEOUT_MINUTES,\n PROP_SESSION_REPLAY_ID,\n} from '../core/constants.js';\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport {\n trackAiMessage,\n type TrackAiMessageOptions,\n} from '../core/tracking.js';\nimport {\n resolveAmplitude,\n type AmplitudeLike,\n type AmplitudeOrAI,\n type TrackCallOptions,\n type TrackFn,\n} from '../types.js';\nimport { StreamingAccumulator } from '../utils/streaming.js';\n\n/**\n * Per-call context overrides for provider wrappers.\n *\n * Pass as the second argument to wrapped provider methods\n * (e.g., `openai.chat.completions.create(params, overrides)`)\n * to set Amplitude tracking context for that specific call.\n * Any fields left `null`/`undefined` are filled from the\n * active `SessionContext` via `AsyncLocalStorage`.\n */\nexport interface ProviderTrackOptions {\n userId?: string | null;\n sessionId?: string | null;\n traceId?: string | null;\n turnId?: number | null;\n agentId?: string | null;\n parentAgentId?: string | null;\n customerOrgId?: string | null;\n agentVersion?: string | null;\n context?: Record<string, unknown> | null;\n env?: string | null;\n groups?: Record<string, unknown> | null;\n eventProperties?: Record<string, unknown> | null;\n /**\n * Controls whether provider wrappers auto-track user input payloads.\n * Set to false when you already call `trackUserMessage()` explicitly.\n */\n trackInputMessages?: boolean;\n}\n\n/**\n * Apply session context fields from AsyncLocalStorage to tracking options.\n * Returns a merged set of fields with explicit values taking precedence.\n * Also injects idle_timeout_minutes and session_replay_id from the context.\n */\nexport function applySessionContext(\n overrides: ProviderTrackOptions = {},\n): ProviderTrackOptions & { userId: string } {\n const ctx = getActiveContext();\n const result: Record<string, unknown> = { ...overrides };\n\n if (ctx != null) {\n if (!result.userId) result.userId = ctx.userId;\n if (!result.sessionId) result.sessionId = ctx.sessionId;\n if (!result.traceId) result.traceId = ctx.traceId;\n if (!result.agentId) result.agentId = ctx.agentId;\n if (!result.parentAgentId) result.parentAgentId = ctx.parentAgentId;\n if (!result.customerOrgId) result.customerOrgId = ctx.customerOrgId;\n if (!result.agentVersion) result.agentVersion = ctx.agentVersion;\n if (!result.context) result.context = ctx.context;\n if (!result.env) result.env = ctx.env;\n if (!result.groups) result.groups = ctx.groups;\n\n if (result.turnId == null) {\n const turnId = ctx.nextTurnId();\n if (turnId != null) result.turnId = turnId;\n }\n\n const existingEp = result.eventProperties as Record<string, unknown> | null;\n const ep = existingEp != null ? { ...existingEp } : {};\n if (ctx.idleTimeoutMinutes != null && !(PROP_IDLE_TIMEOUT_MINUTES in ep)) {\n ep[PROP_IDLE_TIMEOUT_MINUTES] = ctx.idleTimeoutMinutes;\n }\n if (\n ctx.deviceId &&\n ctx.browserSessionId &&\n !(PROP_SESSION_REPLAY_ID in ep)\n ) {\n ep[PROP_SESSION_REPLAY_ID] = `${ctx.deviceId}/${ctx.browserSessionId}`;\n }\n if (Object.keys(ep).length > 0) {\n result.eventProperties = ep;\n }\n }\n\n return result as unknown as ProviderTrackOptions & { userId: string };\n}\n\n/**\n * Extract all context fields from a resolved ProviderTrackOptions into a\n * flat object suitable for spreading into _trackFn() / _track() calls.\n * Ensures all 13 context fields propagate consistently.\n */\nexport type TrackContextFields = Pick<\n TrackCallOptions,\n | 'userId'\n | 'sessionId'\n | 'traceId'\n | 'turnId'\n | 'agentId'\n | 'parentAgentId'\n | 'customerOrgId'\n | 'agentVersion'\n | 'context'\n | 'env'\n | 'groups'\n | 'eventProperties'\n>;\n\nexport function contextFields(ctx: ProviderTrackOptions): TrackContextFields {\n return {\n userId: ctx.userId ?? 'unknown',\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n turnId: ctx.turnId ?? undefined,\n agentId: ctx.agentId,\n parentAgentId: ctx.parentAgentId,\n customerOrgId: ctx.customerOrgId,\n agentVersion: ctx.agentVersion,\n context: ctx.context,\n env: ctx.env,\n groups: ctx.groups,\n eventProperties: ctx.eventProperties,\n };\n}\n\nexport abstract class BaseAIProvider {\n protected _amplitude: AmplitudeLike;\n protected _privacyConfig: PrivacyConfig | null;\n readonly _providerName: string;\n\n constructor(options: {\n amplitude: AmplitudeOrAI;\n privacyConfig?: PrivacyConfig | null;\n providerName: string;\n }) {\n this._amplitude = resolveAmplitude(options.amplitude);\n this._privacyConfig = options.privacyConfig ?? null;\n this._providerName = options.providerName;\n }\n\n protected _track(opts: Omit<TrackAiMessageOptions, 'amplitude'>): string {\n const merged = applySessionContext({\n userId: opts.userId,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: opts.turnId,\n agentId: opts.agentId,\n parentAgentId: opts.parentAgentId,\n customerOrgId: opts.customerOrgId,\n agentVersion: opts.agentVersion,\n context: opts.context,\n env: opts.env,\n groups: opts.groups,\n eventProperties: opts.eventProperties,\n });\n\n return trackAiMessage({\n ...opts,\n amplitude: this._amplitude,\n userId: merged.userId ?? opts.userId,\n sessionId: merged.sessionId ?? opts.sessionId,\n traceId: merged.traceId ?? opts.traceId,\n turnId: merged.turnId ?? opts.turnId,\n agentId: merged.agentId ?? opts.agentId,\n parentAgentId: merged.parentAgentId ?? opts.parentAgentId,\n customerOrgId: merged.customerOrgId ?? opts.customerOrgId,\n agentVersion: merged.agentVersion ?? opts.agentVersion,\n context: merged.context ?? opts.context,\n env: merged.env ?? opts.env,\n groups: merged.groups ?? opts.groups,\n eventProperties: merged.eventProperties ?? opts.eventProperties,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackFn(): TrackFn {\n return (opts: TrackCallOptions) =>\n this._track(opts as Omit<TrackAiMessageOptions, 'amplitude'>);\n }\n\n createStreamingTracker(): SimpleStreamingTracker {\n return new SimpleStreamingTracker(this);\n }\n}\n\nexport class SimpleStreamingTracker {\n private _trackFn: TrackFn;\n readonly accumulator: StreamingAccumulator;\n private _modelName = 'unknown';\n private _providerName: string;\n\n constructor(provider: BaseAIProvider) {\n this._trackFn = provider.trackFn();\n this._providerName = provider._providerName;\n this.accumulator = new StreamingAccumulator();\n }\n\n setModel(model: string): void {\n this._modelName = model;\n this.accumulator.model = model;\n }\n\n addContent(chunk: string): void {\n this.accumulator.addContent(chunk);\n }\n\n setUsage(usage: Parameters<StreamingAccumulator['setUsage']>[0]): void {\n this.accumulator.setUsage(usage);\n }\n\n setFinishReason(reason: string): void {\n this.accumulator.finishReason = reason;\n }\n\n addToolCall(toolCall: Record<string, unknown>): void {\n this.accumulator.addToolCall(toolCall);\n }\n\n finalize(overrides: ProviderTrackOptions = {}): string {\n const state = this.accumulator.getState();\n\n return this._trackFn({\n ...contextFields(overrides),\n modelName: this._modelName,\n provider: this._providerName,\n responseContent: state.content,\n latencyMs: this.accumulator.elapsedMs,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n reasoningTokens: state.reasoningTokens,\n cacheReadInputTokens: state.cacheReadTokens,\n cacheCreationInputTokens: state.cacheCreationTokens,\n finishReason: state.finishReason,\n toolCalls: state.toolCalls.length > 0 ? state.toolCalls : null,\n providerTtfbMs: state.ttfbMs,\n isStreaming: true,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock.d.ts","names":[],"sources":["../../src/providers/bedrock.ts"],"sourcesContent":[],"mappings":";;;;;;AA2Ba,cAbA,iBAaQ,EAAA,OAAA;cAZf,cAgBiB,EAhBD,MAgBC,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;AAY4B,UAxBlC,cAAA,CAwBkC;
|
|
1
|
+
{"version":3,"file":"bedrock.d.ts","names":[],"sources":["../../src/providers/bedrock.ts"],"sourcesContent":[],"mappings":";;;;;;AA2Ba,cAbA,iBAaQ,EAAA,OAAA;cAZf,cAgBiB,EAhBD,MAgBC,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;AAY4B,UAxBlC,cAAA,CAwBkC;EAgFpB,SAAA,EAvGlB,aAuGkB;EAA0B,MAAA,EAAA,OAAA;EAhG5B,aAAA,CAAA,EALX,aAKW,GAAA,IAAA;EAAc;EAmQ3B,aAAA,CAAA,EAAA,OAAA;;cAnQH,OAAA,SAAgB,cAAA;;;uBAIN;mBAYE,0BAA0B;yBAgFpB,0BAA0B;;;;iBAmKzC,sBAAA;;;;;;;;aAQH,MAAM"}
|
|
@@ -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");
|
|
@@ -37,21 +37,17 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
37
37
|
inputTokens: extracted.inputTokens,
|
|
38
38
|
outputTokens: extracted.outputTokens,
|
|
39
39
|
cacheReadInputTokens: extracted.cacheReadTokens ?? 0,
|
|
40
|
-
cacheCreationInputTokens: extracted.cacheWriteTokens ?? 0
|
|
40
|
+
cacheCreationInputTokens: extracted.cacheWriteTokens ?? 0,
|
|
41
|
+
defaultProvider: "bedrock"
|
|
41
42
|
});
|
|
42
43
|
} catch {}
|
|
43
44
|
const ctx = applySessionContext();
|
|
44
45
|
this._track({
|
|
45
|
-
|
|
46
|
+
...contextFields(ctx),
|
|
46
47
|
modelName: modelId,
|
|
47
48
|
provider: "bedrock",
|
|
48
49
|
responseContent: extracted.text,
|
|
49
50
|
latencyMs,
|
|
50
|
-
sessionId: ctx.sessionId,
|
|
51
|
-
traceId: ctx.traceId,
|
|
52
|
-
turnId: ctx.turnId ?? void 0,
|
|
53
|
-
agentId: ctx.agentId,
|
|
54
|
-
env: ctx.env,
|
|
55
51
|
inputTokens: extracted.inputTokens,
|
|
56
52
|
outputTokens: extracted.outputTokens,
|
|
57
53
|
totalTokens: extracted.totalTokens,
|
|
@@ -69,15 +65,11 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
69
65
|
const latencyMs = performance.now() - startTime;
|
|
70
66
|
const ctx = applySessionContext();
|
|
71
67
|
this._track({
|
|
72
|
-
|
|
68
|
+
...contextFields(ctx),
|
|
73
69
|
modelName: modelId,
|
|
74
70
|
provider: "bedrock",
|
|
75
71
|
responseContent: "",
|
|
76
72
|
latencyMs,
|
|
77
|
-
sessionId: ctx.sessionId,
|
|
78
|
-
traceId: ctx.traceId,
|
|
79
|
-
agentId: ctx.agentId,
|
|
80
|
-
env: ctx.env,
|
|
81
73
|
isError: true,
|
|
82
74
|
errorMessage: error instanceof Error ? error.message : String(error)
|
|
83
75
|
});
|
|
@@ -99,19 +91,15 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
99
91
|
if (!_isAsyncIterable(stream)) throw new Error("Bedrock stream response is not AsyncIterable");
|
|
100
92
|
return {
|
|
101
93
|
...response,
|
|
102
|
-
stream: this._wrapConverseStream(modelId, params, stream)
|
|
94
|
+
stream: this._wrapConverseStream(modelId, params, stream, ctx)
|
|
103
95
|
};
|
|
104
96
|
} catch (error) {
|
|
105
97
|
this._track({
|
|
106
|
-
|
|
98
|
+
...contextFields(ctx),
|
|
107
99
|
modelName: modelId,
|
|
108
100
|
provider: "bedrock",
|
|
109
101
|
responseContent: "",
|
|
110
102
|
latencyMs: performance.now() - startTime,
|
|
111
|
-
sessionId: ctx.sessionId,
|
|
112
|
-
traceId: ctx.traceId,
|
|
113
|
-
agentId: ctx.agentId,
|
|
114
|
-
env: ctx.env,
|
|
115
103
|
isError: true,
|
|
116
104
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
117
105
|
isStreaming: true
|
|
@@ -122,10 +110,9 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
122
110
|
get client() {
|
|
123
111
|
return this._client;
|
|
124
112
|
}
|
|
125
|
-
async *_wrapConverseStream(modelId, params, stream) {
|
|
113
|
+
async *_wrapConverseStream(modelId, params, stream, ctx) {
|
|
126
114
|
const accumulator = new StreamingAccumulator();
|
|
127
115
|
accumulator.model = modelId;
|
|
128
|
-
const ctx = applySessionContext();
|
|
129
116
|
try {
|
|
130
117
|
for await (const rawEvent of stream) {
|
|
131
118
|
const event = rawEvent;
|
|
@@ -141,7 +128,9 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
141
128
|
accumulator.setUsage({
|
|
142
129
|
inputTokens: usage?.inputTokens,
|
|
143
130
|
outputTokens: usage?.outputTokens,
|
|
144
|
-
totalTokens: usage?.totalTokens
|
|
131
|
+
totalTokens: usage?.totalTokens,
|
|
132
|
+
cacheReadTokens: usage?.cacheReadInputTokens,
|
|
133
|
+
cacheCreationTokens: usage?.cacheWriteInputTokens
|
|
145
134
|
});
|
|
146
135
|
yield rawEvent;
|
|
147
136
|
}
|
|
@@ -156,20 +145,18 @@ var Bedrock = class extends BaseAIProvider {
|
|
|
156
145
|
costUsd = calculateCost({
|
|
157
146
|
modelName,
|
|
158
147
|
inputTokens: state.inputTokens,
|
|
159
|
-
outputTokens: state.outputTokens
|
|
148
|
+
outputTokens: state.outputTokens,
|
|
149
|
+
cacheReadInputTokens: state.cacheReadTokens ?? 0,
|
|
150
|
+
cacheCreationInputTokens: state.cacheCreationTokens ?? 0,
|
|
151
|
+
defaultProvider: "bedrock"
|
|
160
152
|
});
|
|
161
153
|
} catch {}
|
|
162
154
|
this._track({
|
|
163
|
-
|
|
155
|
+
...contextFields(ctx),
|
|
164
156
|
modelName,
|
|
165
157
|
provider: "bedrock",
|
|
166
158
|
responseContent: state.content,
|
|
167
159
|
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
160
|
inputTokens: state.inputTokens,
|
|
174
161
|
outputTokens: state.outputTokens,
|
|
175
162
|
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 defaultProvider: 'bedrock',\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 defaultProvider: 'bedrock',\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;EA0EO,aAAA,CAAA,EA1GM,aA0GN,GAAA,IAAA;EACP;EAtGuB,YAAA,CAAA,EAAA,OAAA;;AA0PZ,cA1PH,MAAA,SAAe,cAAA,CAgQV;;uBA7PK;yCAuBX,0BACP;+CA0EO,0BACP;;;;iBAoJW,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");
|
|
@@ -33,21 +33,17 @@ var Gemini = class extends BaseAIProvider {
|
|
|
33
33
|
costUsd = calculateCost({
|
|
34
34
|
modelName: model,
|
|
35
35
|
inputTokens: extracted.inputTokens,
|
|
36
|
-
outputTokens: extracted.outputTokens
|
|
36
|
+
outputTokens: extracted.outputTokens,
|
|
37
|
+
defaultProvider: "google"
|
|
37
38
|
});
|
|
38
39
|
} catch {}
|
|
39
40
|
const ctx = applySessionContext();
|
|
40
41
|
this._track({
|
|
41
|
-
|
|
42
|
+
...contextFields(ctx),
|
|
42
43
|
modelName: model,
|
|
43
44
|
provider: "gemini",
|
|
44
45
|
responseContent: extracted.text,
|
|
45
46
|
latencyMs,
|
|
46
|
-
sessionId: ctx.sessionId,
|
|
47
|
-
traceId: ctx.traceId,
|
|
48
|
-
turnId: ctx.turnId ?? void 0,
|
|
49
|
-
agentId: ctx.agentId,
|
|
50
|
-
env: ctx.env,
|
|
51
47
|
inputTokens: extracted.inputTokens,
|
|
52
48
|
outputTokens: extracted.outputTokens,
|
|
53
49
|
totalTokens: extracted.totalTokens,
|
|
@@ -65,15 +61,11 @@ var Gemini = class extends BaseAIProvider {
|
|
|
65
61
|
const latencyMs = performance.now() - startTime;
|
|
66
62
|
const ctx = applySessionContext();
|
|
67
63
|
this._track({
|
|
68
|
-
|
|
64
|
+
...contextFields(ctx),
|
|
69
65
|
modelName: model,
|
|
70
66
|
provider: "gemini",
|
|
71
67
|
responseContent: "",
|
|
72
68
|
latencyMs,
|
|
73
|
-
sessionId: ctx.sessionId,
|
|
74
|
-
traceId: ctx.traceId,
|
|
75
|
-
agentId: ctx.agentId,
|
|
76
|
-
env: ctx.env,
|
|
77
69
|
isError: true,
|
|
78
70
|
errorMessage: error instanceof Error ? error.message : String(error)
|
|
79
71
|
});
|
|
@@ -93,19 +85,15 @@ var Gemini = class extends BaseAIProvider {
|
|
|
93
85
|
if (!_isAsyncIterable(stream)) throw new Error("Gemini stream response is not AsyncIterable");
|
|
94
86
|
return {
|
|
95
87
|
...streamResponse,
|
|
96
|
-
stream: this._wrapStream(model, params, stream, finalResponse)
|
|
88
|
+
stream: this._wrapStream(model, params, stream, finalResponse, ctx)
|
|
97
89
|
};
|
|
98
90
|
} catch (error) {
|
|
99
91
|
this._track({
|
|
100
|
-
|
|
92
|
+
...contextFields(ctx),
|
|
101
93
|
modelName: model,
|
|
102
94
|
provider: "gemini",
|
|
103
95
|
responseContent: "",
|
|
104
96
|
latencyMs: performance.now() - startTime,
|
|
105
|
-
sessionId: ctx.sessionId,
|
|
106
|
-
traceId: ctx.traceId,
|
|
107
|
-
agentId: ctx.agentId,
|
|
108
|
-
env: ctx.env,
|
|
109
97
|
isError: true,
|
|
110
98
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
111
99
|
isStreaming: true
|
|
@@ -116,9 +104,8 @@ var Gemini = class extends BaseAIProvider {
|
|
|
116
104
|
get client() {
|
|
117
105
|
return this._client;
|
|
118
106
|
}
|
|
119
|
-
async *_wrapStream(model, params, stream, finalResponse) {
|
|
107
|
+
async *_wrapStream(model, params, stream, finalResponse, ctx) {
|
|
120
108
|
const accumulator = new StreamingAccumulator();
|
|
121
|
-
const ctx = applySessionContext();
|
|
122
109
|
try {
|
|
123
110
|
for await (const chunk of stream) {
|
|
124
111
|
const extracted = extractGeminiResponse(chunk);
|
|
@@ -144,7 +131,7 @@ var Gemini = class extends BaseAIProvider {
|
|
|
144
131
|
totalTokens: extractedFinal.totalTokens
|
|
145
132
|
});
|
|
146
133
|
if (extractedFinal.finishReason != null) accumulator.finishReason = String(extractedFinal.finishReason);
|
|
147
|
-
if (Array.isArray(extractedFinal.functionCalls)) for (const fc of extractedFinal.functionCalls) accumulator.addToolCall(fc);
|
|
134
|
+
if (Array.isArray(extractedFinal.functionCalls) && accumulator.toolCalls.length === 0) for (const fc of extractedFinal.functionCalls) accumulator.addToolCall(fc);
|
|
148
135
|
} catch {}
|
|
149
136
|
const state = accumulator.getState();
|
|
150
137
|
let costUsd = null;
|
|
@@ -152,20 +139,16 @@ var Gemini = class extends BaseAIProvider {
|
|
|
152
139
|
costUsd = calculateCost({
|
|
153
140
|
modelName: model,
|
|
154
141
|
inputTokens: state.inputTokens,
|
|
155
|
-
outputTokens: state.outputTokens
|
|
142
|
+
outputTokens: state.outputTokens,
|
|
143
|
+
defaultProvider: "google"
|
|
156
144
|
});
|
|
157
145
|
} catch {}
|
|
158
146
|
this._track({
|
|
159
|
-
|
|
147
|
+
...contextFields(ctx),
|
|
160
148
|
modelName: model,
|
|
161
149
|
provider: "gemini",
|
|
162
150
|
responseContent: state.content,
|
|
163
151
|
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
152
|
inputTokens: state.inputTokens,
|
|
170
153
|
outputTokens: state.outputTokens,
|
|
171
154
|
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 defaultProvider: 'google',\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 defaultProvider: 'google',\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,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;
|
|
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;EAmF5B,QAAA,OAAA;EAA0B,SAAA,IAAA,EAjIhC,WAiIgC;EAAO,WAAA,CAAA,OAAA,EA/HjC,cA+HiC;;;cA/F3C,WAAA;;;wCAI2B;mBAQf,0BAA0B;iBAmF5B,0BAA0B"}
|