@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/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# AGENTS.md
|
|
4
4
|
|
|
5
|
-
Package: `@amplitude/ai` v0.
|
|
5
|
+
Package: `@amplitude/ai` v0.2.0
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -13,6 +13,7 @@ Package: `@amplitude/ai` v0.1.1
|
|
|
13
13
|
- Need zero-code coverage: use `patch()`.
|
|
14
14
|
- Already have a provider client: use `wrap()` or provider wrappers.
|
|
15
15
|
- Need user/session lineage: use `ai.agent(...).session(...)`.
|
|
16
|
+
- Multiple agents collaborating: use `session.runAs(childAgent, fn)` for automatic identity propagation.
|
|
16
17
|
- Need tool telemetry: use `tool()`.
|
|
17
18
|
- Need agent-assistant guidance: run MCP prompt `instrument_app`.
|
|
18
19
|
|
|
@@ -21,6 +22,7 @@ Package: `@amplitude/ai` v0.1.1
|
|
|
21
22
|
- zero-code patching
|
|
22
23
|
- wrap-openai
|
|
23
24
|
- bound-agent-session
|
|
25
|
+
- multi-agent-runas
|
|
24
26
|
- tool-decorator
|
|
25
27
|
- express-middleware
|
|
26
28
|
|
package/README.md
CHANGED
|
@@ -715,6 +715,15 @@ s.trackAiMessage(response.content, 'gpt-4o', 'openai', latencyMs, {
|
|
|
715
715
|
});
|
|
716
716
|
```
|
|
717
717
|
|
|
718
|
+
> **Note — pricing data freshness.** Cost calculation relies on pricing data bundled in the installed `@pydantic/genai-prices` package. Newly released models may return `$0` until the package is updated. To get the latest pricing between package releases, opt in to live updates at startup:
|
|
719
|
+
>
|
|
720
|
+
> ```typescript
|
|
721
|
+
> import { enableLivePriceUpdates } from '@amplitude/ai';
|
|
722
|
+
> enableLivePriceUpdates(); // fetches latest prices from genai-prices GitHub repo hourly
|
|
723
|
+
> ```
|
|
724
|
+
>
|
|
725
|
+
> This makes periodic HTTPS requests to `raw.githubusercontent.com` (~26 KB each). Only enable in environments where outbound network access is permitted.
|
|
726
|
+
|
|
718
727
|
## Semantic Cache Tracking
|
|
719
728
|
|
|
720
729
|
Track full-response semantic cache hits (distinct from token-level prompt caching above):
|
|
@@ -1693,45 +1702,65 @@ await session.run(async (s) => {
|
|
|
1693
1702
|
|
|
1694
1703
|
### Pattern C: Multi-Agent Orchestration
|
|
1695
1704
|
|
|
1696
|
-
For architectures where a parent agent delegates to specialized child agents.
|
|
1705
|
+
For architectures where a parent agent delegates to specialized child agents. Use `session.runAs()` to automatically propagate the child agent's identity to **both** manual tracking calls and provider wrappers:
|
|
1697
1706
|
|
|
1698
1707
|
```typescript
|
|
1699
1708
|
const ai = new AmplitudeAI({ apiKey: process.env.AMPLITUDE_AI_API_KEY! });
|
|
1709
|
+
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY!, amplitude: ai });
|
|
1710
|
+
|
|
1700
1711
|
const orchestrator = ai.agent('orchestrator', {
|
|
1701
1712
|
userId: 'user-123',
|
|
1702
1713
|
env: 'production',
|
|
1703
1714
|
});
|
|
1704
|
-
|
|
1705
1715
|
const researcher = orchestrator.child('researcher');
|
|
1706
1716
|
const writer = orchestrator.child('writer');
|
|
1707
|
-
const reviewer = orchestrator.child('reviewer');
|
|
1708
1717
|
|
|
1709
1718
|
const session = orchestrator.session({ userId: 'user-123' });
|
|
1710
1719
|
|
|
1711
1720
|
await session.run(async (s) => {
|
|
1712
1721
|
s.trackUserMessage('Write a blog post about TypeScript generics');
|
|
1713
1722
|
|
|
1714
|
-
// Research phase
|
|
1715
|
-
const researchResult = await
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1723
|
+
// Research phase — provider calls automatically tagged with agentId='researcher'
|
|
1724
|
+
const researchResult = await s.runAs(researcher, async (rs) => {
|
|
1725
|
+
const completion = await openai.chat.completions.create({
|
|
1726
|
+
model: 'gpt-4o',
|
|
1727
|
+
messages: [{ role: 'user', content: 'Research TypeScript generics' }],
|
|
1728
|
+
});
|
|
1729
|
+
return completion.choices[0].message.content;
|
|
1730
|
+
});
|
|
1719
1731
|
|
|
1720
|
-
//
|
|
1721
|
-
const
|
|
1732
|
+
// Writing phase — provider calls automatically tagged with agentId='writer'
|
|
1733
|
+
const draft = await s.runAs(writer, async (ws) => {
|
|
1734
|
+
const completion = await openai.chat.completions.create({
|
|
1735
|
+
model: 'gpt-4o',
|
|
1736
|
+
messages: [{ role: 'user', content: `Write a post using: ${researchResult}` }],
|
|
1737
|
+
});
|
|
1738
|
+
return completion.choices[0].message.content;
|
|
1739
|
+
});
|
|
1722
1740
|
|
|
1723
|
-
s.trackAiMessage(
|
|
1741
|
+
s.trackAiMessage(draft ?? '', 'gpt-4o', 'openai', totalLatencyMs, {
|
|
1724
1742
|
inputTokens: totalInput,
|
|
1725
1743
|
outputTokens: totalOutput,
|
|
1726
1744
|
});
|
|
1727
1745
|
});
|
|
1728
1746
|
|
|
1729
|
-
//
|
|
1730
|
-
//
|
|
1731
|
-
//
|
|
1732
|
-
//
|
|
1747
|
+
// Events emitted:
|
|
1748
|
+
// [Agent] User Message → agentId='orchestrator'
|
|
1749
|
+
// [Agent] AI Response → agentId='researcher', parentAgentId='orchestrator'
|
|
1750
|
+
// [Agent] AI Response → agentId='writer', parentAgentId='orchestrator'
|
|
1751
|
+
// [Agent] AI Response → agentId='orchestrator'
|
|
1752
|
+
// [Agent] Session End → agentId='orchestrator' (one session end, not per-child)
|
|
1733
1753
|
```
|
|
1734
1754
|
|
|
1755
|
+
**How `runAs` works:**
|
|
1756
|
+
|
|
1757
|
+
- Shares the parent session's `sessionId`, `traceId`, and turn counter
|
|
1758
|
+
- Overrides `agentId` and `parentAgentId` in `AsyncLocalStorage` for the callback's duration
|
|
1759
|
+
- Provider wrappers automatically read the child's identity — no `amplitudeOverrides` needed
|
|
1760
|
+
- Does **not** emit `[Agent] Session End` (the child operates within the parent session)
|
|
1761
|
+
- Restores the parent context when the callback completes, even on errors
|
|
1762
|
+
- Supports nesting: `s.runAs(child, (cs) => cs.runAs(grandchild, ...))`
|
|
1763
|
+
|
|
1735
1764
|
## Serverless Environments
|
|
1736
1765
|
|
|
1737
1766
|
**Critical**: Always `await ai.flush()` before your handler returns. Without this, events buffered in memory are lost when the runtime freezes or terminates:
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AA+CA;;;;;;;;;;;;;;;;AAsMkB,cAtML,WAAA,CAsMK;EACL,UAAA,UAAA,EAtMW,mBAsMX;EAQC,UAAA,WAAA,EAAA,OAAA;EAKQ,UAAA,OAAA,EAjND,QAiNC;EACT,UAAA,cAAA,EAjNe,aAiNf;EACO,UAAA,oBAAA,EAjNc,GAiNd,CAAA,MAAA,EAAA,MAAA,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AA+CA;;;;;;;;;;;;;;;;AAsMkB,cAtML,WAAA,CAsMK;EACL,UAAA,UAAA,EAtMW,mBAsMX;EAQC,UAAA,WAAA,EAAA,OAAA;EAKQ,UAAA,OAAA,EAjND,QAiNC;EACT,UAAA,cAAA,EAjNe,aAiNf;EACO,UAAA,oBAAA,EAjNc,GAiNd,CAAA,MAAA,EAAA,MAAA,CAAA;EA4FN,WAAA,CAAA,OAAA,EAAA;IAGQ,SAAA,CAAA,EA7SN,mBA6SM;IACT,MAAA,CAAA,EAAA,MAAA;IA2CC,MAAA,CAAA,EAvVD,QAuVC;EAEQ,CAAA;EACT,QAAA,iBAAA;EA+BI,IAAA,SAAA,CAAA,CAAA,EAjSE,mBAiSF;EACC,IAAA,MAAA,CAAA,CAAA,EA9RF,QA8RE;EAUJ,WAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAAA,MAAA;EAEQ,gBAAA,CAAA,IAAA,EAAA;IACT,MAAA,EAAA,MAAA;IAkCK,OAAA,EAAA,MAAA;IAOJ,SAAA,EAAA,MAAA;IAIQ,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IACT,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IA2BI,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IAOH,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IAEQ,aAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IACT,aAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IAwCC,YAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IAEQ,OAAA,CAAA,EAtYR,MAsYQ,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;IACT,GAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IAqCG,cAAA,CAAA,EAAA,OAAA;IAID,MAAA,CAAA,EAAA,OAAA;IAIV,eAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IAUgB,WAAA,CAAA,EAzbH,UAybG,EAAA,GAAA,IAAA;IAChB,MAAA,CAAA,EAzbQ,YAybR,EAAA,GAAA,IAAA;IAQO,eAAA,CAAA,EAhcU,MAgcV,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;IAAM,MAAA,CAAA,EA/bL,MA+bK,CAAA,MAAA,EAAA,OAAA,CAAA,GAAA,IAAA;;;;;;;;;;;;;;;;;gBApZF,MAAM;;;;;;;;;;;kBAWJ;aACL;;;;;;;;cAQC;;;;;sBAKQ;aACT;oBACO;;;;;;;;;;;;;;;;;;cA4FN;;;sBAGQ;aACT;;;;;;;;;;;;;;;;;cA2CC;;sBAEQ;aACT;;;;;;;iBA+BI;kBACC;;;;;;;;;;cAUJ;;sBAEQ;aACT;;;;;kBAkCK;;;;;;;cAOJ;;;;sBAIQ;aACT;;;;;iBA2BI;;;;;;;cAOH;;sBAEQ;aACT;;;;;;;;;;;;;;;;;cAwCC;;sBAEQ;aACT;;;;;;;cAqCG;;;;aAID;;;MAIV;;aAUgB;;MAChB;YAQO"}
|
package/dist/client.js
CHANGED
|
@@ -133,7 +133,8 @@ var AmplitudeAI = class {
|
|
|
133
133
|
outputTokens: opts.outputTokens,
|
|
134
134
|
reasoningTokens: opts.reasoningTokens ?? 0,
|
|
135
135
|
cacheReadInputTokens: opts.cacheReadTokens ?? 0,
|
|
136
|
-
cacheCreationInputTokens: opts.cacheCreationTokens ?? 0
|
|
136
|
+
cacheCreationInputTokens: opts.cacheCreationTokens ?? 0,
|
|
137
|
+
defaultProvider: opts.provider || void 0
|
|
137
138
|
});
|
|
138
139
|
} catch {}
|
|
139
140
|
return trackAiMessage({
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["availableProviders: string[]"],"sources":["../src/client.ts"],"sourcesContent":["import { BoundAgent } from './bound-agent.js';\nimport { AIConfig } from './config.js';\nimport type { MessageLabel, SessionEnrichments } from './core/enrichments.js';\nimport type { PrivacyConfig } from './core/privacy.js';\nimport {\n trackAiMessage,\n trackEmbedding,\n trackScore,\n trackSessionEnd,\n trackSessionEnrichment,\n trackSpan,\n trackToolCall,\n trackUserMessage,\n} from './core/tracking.js';\nimport { ConfigurationError } from './exceptions.js';\nimport { patchedProviders } from './patching.js';\nimport { setDefaultPropagateContext } from './propagation.js';\nimport { TenantHandle } from './tenant.js';\nimport type {\n AmplitudeClientLike,\n AmplitudeEvent,\n Attachment,\n} from './types.js';\nimport { calculateCost } from './utils/costs.js';\nimport { formatDebugLine, formatDryRunLine } from './utils/debug.js';\nimport { tryRequire } from './utils/resolve-module.js';\n\nconst _MAX_SESSION_TURN_COUNTERS = 10_000;\n\n/**\n * Main Amplitude AI client for tracking LLM interactions.\n *\n * Create an instance with an API key or an existing Amplitude client,\n * then use `.agent()` to create bound agents and `.session()` to\n * manage session context.\n *\n * @example\n * ```typescript\n * const ai = new AmplitudeAI({ apiKey: 'YOUR_KEY' });\n * const agent = ai.agent('my-chatbot', { userId: 'user-1' });\n * const session = agent.session();\n * await session.run(async (s) => {\n * s.trackUserMessage('Hello');\n * s.trackAiMessage('Hi there!', 'gpt-4', 'openai', 150);\n * });\n * ```\n */\nexport class AmplitudeAI {\n protected _amplitude: AmplitudeClientLike;\n protected _ownsClient: boolean;\n protected _config: AIConfig;\n protected _privacyConfig: PrivacyConfig;\n protected _sessionTurnCounters: Map<string, number> = new Map();\n\n constructor(options: {\n amplitude?: AmplitudeClientLike;\n apiKey?: string;\n config?: AIConfig;\n }) {\n if (options.amplitude != null) {\n this._amplitude = options.amplitude;\n this._ownsClient = false;\n } else if (options.apiKey != null) {\n const amplitudeNode = tryRequire('@amplitude/analytics-node') as\n | (AmplitudeClientLike & { init?: (apiKey: string) => unknown })\n | null;\n if (amplitudeNode == null || typeof amplitudeNode.init !== 'function') {\n throw new ConfigurationError(\n '@amplitude/analytics-node is required. Install it as a dependency.',\n );\n }\n amplitudeNode.init(options.apiKey);\n this._amplitude = amplitudeNode;\n this._ownsClient = true;\n } else {\n throw new ConfigurationError(\n \"Provide either an existing Amplitude instance via 'amplitude' or an API key via 'apiKey'.\",\n );\n }\n\n this._config = options.config ?? new AIConfig();\n this._privacyConfig = this._config.toPrivacyConfig();\n setDefaultPropagateContext(this._config.propagateContext);\n\n if (\n this._config.debug ||\n this._config.dryRun ||\n this._config.onEventCallback != null\n ) {\n this._installTrackHook();\n }\n }\n\n private _installTrackHook(): void {\n const originalTrack = this._amplitude.track.bind(this._amplitude);\n const debug = this._config.debug;\n const dryRun = this._config.dryRun;\n const onEvent = this._config.onEventCallback;\n const clientWithConfig = this._amplitude as AmplitudeClientLike & {\n configuration?: { callback?: (...args: unknown[]) => void };\n };\n const existingCallback = clientWithConfig.configuration?.callback;\n let callbackHandledByTransport = false;\n\n if (onEvent != null && clientWithConfig.configuration != null) {\n clientWithConfig.configuration.callback = (...args: unknown[]) => {\n const event = args[0];\n const statusCode = typeof args[1] === 'number' ? args[1] : 0;\n const message = args[2] == null ? null : String(args[2]);\n if (typeof existingCallback === 'function') {\n try {\n existingCallback(...args);\n } catch {\n // preserve hook behavior even if customer callback throws\n }\n }\n try {\n onEvent(event, statusCode, message);\n } catch {\n // swallow callback errors to avoid disrupting tracking\n }\n };\n callbackHandledByTransport = true;\n }\n\n this._amplitude.track = (event: AmplitudeEvent) => {\n if (debug) {\n console.error(formatDebugLine(event));\n }\n if (dryRun) {\n console.error(formatDryRunLine(event));\n }\n if (!dryRun) {\n originalTrack(event);\n }\n if (onEvent != null && (!callbackHandledByTransport || dryRun)) {\n try {\n onEvent(event, dryRun ? -1 : 0, dryRun ? 'dry-run' : null);\n } catch {\n // swallow callback errors to avoid disrupting tracking\n }\n }\n };\n }\n\n get amplitude(): AmplitudeClientLike {\n return this._amplitude;\n }\n\n get config(): AIConfig {\n return this._config;\n }\n\n _nextTurnId(sessionId: string): number {\n if (\n !this._sessionTurnCounters.has(sessionId) &&\n this._sessionTurnCounters.size >= _MAX_SESSION_TURN_COUNTERS\n ) {\n const oldestKey = this._sessionTurnCounters.keys().next().value;\n if (oldestKey != null) this._sessionTurnCounters.delete(oldestKey);\n }\n\n const current = this._sessionTurnCounters.get(sessionId) ?? 0;\n const next = current + 1;\n this._sessionTurnCounters.set(sessionId, next);\n return next;\n }\n\n // ---------------------------------------------------------------\n // Message Tracking\n // ---------------------------------------------------------------\n\n trackUserMessage(opts: {\n userId: string;\n content: string;\n sessionId: string;\n traceId?: string | null;\n turnId?: number | null;\n messageId?: string | 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 isRegeneration?: boolean;\n isEdit?: boolean;\n editedMessageId?: string | null;\n attachments?: Attachment[] | null;\n labels?: MessageLabel[] | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n const effectiveTurnId = opts.turnId ?? this._nextTurnId(opts.sessionId);\n return trackUserMessage({\n amplitude: this._amplitude,\n userId: opts.userId,\n messageContent: opts.content,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: effectiveTurnId,\n messageId: opts.messageId,\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 isRegeneration: opts.isRegeneration,\n isEdit: opts.isEdit,\n editedMessageId: opts.editedMessageId,\n attachments: opts.attachments,\n labels: opts.labels,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackAiMessage(opts: {\n userId: string;\n content: string;\n sessionId: string;\n model: string;\n provider: string;\n latencyMs: number;\n inputTokens?: number | null;\n outputTokens?: number | null;\n reasoningTokens?: number | null;\n cacheReadTokens?: number | null;\n cacheCreationTokens?: number | null;\n totalTokens?: number | null;\n totalCostUsd?: number | null;\n finishReason?: string | null;\n toolCalls?: Array<Record<string, unknown>> | null;\n reasoningContent?: string | null;\n systemPrompt?: string | null;\n temperature?: number | null;\n maxOutputTokens?: number | null;\n topP?: number | null;\n isStreaming?: boolean | null;\n promptId?: string | null;\n wasCopied?: boolean;\n wasCached?: boolean;\n modelTier?: string | null;\n attachments?: Attachment[] | null;\n labels?: MessageLabel[] | null;\n traceId?: string | null;\n turnId?: number | null;\n messageId?: string | 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 isError?: boolean;\n errorMessage?: string | null;\n ttfbMs?: number | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n privacyConfig?: PrivacyConfig | null;\n }): string {\n const effectiveTurnId = opts.turnId ?? this._nextTurnId(opts.sessionId);\n\n let effectiveCost = opts.totalCostUsd ?? null;\n if (\n effectiveCost == null &&\n opts.inputTokens != null &&\n opts.outputTokens != null\n ) {\n try {\n effectiveCost = calculateCost({\n modelName: opts.model,\n inputTokens: opts.inputTokens,\n outputTokens: opts.outputTokens,\n reasoningTokens: opts.reasoningTokens ?? 0,\n cacheReadInputTokens: opts.cacheReadTokens ?? 0,\n cacheCreationInputTokens: opts.cacheCreationTokens ?? 0,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n return trackAiMessage({\n amplitude: this._amplitude,\n userId: opts.userId,\n modelName: opts.model,\n provider: opts.provider,\n responseContent: opts.content,\n latencyMs: opts.latencyMs,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: effectiveTurnId,\n messageId: opts.messageId,\n inputTokens: opts.inputTokens,\n outputTokens: opts.outputTokens,\n reasoningTokens: opts.reasoningTokens,\n cacheReadInputTokens: opts.cacheReadTokens,\n cacheCreationInputTokens: opts.cacheCreationTokens,\n totalTokens: opts.totalTokens,\n totalCostUsd: effectiveCost,\n finishReason: opts.finishReason,\n toolCalls: opts.toolCalls,\n reasoningContent: opts.reasoningContent,\n systemPrompt: opts.systemPrompt,\n temperature: opts.temperature,\n maxOutputTokens: opts.maxOutputTokens,\n topP: opts.topP,\n isStreaming: opts.isStreaming,\n promptId: opts.promptId,\n wasCopied: opts.wasCopied,\n wasCached: opts.wasCached,\n modelTier: opts.modelTier,\n attachments: opts.attachments,\n labels: opts.labels,\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 isError: opts.isError,\n errorMessage: opts.errorMessage,\n providerTtfbMs: opts.ttfbMs,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: opts.privacyConfig ?? this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Operation Tracking\n // ---------------------------------------------------------------\n\n trackToolCall(opts: {\n userId: string;\n toolName: string;\n latencyMs: number;\n success: boolean;\n sessionId?: string | null;\n traceId?: string | null;\n turnId?: number | null;\n invocationId?: string | null;\n input?: unknown;\n output?: unknown;\n parentMessageId?: string | 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 errorMessage?: string | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n return trackToolCall({\n amplitude: this._amplitude,\n userId: opts.userId,\n toolName: opts.toolName,\n success: opts.success,\n latencyMs: opts.latencyMs,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: opts.turnId ?? undefined,\n invocationId: opts.invocationId,\n toolInput: opts.input,\n toolOutput: opts.output,\n parentMessageId: opts.parentMessageId,\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 errorMessage: opts.errorMessage,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackEmbedding(opts: {\n userId: string;\n model: string;\n provider: string;\n latencyMs: number;\n inputTokens?: number | null;\n dimensions?: number | null;\n totalCostUsd?: number | 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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n return trackEmbedding({\n amplitude: this._amplitude,\n userId: opts.userId,\n model: opts.model,\n provider: opts.provider,\n latencyMs: opts.latencyMs,\n inputTokens: opts.inputTokens,\n dimensions: opts.dimensions,\n totalCostUsd: opts.totalCostUsd,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackSpan(opts: {\n userId: string;\n spanName: string;\n traceId: string;\n latencyMs: number;\n inputState?: Record<string, unknown> | null;\n outputState?: Record<string, unknown> | null;\n parentSpanId?: string | null;\n isError?: boolean;\n errorMessage?: string | null;\n sessionId?: 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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n return trackSpan({\n amplitude: this._amplitude,\n userId: opts.userId,\n spanName: opts.spanName,\n traceId: opts.traceId,\n latencyMs: opts.latencyMs,\n inputState: opts.inputState,\n outputState: opts.outputState,\n parentSpanId: opts.parentSpanId,\n isError: opts.isError,\n errorMessage: opts.errorMessage,\n sessionId: opts.sessionId,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Session Management\n // ---------------------------------------------------------------\n\n trackSessionEnd(opts: {\n userId: string;\n sessionId: string;\n enrichments?: SessionEnrichments | 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 abandonmentTurn?: number | null;\n idleTimeoutMinutes?: number | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): void {\n trackSessionEnd({\n amplitude: this._amplitude,\n userId: opts.userId,\n sessionId: opts.sessionId,\n enrichments: opts.enrichments,\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 abandonmentTurn: opts.abandonmentTurn,\n idleTimeoutMinutes: opts.idleTimeoutMinutes,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n this._sessionTurnCounters.delete(opts.sessionId);\n }\n\n trackSessionEnrichment(opts: {\n userId: string;\n sessionId: string;\n enrichments: SessionEnrichments;\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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): void {\n trackSessionEnrichment({\n amplitude: this._amplitude,\n userId: opts.userId,\n sessionId: opts.sessionId,\n enrichments: opts.enrichments,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Scoring\n // ---------------------------------------------------------------\n\n score(opts: {\n userId: string;\n name: string;\n value: number;\n targetId: string;\n targetType?: string;\n source?: string;\n comment?: 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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): void {\n trackScore({\n amplitude: this._amplitude,\n userId: opts.userId,\n name: opts.name,\n value: opts.value,\n targetId: opts.targetId,\n targetType: opts.targetType,\n source: opts.source,\n comment: opts.comment,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Bound Agent Factory\n // ---------------------------------------------------------------\n\n agent(\n agentId: string,\n opts: {\n userId?: 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 sessionId?: string | null;\n traceId?: string | null;\n groups?: Record<string, unknown> | null;\n deviceId?: string | null;\n browserSessionId?: string | null;\n } = {},\n ): BoundAgent {\n return new BoundAgent(this, { agentId, ...opts });\n }\n\n // ---------------------------------------------------------------\n // Tenant Factory\n // ---------------------------------------------------------------\n\n tenant(\n customerOrgId: string,\n opts: { groups?: Record<string, unknown> | null; env?: string | null } = {},\n ): TenantHandle {\n return new TenantHandle(this, { customerOrgId, ...opts });\n }\n\n // ---------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------\n\n status(): Record<string, unknown> {\n const availableProviders: string[] = [];\n for (const mod of [\n 'openai',\n '@anthropic-ai/sdk',\n '@google/generative-ai',\n '@aws-sdk/client-bedrock-runtime',\n '@mistralai/mistralai',\n ]) {\n if (tryRequire(mod) != null) {\n const name =\n mod === '@anthropic-ai/sdk'\n ? 'anthropic'\n : mod === '@google/generative-ai'\n ? 'gemini'\n : mod === '@aws-sdk/client-bedrock-runtime'\n ? 'bedrock'\n : mod === '@mistralai/mistralai'\n ? 'mistral'\n : mod;\n availableProviders.push(name);\n if (mod === 'openai') {\n availableProviders.push('azure-openai');\n }\n }\n }\n\n return {\n content_mode: this._config.contentMode,\n debug: this._config.debug,\n dry_run: this._config.dryRun,\n redact_pii: this._config.redactPii,\n providers_available: availableProviders,\n patched_providers: patchedProviders(),\n };\n }\n\n flush(): unknown {\n return this._amplitude.flush();\n }\n\n shutdown(): void {\n if (this._ownsClient) {\n this._amplitude.shutdown?.();\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["availableProviders: string[]"],"sources":["../src/client.ts"],"sourcesContent":["import { BoundAgent } from './bound-agent.js';\nimport { AIConfig } from './config.js';\nimport type { MessageLabel, SessionEnrichments } from './core/enrichments.js';\nimport type { PrivacyConfig } from './core/privacy.js';\nimport {\n trackAiMessage,\n trackEmbedding,\n trackScore,\n trackSessionEnd,\n trackSessionEnrichment,\n trackSpan,\n trackToolCall,\n trackUserMessage,\n} from './core/tracking.js';\nimport { ConfigurationError } from './exceptions.js';\nimport { patchedProviders } from './patching.js';\nimport { setDefaultPropagateContext } from './propagation.js';\nimport { TenantHandle } from './tenant.js';\nimport type {\n AmplitudeClientLike,\n AmplitudeEvent,\n Attachment,\n} from './types.js';\nimport { calculateCost } from './utils/costs.js';\nimport { formatDebugLine, formatDryRunLine } from './utils/debug.js';\nimport { tryRequire } from './utils/resolve-module.js';\n\nconst _MAX_SESSION_TURN_COUNTERS = 10_000;\n\n/**\n * Main Amplitude AI client for tracking LLM interactions.\n *\n * Create an instance with an API key or an existing Amplitude client,\n * then use `.agent()` to create bound agents and `.session()` to\n * manage session context.\n *\n * @example\n * ```typescript\n * const ai = new AmplitudeAI({ apiKey: 'YOUR_KEY' });\n * const agent = ai.agent('my-chatbot', { userId: 'user-1' });\n * const session = agent.session();\n * await session.run(async (s) => {\n * s.trackUserMessage('Hello');\n * s.trackAiMessage('Hi there!', 'gpt-4', 'openai', 150);\n * });\n * ```\n */\nexport class AmplitudeAI {\n protected _amplitude: AmplitudeClientLike;\n protected _ownsClient: boolean;\n protected _config: AIConfig;\n protected _privacyConfig: PrivacyConfig;\n protected _sessionTurnCounters: Map<string, number> = new Map();\n\n constructor(options: {\n amplitude?: AmplitudeClientLike;\n apiKey?: string;\n config?: AIConfig;\n }) {\n if (options.amplitude != null) {\n this._amplitude = options.amplitude;\n this._ownsClient = false;\n } else if (options.apiKey != null) {\n const amplitudeNode = tryRequire('@amplitude/analytics-node') as\n | (AmplitudeClientLike & { init?: (apiKey: string) => unknown })\n | null;\n if (amplitudeNode == null || typeof amplitudeNode.init !== 'function') {\n throw new ConfigurationError(\n '@amplitude/analytics-node is required. Install it as a dependency.',\n );\n }\n amplitudeNode.init(options.apiKey);\n this._amplitude = amplitudeNode;\n this._ownsClient = true;\n } else {\n throw new ConfigurationError(\n \"Provide either an existing Amplitude instance via 'amplitude' or an API key via 'apiKey'.\",\n );\n }\n\n this._config = options.config ?? new AIConfig();\n this._privacyConfig = this._config.toPrivacyConfig();\n setDefaultPropagateContext(this._config.propagateContext);\n\n if (\n this._config.debug ||\n this._config.dryRun ||\n this._config.onEventCallback != null\n ) {\n this._installTrackHook();\n }\n }\n\n private _installTrackHook(): void {\n const originalTrack = this._amplitude.track.bind(this._amplitude);\n const debug = this._config.debug;\n const dryRun = this._config.dryRun;\n const onEvent = this._config.onEventCallback;\n const clientWithConfig = this._amplitude as AmplitudeClientLike & {\n configuration?: { callback?: (...args: unknown[]) => void };\n };\n const existingCallback = clientWithConfig.configuration?.callback;\n let callbackHandledByTransport = false;\n\n if (onEvent != null && clientWithConfig.configuration != null) {\n clientWithConfig.configuration.callback = (...args: unknown[]) => {\n const event = args[0];\n const statusCode = typeof args[1] === 'number' ? args[1] : 0;\n const message = args[2] == null ? null : String(args[2]);\n if (typeof existingCallback === 'function') {\n try {\n existingCallback(...args);\n } catch {\n // preserve hook behavior even if customer callback throws\n }\n }\n try {\n onEvent(event, statusCode, message);\n } catch {\n // swallow callback errors to avoid disrupting tracking\n }\n };\n callbackHandledByTransport = true;\n }\n\n this._amplitude.track = (event: AmplitudeEvent) => {\n if (debug) {\n console.error(formatDebugLine(event));\n }\n if (dryRun) {\n console.error(formatDryRunLine(event));\n }\n if (!dryRun) {\n originalTrack(event);\n }\n if (onEvent != null && (!callbackHandledByTransport || dryRun)) {\n try {\n onEvent(event, dryRun ? -1 : 0, dryRun ? 'dry-run' : null);\n } catch {\n // swallow callback errors to avoid disrupting tracking\n }\n }\n };\n }\n\n get amplitude(): AmplitudeClientLike {\n return this._amplitude;\n }\n\n get config(): AIConfig {\n return this._config;\n }\n\n _nextTurnId(sessionId: string): number {\n if (\n !this._sessionTurnCounters.has(sessionId) &&\n this._sessionTurnCounters.size >= _MAX_SESSION_TURN_COUNTERS\n ) {\n const oldestKey = this._sessionTurnCounters.keys().next().value;\n if (oldestKey != null) this._sessionTurnCounters.delete(oldestKey);\n }\n\n const current = this._sessionTurnCounters.get(sessionId) ?? 0;\n const next = current + 1;\n this._sessionTurnCounters.set(sessionId, next);\n return next;\n }\n\n // ---------------------------------------------------------------\n // Message Tracking\n // ---------------------------------------------------------------\n\n trackUserMessage(opts: {\n userId: string;\n content: string;\n sessionId: string;\n traceId?: string | null;\n turnId?: number | null;\n messageId?: string | 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 isRegeneration?: boolean;\n isEdit?: boolean;\n editedMessageId?: string | null;\n attachments?: Attachment[] | null;\n labels?: MessageLabel[] | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n const effectiveTurnId = opts.turnId ?? this._nextTurnId(opts.sessionId);\n return trackUserMessage({\n amplitude: this._amplitude,\n userId: opts.userId,\n messageContent: opts.content,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: effectiveTurnId,\n messageId: opts.messageId,\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 isRegeneration: opts.isRegeneration,\n isEdit: opts.isEdit,\n editedMessageId: opts.editedMessageId,\n attachments: opts.attachments,\n labels: opts.labels,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackAiMessage(opts: {\n userId: string;\n content: string;\n sessionId: string;\n model: string;\n provider: string;\n latencyMs: number;\n inputTokens?: number | null;\n outputTokens?: number | null;\n reasoningTokens?: number | null;\n cacheReadTokens?: number | null;\n cacheCreationTokens?: number | null;\n totalTokens?: number | null;\n totalCostUsd?: number | null;\n finishReason?: string | null;\n toolCalls?: Array<Record<string, unknown>> | null;\n reasoningContent?: string | null;\n systemPrompt?: string | null;\n temperature?: number | null;\n maxOutputTokens?: number | null;\n topP?: number | null;\n isStreaming?: boolean | null;\n promptId?: string | null;\n wasCopied?: boolean;\n wasCached?: boolean;\n modelTier?: string | null;\n attachments?: Attachment[] | null;\n labels?: MessageLabel[] | null;\n traceId?: string | null;\n turnId?: number | null;\n messageId?: string | 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 isError?: boolean;\n errorMessage?: string | null;\n ttfbMs?: number | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n privacyConfig?: PrivacyConfig | null;\n }): string {\n const effectiveTurnId = opts.turnId ?? this._nextTurnId(opts.sessionId);\n\n let effectiveCost = opts.totalCostUsd ?? null;\n if (\n effectiveCost == null &&\n opts.inputTokens != null &&\n opts.outputTokens != null\n ) {\n try {\n effectiveCost = calculateCost({\n modelName: opts.model,\n inputTokens: opts.inputTokens,\n outputTokens: opts.outputTokens,\n reasoningTokens: opts.reasoningTokens ?? 0,\n cacheReadInputTokens: opts.cacheReadTokens ?? 0,\n cacheCreationInputTokens: opts.cacheCreationTokens ?? 0,\n defaultProvider: opts.provider || undefined,\n });\n } catch {\n // cost calculation is best-effort\n }\n }\n\n return trackAiMessage({\n amplitude: this._amplitude,\n userId: opts.userId,\n modelName: opts.model,\n provider: opts.provider,\n responseContent: opts.content,\n latencyMs: opts.latencyMs,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: effectiveTurnId,\n messageId: opts.messageId,\n inputTokens: opts.inputTokens,\n outputTokens: opts.outputTokens,\n reasoningTokens: opts.reasoningTokens,\n cacheReadInputTokens: opts.cacheReadTokens,\n cacheCreationInputTokens: opts.cacheCreationTokens,\n totalTokens: opts.totalTokens,\n totalCostUsd: effectiveCost,\n finishReason: opts.finishReason,\n toolCalls: opts.toolCalls,\n reasoningContent: opts.reasoningContent,\n systemPrompt: opts.systemPrompt,\n temperature: opts.temperature,\n maxOutputTokens: opts.maxOutputTokens,\n topP: opts.topP,\n isStreaming: opts.isStreaming,\n promptId: opts.promptId,\n wasCopied: opts.wasCopied,\n wasCached: opts.wasCached,\n modelTier: opts.modelTier,\n attachments: opts.attachments,\n labels: opts.labels,\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 isError: opts.isError,\n errorMessage: opts.errorMessage,\n providerTtfbMs: opts.ttfbMs,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: opts.privacyConfig ?? this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Operation Tracking\n // ---------------------------------------------------------------\n\n trackToolCall(opts: {\n userId: string;\n toolName: string;\n latencyMs: number;\n success: boolean;\n sessionId?: string | null;\n traceId?: string | null;\n turnId?: number | null;\n invocationId?: string | null;\n input?: unknown;\n output?: unknown;\n parentMessageId?: string | 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 errorMessage?: string | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n return trackToolCall({\n amplitude: this._amplitude,\n userId: opts.userId,\n toolName: opts.toolName,\n success: opts.success,\n latencyMs: opts.latencyMs,\n sessionId: opts.sessionId,\n traceId: opts.traceId,\n turnId: opts.turnId ?? undefined,\n invocationId: opts.invocationId,\n toolInput: opts.input,\n toolOutput: opts.output,\n parentMessageId: opts.parentMessageId,\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 errorMessage: opts.errorMessage,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackEmbedding(opts: {\n userId: string;\n model: string;\n provider: string;\n latencyMs: number;\n inputTokens?: number | null;\n dimensions?: number | null;\n totalCostUsd?: number | 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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n return trackEmbedding({\n amplitude: this._amplitude,\n userId: opts.userId,\n model: opts.model,\n provider: opts.provider,\n latencyMs: opts.latencyMs,\n inputTokens: opts.inputTokens,\n dimensions: opts.dimensions,\n totalCostUsd: opts.totalCostUsd,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n trackSpan(opts: {\n userId: string;\n spanName: string;\n traceId: string;\n latencyMs: number;\n inputState?: Record<string, unknown> | null;\n outputState?: Record<string, unknown> | null;\n parentSpanId?: string | null;\n isError?: boolean;\n errorMessage?: string | null;\n sessionId?: 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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): string {\n return trackSpan({\n amplitude: this._amplitude,\n userId: opts.userId,\n spanName: opts.spanName,\n traceId: opts.traceId,\n latencyMs: opts.latencyMs,\n inputState: opts.inputState,\n outputState: opts.outputState,\n parentSpanId: opts.parentSpanId,\n isError: opts.isError,\n errorMessage: opts.errorMessage,\n sessionId: opts.sessionId,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Session Management\n // ---------------------------------------------------------------\n\n trackSessionEnd(opts: {\n userId: string;\n sessionId: string;\n enrichments?: SessionEnrichments | 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 abandonmentTurn?: number | null;\n idleTimeoutMinutes?: number | null;\n eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): void {\n trackSessionEnd({\n amplitude: this._amplitude,\n userId: opts.userId,\n sessionId: opts.sessionId,\n enrichments: opts.enrichments,\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 abandonmentTurn: opts.abandonmentTurn,\n idleTimeoutMinutes: opts.idleTimeoutMinutes,\n eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n this._sessionTurnCounters.delete(opts.sessionId);\n }\n\n trackSessionEnrichment(opts: {\n userId: string;\n sessionId: string;\n enrichments: SessionEnrichments;\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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): void {\n trackSessionEnrichment({\n amplitude: this._amplitude,\n userId: opts.userId,\n sessionId: opts.sessionId,\n enrichments: opts.enrichments,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Scoring\n // ---------------------------------------------------------------\n\n score(opts: {\n userId: string;\n name: string;\n value: number;\n targetId: string;\n targetType?: string;\n source?: string;\n comment?: 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 eventProperties?: Record<string, unknown> | null;\n groups?: Record<string, unknown> | null;\n }): void {\n trackScore({\n amplitude: this._amplitude,\n userId: opts.userId,\n name: opts.name,\n value: opts.value,\n targetId: opts.targetId,\n targetType: opts.targetType,\n source: opts.source,\n comment: opts.comment,\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 eventProperties: opts.eventProperties,\n groups: opts.groups,\n privacyConfig: this._privacyConfig,\n });\n }\n\n // ---------------------------------------------------------------\n // Bound Agent Factory\n // ---------------------------------------------------------------\n\n agent(\n agentId: string,\n opts: {\n userId?: 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 sessionId?: string | null;\n traceId?: string | null;\n groups?: Record<string, unknown> | null;\n deviceId?: string | null;\n browserSessionId?: string | null;\n } = {},\n ): BoundAgent {\n return new BoundAgent(this, { agentId, ...opts });\n }\n\n // ---------------------------------------------------------------\n // Tenant Factory\n // ---------------------------------------------------------------\n\n tenant(\n customerOrgId: string,\n opts: { groups?: Record<string, unknown> | null; env?: string | null } = {},\n ): TenantHandle {\n return new TenantHandle(this, { customerOrgId, ...opts });\n }\n\n // ---------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------\n\n status(): Record<string, unknown> {\n const availableProviders: string[] = [];\n for (const mod of [\n 'openai',\n '@anthropic-ai/sdk',\n '@google/generative-ai',\n '@aws-sdk/client-bedrock-runtime',\n '@mistralai/mistralai',\n ]) {\n if (tryRequire(mod) != null) {\n const name =\n mod === '@anthropic-ai/sdk'\n ? 'anthropic'\n : mod === '@google/generative-ai'\n ? 'gemini'\n : mod === '@aws-sdk/client-bedrock-runtime'\n ? 'bedrock'\n : mod === '@mistralai/mistralai'\n ? 'mistral'\n : mod;\n availableProviders.push(name);\n if (mod === 'openai') {\n availableProviders.push('azure-openai');\n }\n }\n }\n\n return {\n content_mode: this._config.contentMode,\n debug: this._config.debug,\n dry_run: this._config.dryRun,\n redact_pii: this._config.redactPii,\n providers_available: availableProviders,\n patched_providers: patchedProviders(),\n };\n }\n\n flush(): unknown {\n return this._amplitude.flush();\n }\n\n shutdown(): void {\n if (this._ownsClient) {\n this._amplitude.shutdown?.();\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ import { AmplitudeTracingProcessor } from "./integrations/openai-agents.js";
|
|
|
31
31
|
import { AmplitudeToolLoop } from "./integrations/anthropic-tools.js";
|
|
32
32
|
import { AmplitudeCrewAIHooks } from "./integrations/crewai.js";
|
|
33
33
|
import { inferProviderFromModel } from "./utils/providers.js";
|
|
34
|
-
import { calculateCost, getGenaiPriceLookupCandidates, inferProvider, stripProviderPrefix } from "./utils/costs.js";
|
|
34
|
+
import { calculateCost, enableLivePriceUpdates, getGenaiPriceLookupCandidates, inferProvider, stripProviderPrefix } from "./utils/costs.js";
|
|
35
35
|
import { countMessageTokens, countTokens, estimateTokens } from "./utils/tokens.js";
|
|
36
36
|
import { TIER_FAST, TIER_REASONING, TIER_STANDARD, inferModelTier } from "./utils/model-tiers.js";
|
|
37
|
-
export { AIConfig, type AIConfigOptions, ANTHROPIC_AVAILABLE, OPENAI_AVAILABLE as AZURE_OPENAI_AVAILABLE, type AiMessageOpts, AmplitudeAI, AmplitudeAIError, type AmplitudeAILike, AmplitudeAIWrapError, AmplitudeAgentExporter, AmplitudeCallbackHandler, type AmplitudeClientLike, AmplitudeCrewAIHooks, type AmplitudeEvent, AmplitudeGenAIExporter, type AmplitudeLike, AmplitudeLlamaIndexHandler, type AmplitudeOrAI, AmplitudeSpanExporter, AmplitudeToolLoop, AmplitudeTracingProcessor, Anthropic, type AnthropicParams, type AnthropicResponse, type Attachment, AzureOpenAI, BEDROCK_AVAILABLE, Bedrock, type BedrockConverseParams, type BedrockConverseResponse, BoundAgent, type ChatCompletionParams, type ChatCompletionResponse, type ChatMessage, ConfigurationError, type ContentBlock, ContentMode, EVENT_AI_RESPONSE, EVENT_EMBEDDING, EVENT_SCORE, EVENT_SESSION_END, EVENT_SESSION_ENRICHMENT, EVENT_SPAN, EVENT_TOOL_CALL, EVENT_USER_MESSAGE, type EmbeddingOpts, EvidenceQuote, GEMINI_AVAILABLE, GENERATED_FILES, Gemini, MAX_SERIALIZED_LENGTH, MCP_PROMPTS, MCP_RESOURCES, MCP_SERVER_NAME, MCP_TOOLS, MISTRAL_AVAILABLE, MessageLabel, type MiddlewareOptions, Mistral, type MistralChatParams, type MistralChatResponse, MockAmplitudeAI, OPENAI_AVAILABLE, type ObserveWrapped, OpenAI, PROP_ABANDONMENT_TURN, PROP_AGENT_CHAIN, PROP_AGENT_ID, PROP_AGENT_VERSION, PROP_ATTACHMENTS, PROP_ATTACHMENT_COUNT, PROP_ATTACHMENT_TYPES, PROP_CACHE_CREATION_TOKENS, PROP_CACHE_READ_TOKENS, PROP_COMMENT, PROP_COMPONENT_TYPE, PROP_CONTEXT, PROP_COST_USD, PROP_CUSTOMER_ORG_ID, PROP_EDITED_MESSAGE_ID, PROP_EMBEDDING_DIMENSIONS, PROP_ENRICHMENTS, PROP_ENV, PROP_ERROR_MESSAGE, PROP_EVALUATION_SOURCE, PROP_FINISH_REASON, PROP_HAS_ATTACHMENTS, PROP_HAS_REASONING, PROP_IDLE_TIMEOUT_MINUTES, PROP_INPUT_STATE, PROP_INPUT_TOKENS, PROP_INVOCATION_ID, PROP_IS_EDIT, PROP_IS_ERROR, PROP_IS_REGENERATION, PROP_IS_STREAMING, PROP_LATENCY_MS, PROP_LOCALE, PROP_MAX_OUTPUT_TOKENS, PROP_MESSAGE_ID, PROP_MESSAGE_LABELS, PROP_MESSAGE_LABEL_MAP, PROP_MODEL_NAME, PROP_MODEL_TIER, PROP_OUTPUT_STATE, PROP_OUTPUT_TOKENS, PROP_PARENT_AGENT_ID, PROP_PARENT_MESSAGE_ID, PROP_PARENT_SPAN_ID, PROP_PROMPT_ID, PROP_PROVIDER, PROP_QUALITY_SCORE, PROP_REASONING_CONTENT, PROP_REASONING_TOKENS, PROP_REQUEST_COMPLEXITY, PROP_ROOT_AGENT_NAME, PROP_RUNTIME, PROP_SCORE_NAME, PROP_SCORE_VALUE, PROP_SDK_VERSION, PROP_SENTIMENT_SCORE, PROP_SESSION_ID, PROP_SESSION_REPLAY_ID, PROP_SPAN_ID, PROP_SPAN_KIND, PROP_SPAN_NAME, PROP_SYSTEM_PROMPT, PROP_SYSTEM_PROMPT_LENGTH, PROP_TARGET_ID, PROP_TARGET_TYPE, PROP_TASK_FAILURE_REASON, PROP_TASK_FAILURE_TYPE, PROP_TEMPERATURE, PROP_TOOL_CALLS, PROP_TOOL_INPUT, PROP_TOOL_NAME, PROP_TOOL_OUTPUT, PROP_TOOL_SUCCESS, PROP_TOP_P, PROP_TOTAL_ATTACHMENT_SIZE, PROP_TOTAL_TOKENS, PROP_TRACE_ID, PROP_TTFB_MS, PROP_TURN_ID, PROP_WAS_CACHED, PROP_WAS_COPIED, PrivacyConfig, ProviderError, RubricScore, SDK_RUNTIME, SDK_VERSION, type ScoreOpts, Session, SessionContext, type SessionEndOpts, type SessionEnrichmentOpts, SessionEnrichments, type SpanOpts, StreamingAccumulator, TIER_FAST, TIER_REASONING, TIER_STANDARD, TenantHandle, type ToolCallOpts, type ToolCallShape, ToolCallTracker, type ToolWrapped, TopicClassification, type TrackCallOptions, type TrackFn, TrackingError, type UserMessageOpts, ValidationError, WrappedResponses, calculateCost, countMessageTokens, countTokens, createAmplitudeAIMiddleware, createAmplitudeCallback, createAmplitudeLlamaIndexHandler, estimateTokens, extractAnthropicContent, extractAnthropicSystemPrompt, extractBedrockResponse, extractContext, extractGeminiResponse, extractSystemPrompt, getActiveContext, getGenaiPriceLookupCandidates, inferModelTier, inferProvider, inferProviderFromModel, injectContext, observe, patch, patchAnthropic, patchAzureOpenAI, patchBedrock, patchGemini, patchMistral, patchOpenAI, patchedProviders, resolveAmplitude, runWithContext, runWithContextAsync, serializeToJsonString, stripProviderPrefix, tool, trackAiMessage, trackConversation, trackEmbedding, trackScore, trackSessionEnd, trackSessionEnrichment, trackSpan, trackToolCall, trackUserMessage, unpatch, unpatchAnthropic, unpatchAzureOpenAI, unpatchBedrock, unpatchGemini, unpatchMistral, unpatchOpenAI, wrap };
|
|
37
|
+
export { AIConfig, type AIConfigOptions, ANTHROPIC_AVAILABLE, OPENAI_AVAILABLE as AZURE_OPENAI_AVAILABLE, type AiMessageOpts, AmplitudeAI, AmplitudeAIError, type AmplitudeAILike, AmplitudeAIWrapError, AmplitudeAgentExporter, AmplitudeCallbackHandler, type AmplitudeClientLike, AmplitudeCrewAIHooks, type AmplitudeEvent, AmplitudeGenAIExporter, type AmplitudeLike, AmplitudeLlamaIndexHandler, type AmplitudeOrAI, AmplitudeSpanExporter, AmplitudeToolLoop, AmplitudeTracingProcessor, Anthropic, type AnthropicParams, type AnthropicResponse, type Attachment, AzureOpenAI, BEDROCK_AVAILABLE, Bedrock, type BedrockConverseParams, type BedrockConverseResponse, BoundAgent, type ChatCompletionParams, type ChatCompletionResponse, type ChatMessage, ConfigurationError, type ContentBlock, ContentMode, EVENT_AI_RESPONSE, EVENT_EMBEDDING, EVENT_SCORE, EVENT_SESSION_END, EVENT_SESSION_ENRICHMENT, EVENT_SPAN, EVENT_TOOL_CALL, EVENT_USER_MESSAGE, type EmbeddingOpts, EvidenceQuote, GEMINI_AVAILABLE, GENERATED_FILES, Gemini, MAX_SERIALIZED_LENGTH, MCP_PROMPTS, MCP_RESOURCES, MCP_SERVER_NAME, MCP_TOOLS, MISTRAL_AVAILABLE, MessageLabel, type MiddlewareOptions, Mistral, type MistralChatParams, type MistralChatResponse, MockAmplitudeAI, OPENAI_AVAILABLE, type ObserveWrapped, OpenAI, PROP_ABANDONMENT_TURN, PROP_AGENT_CHAIN, PROP_AGENT_ID, PROP_AGENT_VERSION, PROP_ATTACHMENTS, PROP_ATTACHMENT_COUNT, PROP_ATTACHMENT_TYPES, PROP_CACHE_CREATION_TOKENS, PROP_CACHE_READ_TOKENS, PROP_COMMENT, PROP_COMPONENT_TYPE, PROP_CONTEXT, PROP_COST_USD, PROP_CUSTOMER_ORG_ID, PROP_EDITED_MESSAGE_ID, PROP_EMBEDDING_DIMENSIONS, PROP_ENRICHMENTS, PROP_ENV, PROP_ERROR_MESSAGE, PROP_EVALUATION_SOURCE, PROP_FINISH_REASON, PROP_HAS_ATTACHMENTS, PROP_HAS_REASONING, PROP_IDLE_TIMEOUT_MINUTES, PROP_INPUT_STATE, PROP_INPUT_TOKENS, PROP_INVOCATION_ID, PROP_IS_EDIT, PROP_IS_ERROR, PROP_IS_REGENERATION, PROP_IS_STREAMING, PROP_LATENCY_MS, PROP_LOCALE, PROP_MAX_OUTPUT_TOKENS, PROP_MESSAGE_ID, PROP_MESSAGE_LABELS, PROP_MESSAGE_LABEL_MAP, PROP_MODEL_NAME, PROP_MODEL_TIER, PROP_OUTPUT_STATE, PROP_OUTPUT_TOKENS, PROP_PARENT_AGENT_ID, PROP_PARENT_MESSAGE_ID, PROP_PARENT_SPAN_ID, PROP_PROMPT_ID, PROP_PROVIDER, PROP_QUALITY_SCORE, PROP_REASONING_CONTENT, PROP_REASONING_TOKENS, PROP_REQUEST_COMPLEXITY, PROP_ROOT_AGENT_NAME, PROP_RUNTIME, PROP_SCORE_NAME, PROP_SCORE_VALUE, PROP_SDK_VERSION, PROP_SENTIMENT_SCORE, PROP_SESSION_ID, PROP_SESSION_REPLAY_ID, PROP_SPAN_ID, PROP_SPAN_KIND, PROP_SPAN_NAME, PROP_SYSTEM_PROMPT, PROP_SYSTEM_PROMPT_LENGTH, PROP_TARGET_ID, PROP_TARGET_TYPE, PROP_TASK_FAILURE_REASON, PROP_TASK_FAILURE_TYPE, PROP_TEMPERATURE, PROP_TOOL_CALLS, PROP_TOOL_INPUT, PROP_TOOL_NAME, PROP_TOOL_OUTPUT, PROP_TOOL_SUCCESS, PROP_TOP_P, PROP_TOTAL_ATTACHMENT_SIZE, PROP_TOTAL_TOKENS, PROP_TRACE_ID, PROP_TTFB_MS, PROP_TURN_ID, PROP_WAS_CACHED, PROP_WAS_COPIED, PrivacyConfig, ProviderError, RubricScore, SDK_RUNTIME, SDK_VERSION, type ScoreOpts, Session, SessionContext, type SessionEndOpts, type SessionEnrichmentOpts, SessionEnrichments, type SpanOpts, StreamingAccumulator, TIER_FAST, TIER_REASONING, TIER_STANDARD, TenantHandle, type ToolCallOpts, type ToolCallShape, ToolCallTracker, type ToolWrapped, TopicClassification, type TrackCallOptions, type TrackFn, TrackingError, type UserMessageOpts, ValidationError, WrappedResponses, calculateCost, countMessageTokens, countTokens, createAmplitudeAIMiddleware, createAmplitudeCallback, createAmplitudeLlamaIndexHandler, enableLivePriceUpdates, estimateTokens, extractAnthropicContent, extractAnthropicSystemPrompt, extractBedrockResponse, extractContext, extractGeminiResponse, extractSystemPrompt, getActiveContext, getGenaiPriceLookupCandidates, inferModelTier, inferProvider, inferProviderFromModel, injectContext, observe, patch, patchAnthropic, patchAzureOpenAI, patchBedrock, patchGemini, patchMistral, patchOpenAI, patchedProviders, resolveAmplitude, runWithContext, runWithContextAsync, serializeToJsonString, stripProviderPrefix, tool, trackAiMessage, trackConversation, trackEmbedding, trackScore, trackSessionEnd, trackSessionEnrichment, trackSpan, trackToolCall, trackUserMessage, unpatch, unpatchAnthropic, unpatchAzureOpenAI, unpatchBedrock, unpatchGemini, unpatchMistral, unpatchOpenAI, wrap };
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { BoundAgent } from "./bound-agent.js";
|
|
|
9
9
|
import { AIConfig, ContentMode } from "./config.js";
|
|
10
10
|
import { extractContext, injectContext } from "./propagation.js";
|
|
11
11
|
import { inferProviderFromModel } from "./utils/providers.js";
|
|
12
|
-
import { calculateCost, getGenaiPriceLookupCandidates, inferProvider, stripProviderPrefix } from "./utils/costs.js";
|
|
12
|
+
import { calculateCost, enableLivePriceUpdates, getGenaiPriceLookupCandidates, inferProvider, stripProviderPrefix } from "./utils/costs.js";
|
|
13
13
|
import { StreamingAccumulator } from "./utils/streaming.js";
|
|
14
14
|
import { resolveAmplitude } from "./types.js";
|
|
15
15
|
import { ANTHROPIC_AVAILABLE, Anthropic, extractAnthropicContent, extractAnthropicSystemPrompt } from "./providers/anthropic.js";
|
|
@@ -35,4 +35,4 @@ import { AmplitudeToolLoop } from "./integrations/anthropic-tools.js";
|
|
|
35
35
|
import { AmplitudeCrewAIHooks } from "./integrations/crewai.js";
|
|
36
36
|
import { countMessageTokens, countTokens, estimateTokens } from "./utils/tokens.js";
|
|
37
37
|
|
|
38
|
-
export { AIConfig, ANTHROPIC_AVAILABLE, OPENAI_AVAILABLE as AZURE_OPENAI_AVAILABLE, AmplitudeAI, AmplitudeAIError, AmplitudeAIWrapError, AmplitudeAgentExporter, AmplitudeCallbackHandler, AmplitudeCrewAIHooks, AmplitudeGenAIExporter, AmplitudeLlamaIndexHandler, AmplitudeSpanExporter, AmplitudeToolLoop, AmplitudeTracingProcessor, Anthropic, AzureOpenAI, BEDROCK_AVAILABLE, Bedrock, BoundAgent, ConfigurationError, ContentMode, EVENT_AI_RESPONSE, EVENT_EMBEDDING, EVENT_SCORE, EVENT_SESSION_END, EVENT_SESSION_ENRICHMENT, EVENT_SPAN, EVENT_TOOL_CALL, EVENT_USER_MESSAGE, EvidenceQuote, GEMINI_AVAILABLE, GENERATED_FILES, Gemini, MAX_SERIALIZED_LENGTH, MCP_PROMPTS, MCP_RESOURCES, MCP_SERVER_NAME, MCP_TOOLS, MISTRAL_AVAILABLE, MessageLabel, Mistral, MockAmplitudeAI, OPENAI_AVAILABLE, OpenAI, PROP_ABANDONMENT_TURN, PROP_AGENT_CHAIN, PROP_AGENT_ID, PROP_AGENT_VERSION, PROP_ATTACHMENTS, PROP_ATTACHMENT_COUNT, PROP_ATTACHMENT_TYPES, PROP_CACHE_CREATION_TOKENS, PROP_CACHE_READ_TOKENS, PROP_COMMENT, PROP_COMPONENT_TYPE, PROP_CONTEXT, PROP_COST_USD, PROP_CUSTOMER_ORG_ID, PROP_EDITED_MESSAGE_ID, PROP_EMBEDDING_DIMENSIONS, PROP_ENRICHMENTS, PROP_ENV, PROP_ERROR_MESSAGE, PROP_EVALUATION_SOURCE, PROP_FINISH_REASON, PROP_HAS_ATTACHMENTS, PROP_HAS_REASONING, PROP_IDLE_TIMEOUT_MINUTES, PROP_INPUT_STATE, PROP_INPUT_TOKENS, PROP_INVOCATION_ID, PROP_IS_EDIT, PROP_IS_ERROR, PROP_IS_REGENERATION, PROP_IS_STREAMING, PROP_LATENCY_MS, PROP_LOCALE, PROP_MAX_OUTPUT_TOKENS, PROP_MESSAGE_ID, PROP_MESSAGE_LABELS, PROP_MESSAGE_LABEL_MAP, PROP_MODEL_NAME, PROP_MODEL_TIER, PROP_OUTPUT_STATE, PROP_OUTPUT_TOKENS, PROP_PARENT_AGENT_ID, PROP_PARENT_MESSAGE_ID, PROP_PARENT_SPAN_ID, PROP_PROMPT_ID, PROP_PROVIDER, PROP_QUALITY_SCORE, PROP_REASONING_CONTENT, PROP_REASONING_TOKENS, PROP_REQUEST_COMPLEXITY, PROP_ROOT_AGENT_NAME, PROP_RUNTIME, PROP_SCORE_NAME, PROP_SCORE_VALUE, PROP_SDK_VERSION, PROP_SENTIMENT_SCORE, PROP_SESSION_ID, PROP_SESSION_REPLAY_ID, PROP_SPAN_ID, PROP_SPAN_KIND, PROP_SPAN_NAME, PROP_SYSTEM_PROMPT, PROP_SYSTEM_PROMPT_LENGTH, PROP_TARGET_ID, PROP_TARGET_TYPE, PROP_TASK_FAILURE_REASON, PROP_TASK_FAILURE_TYPE, PROP_TEMPERATURE, PROP_TOOL_CALLS, PROP_TOOL_INPUT, PROP_TOOL_NAME, PROP_TOOL_OUTPUT, PROP_TOOL_SUCCESS, PROP_TOP_P, PROP_TOTAL_ATTACHMENT_SIZE, PROP_TOTAL_TOKENS, PROP_TRACE_ID, PROP_TTFB_MS, PROP_TURN_ID, PROP_WAS_CACHED, PROP_WAS_COPIED, PrivacyConfig, ProviderError, RubricScore, SDK_RUNTIME, SDK_VERSION, Session, SessionContext, SessionEnrichments, StreamingAccumulator, TIER_FAST, TIER_REASONING, TIER_STANDARD, TenantHandle, ToolCallTracker, TopicClassification, TrackingError, ValidationError, WrappedResponses, calculateCost, countMessageTokens, countTokens, createAmplitudeAIMiddleware, createAmplitudeCallback, createAmplitudeLlamaIndexHandler, estimateTokens, extractAnthropicContent, extractAnthropicSystemPrompt, extractBedrockResponse, extractContext, extractGeminiResponse, extractSystemPrompt, getActiveContext, getGenaiPriceLookupCandidates, inferModelTier, inferProvider, inferProviderFromModel, injectContext, observe, patch, patchAnthropic, patchAzureOpenAI, patchBedrock, patchGemini, patchMistral, patchOpenAI, patchedProviders, resolveAmplitude, runWithContext, runWithContextAsync, serializeToJsonString, stripProviderPrefix, tool, trackAiMessage, trackConversation, trackEmbedding, trackScore, trackSessionEnd, trackSessionEnrichment, trackSpan, trackToolCall, trackUserMessage, unpatch, unpatchAnthropic, unpatchAzureOpenAI, unpatchBedrock, unpatchGemini, unpatchMistral, unpatchOpenAI, wrap };
|
|
38
|
+
export { AIConfig, ANTHROPIC_AVAILABLE, OPENAI_AVAILABLE as AZURE_OPENAI_AVAILABLE, AmplitudeAI, AmplitudeAIError, AmplitudeAIWrapError, AmplitudeAgentExporter, AmplitudeCallbackHandler, AmplitudeCrewAIHooks, AmplitudeGenAIExporter, AmplitudeLlamaIndexHandler, AmplitudeSpanExporter, AmplitudeToolLoop, AmplitudeTracingProcessor, Anthropic, AzureOpenAI, BEDROCK_AVAILABLE, Bedrock, BoundAgent, ConfigurationError, ContentMode, EVENT_AI_RESPONSE, EVENT_EMBEDDING, EVENT_SCORE, EVENT_SESSION_END, EVENT_SESSION_ENRICHMENT, EVENT_SPAN, EVENT_TOOL_CALL, EVENT_USER_MESSAGE, EvidenceQuote, GEMINI_AVAILABLE, GENERATED_FILES, Gemini, MAX_SERIALIZED_LENGTH, MCP_PROMPTS, MCP_RESOURCES, MCP_SERVER_NAME, MCP_TOOLS, MISTRAL_AVAILABLE, MessageLabel, Mistral, MockAmplitudeAI, OPENAI_AVAILABLE, OpenAI, PROP_ABANDONMENT_TURN, PROP_AGENT_CHAIN, PROP_AGENT_ID, PROP_AGENT_VERSION, PROP_ATTACHMENTS, PROP_ATTACHMENT_COUNT, PROP_ATTACHMENT_TYPES, PROP_CACHE_CREATION_TOKENS, PROP_CACHE_READ_TOKENS, PROP_COMMENT, PROP_COMPONENT_TYPE, PROP_CONTEXT, PROP_COST_USD, PROP_CUSTOMER_ORG_ID, PROP_EDITED_MESSAGE_ID, PROP_EMBEDDING_DIMENSIONS, PROP_ENRICHMENTS, PROP_ENV, PROP_ERROR_MESSAGE, PROP_EVALUATION_SOURCE, PROP_FINISH_REASON, PROP_HAS_ATTACHMENTS, PROP_HAS_REASONING, PROP_IDLE_TIMEOUT_MINUTES, PROP_INPUT_STATE, PROP_INPUT_TOKENS, PROP_INVOCATION_ID, PROP_IS_EDIT, PROP_IS_ERROR, PROP_IS_REGENERATION, PROP_IS_STREAMING, PROP_LATENCY_MS, PROP_LOCALE, PROP_MAX_OUTPUT_TOKENS, PROP_MESSAGE_ID, PROP_MESSAGE_LABELS, PROP_MESSAGE_LABEL_MAP, PROP_MODEL_NAME, PROP_MODEL_TIER, PROP_OUTPUT_STATE, PROP_OUTPUT_TOKENS, PROP_PARENT_AGENT_ID, PROP_PARENT_MESSAGE_ID, PROP_PARENT_SPAN_ID, PROP_PROMPT_ID, PROP_PROVIDER, PROP_QUALITY_SCORE, PROP_REASONING_CONTENT, PROP_REASONING_TOKENS, PROP_REQUEST_COMPLEXITY, PROP_ROOT_AGENT_NAME, PROP_RUNTIME, PROP_SCORE_NAME, PROP_SCORE_VALUE, PROP_SDK_VERSION, PROP_SENTIMENT_SCORE, PROP_SESSION_ID, PROP_SESSION_REPLAY_ID, PROP_SPAN_ID, PROP_SPAN_KIND, PROP_SPAN_NAME, PROP_SYSTEM_PROMPT, PROP_SYSTEM_PROMPT_LENGTH, PROP_TARGET_ID, PROP_TARGET_TYPE, PROP_TASK_FAILURE_REASON, PROP_TASK_FAILURE_TYPE, PROP_TEMPERATURE, PROP_TOOL_CALLS, PROP_TOOL_INPUT, PROP_TOOL_NAME, PROP_TOOL_OUTPUT, PROP_TOOL_SUCCESS, PROP_TOP_P, PROP_TOTAL_ATTACHMENT_SIZE, PROP_TOTAL_TOKENS, PROP_TRACE_ID, PROP_TTFB_MS, PROP_TURN_ID, PROP_WAS_CACHED, PROP_WAS_COPIED, PrivacyConfig, ProviderError, RubricScore, SDK_RUNTIME, SDK_VERSION, Session, SessionContext, SessionEnrichments, StreamingAccumulator, TIER_FAST, TIER_REASONING, TIER_STANDARD, TenantHandle, ToolCallTracker, TopicClassification, TrackingError, ValidationError, WrappedResponses, calculateCost, countMessageTokens, countTokens, createAmplitudeAIMiddleware, createAmplitudeCallback, createAmplitudeLlamaIndexHandler, enableLivePriceUpdates, estimateTokens, extractAnthropicContent, extractAnthropicSystemPrompt, extractBedrockResponse, extractContext, extractGeminiResponse, extractSystemPrompt, getActiveContext, getGenaiPriceLookupCandidates, inferModelTier, inferProvider, inferProviderFromModel, injectContext, observe, patch, patchAnthropic, patchAzureOpenAI, patchBedrock, patchGemini, patchMistral, patchOpenAI, patchedProviders, resolveAmplitude, runWithContext, runWithContextAsync, serializeToJsonString, stripProviderPrefix, tool, trackAiMessage, trackConversation, trackEmbedding, trackScore, trackSessionEnd, trackSessionEnrichment, trackSpan, trackToolCall, trackUserMessage, unpatch, unpatchAnthropic, unpatchAzureOpenAI, unpatchBedrock, unpatchGemini, unpatchMistral, unpatchOpenAI, wrap };
|
|
@@ -73,7 +73,8 @@ var AmplitudeToolLoop = class {
|
|
|
73
73
|
inputTokens: normalizedInput,
|
|
74
74
|
outputTokens: usage.output_tokens,
|
|
75
75
|
cacheReadInputTokens: cacheRead,
|
|
76
|
-
cacheCreationInputTokens: cacheCreation
|
|
76
|
+
cacheCreationInputTokens: cacheCreation,
|
|
77
|
+
defaultProvider: "anthropic"
|
|
77
78
|
});
|
|
78
79
|
if (cost > 0) costUsd = cost;
|
|
79
80
|
} catch {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-tools.js","names":["allResponses: Array<Record<string, unknown>>","costUsd: number | undefined","toolResults: Array<Record<string, unknown>>"],"sources":["../../src/integrations/anthropic-tools.ts"],"sourcesContent":["/**\n * Anthropic tool loop integration.\n *\n * Runs Anthropic's multi-turn tool_use loop and tracks each turn.\n */\n\nimport type { AmplitudeAI } from '../client.js';\nimport { getActiveContext } from '../context.js';\nimport { calculateCost } from '../utils/costs.js';\n\nexport interface ToolLoopOptions {\n amplitudeAI: AmplitudeAI;\n userId?: string;\n sessionId?: string;\n agentId?: string;\n env?: string;\n maxTurns?: number;\n}\n\nexport class AmplitudeToolLoop {\n private _ai: AmplitudeAI;\n private _userId: string | null;\n private _sessionId: string | null;\n private _agentId: string | null;\n private _env: string | null;\n private _maxTurns: number;\n\n constructor(options: ToolLoopOptions) {\n this._ai = options.amplitudeAI;\n this._userId = options.userId ?? null;\n this._sessionId = options.sessionId ?? null;\n this._agentId = options.agentId ?? null;\n this._env = options.env ?? null;\n this._maxTurns = options.maxTurns ?? 10;\n }\n\n /**\n * Run a tool loop with the Anthropic API.\n *\n * This method orchestrates multi-turn tool_use conversations,\n * tracking each AI response and tool call along the way.\n */\n async run(options: {\n client: unknown;\n model: string;\n messages: Array<Record<string, unknown>>;\n tools: Array<Record<string, unknown>>;\n system?: string;\n toolExecutor: (\n name: string,\n input: Record<string, unknown>,\n ) => Promise<unknown>;\n }): Promise<Array<Record<string, unknown>>> {\n const ctx = getActiveContext();\n const userId = this._userId ?? ctx?.userId ?? 'unknown';\n const sessionId = this._sessionId ?? ctx?.sessionId ?? 'tool-loop-session';\n const agentId = this._agentId ?? ctx?.agentId ?? undefined;\n const env = this._env ?? ctx?.env ?? undefined;\n\n const messages = [...options.messages];\n const allResponses: Array<Record<string, unknown>> = [];\n let currentTurnId = 1;\n\n for (const msg of messages) {\n const userText = _extractUserText(msg);\n if (msg.role === 'user' && userText.length > 0) {\n this._ai.trackUserMessage({\n userId,\n content: userText,\n sessionId,\n agentId,\n env,\n turnId: currentTurnId,\n });\n currentTurnId += 1;\n }\n }\n\n for (let turn = 0; turn < this._maxTurns; turn++) {\n const clientObj = options.client as Record<string, unknown>;\n const messagesApi = clientObj.messages as Record<string, unknown>;\n const createFn = messagesApi.create as (\n ...args: unknown[]\n ) => Promise<unknown>;\n\n const startTime = performance.now();\n const response = (await createFn.call(messagesApi, {\n model: options.model,\n messages,\n tools: options.tools,\n system: options.system,\n })) as Record<string, unknown>;\n\n const latencyMs = performance.now() - startTime;\n allResponses.push(response);\n\n const content = _normalizeContentBlocks(response.content);\n const responseText = _extractAssistantText(content);\n const toolUseBlocks = content.filter((b) => b.type === 'tool_use');\n const usage = response.usage as Record<string, number> | undefined;\n\n const cacheRead = usage?.cache_read_input_tokens ?? 0;\n const cacheCreation = usage?.cache_creation_input_tokens ?? 0;\n const rawInput = usage?.input_tokens ?? 0;\n const normalizedInput =\n cacheRead || cacheCreation\n ? rawInput + cacheRead + cacheCreation\n : rawInput;\n\n let costUsd: number | undefined;\n if (usage?.input_tokens != null && usage?.output_tokens != null) {\n try {\n const cost = calculateCost({\n modelName: options.model,\n inputTokens: normalizedInput,\n outputTokens: usage.output_tokens,\n cacheReadInputTokens: cacheRead,\n cacheCreationInputTokens: cacheCreation,\n });\n if (cost > 0) costUsd = cost;\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._ai.trackAiMessage({\n userId,\n content: responseText,\n sessionId,\n model: options.model,\n provider: 'anthropic',\n latencyMs,\n turnId: currentTurnId,\n agentId,\n env,\n inputTokens: normalizedInput || undefined,\n outputTokens: usage?.output_tokens,\n cacheReadTokens: cacheRead || undefined,\n cacheCreationTokens: cacheCreation || undefined,\n totalCostUsd: costUsd,\n });\n currentTurnId += 1;\n\n if (response.stop_reason !== 'tool_use' || toolUseBlocks.length === 0) {\n break;\n }\n\n messages.push({ role: 'assistant', content });\n\n const toolResults: Array<Record<string, unknown>> = [];\n for (const toolUse of toolUseBlocks) {\n const toolName = String(toolUse.name);\n const toolInput = toolUse.input as Record<string, unknown>;\n const toolStartTime = performance.now();\n\n try {\n const output = await options.toolExecutor(toolName, toolInput);\n const toolLatencyMs = performance.now() - toolStartTime;\n\n this._ai.trackToolCall({\n userId,\n toolName,\n latencyMs: toolLatencyMs,\n success: true,\n sessionId,\n agentId,\n env,\n input: toolInput,\n output: output == null ? undefined : String(output),\n });\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolUse.id,\n content: output == null ? '' : String(output),\n });\n } catch (error) {\n const toolLatencyMs = performance.now() - toolStartTime;\n\n this._ai.trackToolCall({\n userId,\n toolName,\n latencyMs: toolLatencyMs,\n success: false,\n sessionId,\n agentId,\n env,\n input: toolInput,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n });\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolUse.id,\n content: `Error: ${error instanceof Error ? error.message : String(error)}`,\n is_error: true,\n });\n }\n }\n\n messages.push({ role: 'user', content: toolResults });\n }\n\n return allResponses;\n }\n}\n\nfunction _extractUserText(msg: Record<string, unknown>): string {\n if (typeof msg.content === 'string') return msg.content;\n if (!Array.isArray(msg.content)) return '';\n return msg.content\n .map((block) => {\n if (typeof block === 'string') return block;\n const item = block as Record<string, unknown>;\n return typeof item.text === 'string' ? item.text : '';\n })\n .join('');\n}\n\nfunction _extractAssistantText(\n content: Array<Record<string, unknown>> | undefined,\n): string {\n if (!Array.isArray(content)) return '';\n return content\n .filter((b) => b.type === 'text')\n .map((b) => String(b.text ?? ''))\n .join('');\n}\n\nfunction _normalizeContentBlocks(\n value: unknown,\n): Array<Record<string, unknown>> {\n if (!Array.isArray(value)) return [];\n return value.filter((v) => v != null && typeof v === 'object') as Array<\n Record<string, unknown>\n >;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"anthropic-tools.js","names":["allResponses: Array<Record<string, unknown>>","costUsd: number | undefined","toolResults: Array<Record<string, unknown>>"],"sources":["../../src/integrations/anthropic-tools.ts"],"sourcesContent":["/**\n * Anthropic tool loop integration.\n *\n * Runs Anthropic's multi-turn tool_use loop and tracks each turn.\n */\n\nimport type { AmplitudeAI } from '../client.js';\nimport { getActiveContext } from '../context.js';\nimport { calculateCost } from '../utils/costs.js';\n\nexport interface ToolLoopOptions {\n amplitudeAI: AmplitudeAI;\n userId?: string;\n sessionId?: string;\n agentId?: string;\n env?: string;\n maxTurns?: number;\n}\n\nexport class AmplitudeToolLoop {\n private _ai: AmplitudeAI;\n private _userId: string | null;\n private _sessionId: string | null;\n private _agentId: string | null;\n private _env: string | null;\n private _maxTurns: number;\n\n constructor(options: ToolLoopOptions) {\n this._ai = options.amplitudeAI;\n this._userId = options.userId ?? null;\n this._sessionId = options.sessionId ?? null;\n this._agentId = options.agentId ?? null;\n this._env = options.env ?? null;\n this._maxTurns = options.maxTurns ?? 10;\n }\n\n /**\n * Run a tool loop with the Anthropic API.\n *\n * This method orchestrates multi-turn tool_use conversations,\n * tracking each AI response and tool call along the way.\n */\n async run(options: {\n client: unknown;\n model: string;\n messages: Array<Record<string, unknown>>;\n tools: Array<Record<string, unknown>>;\n system?: string;\n toolExecutor: (\n name: string,\n input: Record<string, unknown>,\n ) => Promise<unknown>;\n }): Promise<Array<Record<string, unknown>>> {\n const ctx = getActiveContext();\n const userId = this._userId ?? ctx?.userId ?? 'unknown';\n const sessionId = this._sessionId ?? ctx?.sessionId ?? 'tool-loop-session';\n const agentId = this._agentId ?? ctx?.agentId ?? undefined;\n const env = this._env ?? ctx?.env ?? undefined;\n\n const messages = [...options.messages];\n const allResponses: Array<Record<string, unknown>> = [];\n let currentTurnId = 1;\n\n for (const msg of messages) {\n const userText = _extractUserText(msg);\n if (msg.role === 'user' && userText.length > 0) {\n this._ai.trackUserMessage({\n userId,\n content: userText,\n sessionId,\n agentId,\n env,\n turnId: currentTurnId,\n });\n currentTurnId += 1;\n }\n }\n\n for (let turn = 0; turn < this._maxTurns; turn++) {\n const clientObj = options.client as Record<string, unknown>;\n const messagesApi = clientObj.messages as Record<string, unknown>;\n const createFn = messagesApi.create as (\n ...args: unknown[]\n ) => Promise<unknown>;\n\n const startTime = performance.now();\n const response = (await createFn.call(messagesApi, {\n model: options.model,\n messages,\n tools: options.tools,\n system: options.system,\n })) as Record<string, unknown>;\n\n const latencyMs = performance.now() - startTime;\n allResponses.push(response);\n\n const content = _normalizeContentBlocks(response.content);\n const responseText = _extractAssistantText(content);\n const toolUseBlocks = content.filter((b) => b.type === 'tool_use');\n const usage = response.usage as Record<string, number> | undefined;\n\n const cacheRead = usage?.cache_read_input_tokens ?? 0;\n const cacheCreation = usage?.cache_creation_input_tokens ?? 0;\n const rawInput = usage?.input_tokens ?? 0;\n const normalizedInput =\n cacheRead || cacheCreation\n ? rawInput + cacheRead + cacheCreation\n : rawInput;\n\n let costUsd: number | undefined;\n if (usage?.input_tokens != null && usage?.output_tokens != null) {\n try {\n const cost = calculateCost({\n modelName: options.model,\n inputTokens: normalizedInput,\n outputTokens: usage.output_tokens,\n cacheReadInputTokens: cacheRead,\n cacheCreationInputTokens: cacheCreation,\n defaultProvider: 'anthropic',\n });\n if (cost > 0) costUsd = cost;\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._ai.trackAiMessage({\n userId,\n content: responseText,\n sessionId,\n model: options.model,\n provider: 'anthropic',\n latencyMs,\n turnId: currentTurnId,\n agentId,\n env,\n inputTokens: normalizedInput || undefined,\n outputTokens: usage?.output_tokens,\n cacheReadTokens: cacheRead || undefined,\n cacheCreationTokens: cacheCreation || undefined,\n totalCostUsd: costUsd,\n });\n currentTurnId += 1;\n\n if (response.stop_reason !== 'tool_use' || toolUseBlocks.length === 0) {\n break;\n }\n\n messages.push({ role: 'assistant', content });\n\n const toolResults: Array<Record<string, unknown>> = [];\n for (const toolUse of toolUseBlocks) {\n const toolName = String(toolUse.name);\n const toolInput = toolUse.input as Record<string, unknown>;\n const toolStartTime = performance.now();\n\n try {\n const output = await options.toolExecutor(toolName, toolInput);\n const toolLatencyMs = performance.now() - toolStartTime;\n\n this._ai.trackToolCall({\n userId,\n toolName,\n latencyMs: toolLatencyMs,\n success: true,\n sessionId,\n agentId,\n env,\n input: toolInput,\n output: output == null ? undefined : String(output),\n });\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolUse.id,\n content: output == null ? '' : String(output),\n });\n } catch (error) {\n const toolLatencyMs = performance.now() - toolStartTime;\n\n this._ai.trackToolCall({\n userId,\n toolName,\n latencyMs: toolLatencyMs,\n success: false,\n sessionId,\n agentId,\n env,\n input: toolInput,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n });\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolUse.id,\n content: `Error: ${error instanceof Error ? error.message : String(error)}`,\n is_error: true,\n });\n }\n }\n\n messages.push({ role: 'user', content: toolResults });\n }\n\n return allResponses;\n }\n}\n\nfunction _extractUserText(msg: Record<string, unknown>): string {\n if (typeof msg.content === 'string') return msg.content;\n if (!Array.isArray(msg.content)) return '';\n return msg.content\n .map((block) => {\n if (typeof block === 'string') return block;\n const item = block as Record<string, unknown>;\n return typeof item.text === 'string' ? item.text : '';\n })\n .join('');\n}\n\nfunction _extractAssistantText(\n content: Array<Record<string, unknown>> | undefined,\n): string {\n if (!Array.isArray(content)) return '';\n return content\n .filter((b) => b.type === 'text')\n .map((b) => String(b.text ?? ''))\n .join('');\n}\n\nfunction _normalizeContentBlocks(\n value: unknown,\n): Array<Record<string, unknown>> {\n if (!Array.isArray(value)) return [];\n return value.filter((v) => v != null && typeof v === 'object') as Array<\n Record<string, unknown>\n >;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"langchain.d.ts","names":[],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"langchain.d.ts","names":[],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":[],"mappings":";;;;;AAgGuB,UApFN,sBAAA,CAoFM;EAiEP,WAAA,EApJD,WAoJC;EAAM,MAAA,CAAA,EAAA,MAAA;EAoFN,SAAA,CAAA,EAAA,MAAA;;;kBAnOE;;cAGL,wBAAA;;;;;;;;;;;uBAYU;;6BAqBP;uBA0CO;8BAiEP;;;;;iBAoFA,uBAAA,UACL,yBACR"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getActiveContext } from "../context.js";
|
|
2
|
-
import { calculateCost } from "../utils/costs.js";
|
|
2
|
+
import { calculateCost, inferProvider } from "../utils/costs.js";
|
|
3
3
|
|
|
4
4
|
//#region src/integrations/langchain.ts
|
|
5
5
|
var AmplitudeCallbackHandler = class {
|
|
@@ -34,7 +34,7 @@ var AmplitudeCallbackHandler = class {
|
|
|
34
34
|
handleLLMStart(serialized, prompts, runId) {
|
|
35
35
|
this._runStartTimes.set(runId, performance.now());
|
|
36
36
|
const kwargs = serialized.kwargs;
|
|
37
|
-
const idModel = Array.isArray(serialized.id) ? serialized.id.find((v) => typeof v === "string" && (v
|
|
37
|
+
const idModel = Array.isArray(serialized.id) ? serialized.id.find((v) => typeof v === "string" && (/\d/.test(v) || v.includes("."))) : void 0;
|
|
38
38
|
const modelName = String(kwargs?.model ?? kwargs?.modelName ?? kwargs?.model_name ?? idModel ?? "");
|
|
39
39
|
if (modelName) this._runModelNames.set(runId, modelName);
|
|
40
40
|
const trackUserMessage = this._ai.trackUserMessage;
|
|
@@ -65,14 +65,16 @@ var AmplitudeCallbackHandler = class {
|
|
|
65
65
|
this._runModelNames.delete(runId);
|
|
66
66
|
const ctx = this._getContext();
|
|
67
67
|
const modelName = String(llmOutput?.modelName ?? modelFromStart ?? "unknown");
|
|
68
|
-
const inputTokens
|
|
69
|
-
const outputTokens = _safeNumber(usage?.completionTokens ?? usage?.completion_tokens ?? usage?.output_tokens);
|
|
68
|
+
const { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens } = _extractLangchainUsage(usage);
|
|
70
69
|
let costUsd;
|
|
71
70
|
if (modelName !== "unknown" && inputTokens != null && outputTokens != null) try {
|
|
72
71
|
const cost = calculateCost({
|
|
73
72
|
modelName,
|
|
74
73
|
inputTokens,
|
|
75
|
-
outputTokens
|
|
74
|
+
outputTokens,
|
|
75
|
+
cacheReadInputTokens: cacheReadTokens,
|
|
76
|
+
cacheCreationInputTokens: cacheCreationTokens,
|
|
77
|
+
defaultProvider: inferProvider(modelName)
|
|
76
78
|
});
|
|
77
79
|
if (cost > 0) costUsd = cost;
|
|
78
80
|
} catch {}
|
|
@@ -169,6 +171,34 @@ function createAmplitudeCallback(options) {
|
|
|
169
171
|
function _safeNumber(value) {
|
|
170
172
|
return typeof value === "number" ? value : void 0;
|
|
171
173
|
}
|
|
174
|
+
function _extractLangchainUsage(usage) {
|
|
175
|
+
if (!usage) return {
|
|
176
|
+
inputTokens: void 0,
|
|
177
|
+
outputTokens: void 0,
|
|
178
|
+
cacheReadTokens: 0,
|
|
179
|
+
cacheCreationTokens: 0
|
|
180
|
+
};
|
|
181
|
+
const outputTokens = _safeNumber(usage.completionTokens ?? usage.completion_tokens ?? usage.output_tokens);
|
|
182
|
+
const promptTokens = _safeNumber(usage.promptTokens ?? usage.prompt_tokens);
|
|
183
|
+
if (promptTokens != null) {
|
|
184
|
+
const details = usage.prompt_tokens_details;
|
|
185
|
+
return {
|
|
186
|
+
inputTokens: promptTokens,
|
|
187
|
+
outputTokens,
|
|
188
|
+
cacheReadTokens: _safeNumber(details?.cached_tokens ?? details?.cachedTokens) ?? 0,
|
|
189
|
+
cacheCreationTokens: 0
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const rawInput = _safeNumber(usage.input_tokens);
|
|
193
|
+
const cacheRead = _safeNumber(usage.cache_read_input_tokens) ?? 0;
|
|
194
|
+
const cacheCreation = _safeNumber(usage.cache_creation_input_tokens) ?? 0;
|
|
195
|
+
return {
|
|
196
|
+
inputTokens: rawInput != null ? rawInput + cacheRead + cacheCreation : void 0,
|
|
197
|
+
outputTokens,
|
|
198
|
+
cacheReadTokens: cacheRead,
|
|
199
|
+
cacheCreationTokens: cacheCreation
|
|
200
|
+
};
|
|
201
|
+
}
|
|
172
202
|
function _extractLangchainText(generation) {
|
|
173
203
|
if (generation == null || typeof generation !== "object") return "";
|
|
174
204
|
const gen = generation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"langchain.js","names":["costUsd: number | undefined"],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":["/**\n * LangChain integration — AmplitudeCallbackHandler.\n *\n * Tracks LLM calls, tool calls, and chain events via LangChain's\n * callback system.\n */\n\nimport type { AmplitudeAI } from '../client.js';\nimport { getActiveContext } from '../context.js';\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport { calculateCost } from '../utils/costs.js';\n\nexport interface CallbackHandlerOptions {\n amplitudeAI: AmplitudeAI;\n userId?: string;\n sessionId?: string;\n agentId?: string;\n env?: string;\n privacyConfig?: PrivacyConfig | null;\n}\n\nexport class AmplitudeCallbackHandler {\n private _ai: AmplitudeAI;\n private _userId: string | null;\n private _sessionId: string | null;\n private _agentId: string | null;\n private _env: string | null;\n private _privacyConfig: PrivacyConfig | null;\n private _runStartTimes: Map<string, number> = new Map();\n private _runModelNames: Map<string, string> = new Map();\n private _toolInputs: Map<string, unknown> = new Map();\n private _toolNames: Map<string, string> = new Map();\n\n constructor(options: CallbackHandlerOptions) {\n this._ai = options.amplitudeAI;\n this._userId = options.userId ?? null;\n this._sessionId = options.sessionId ?? null;\n this._agentId = options.agentId ?? null;\n this._env = options.env ?? null;\n this._privacyConfig = options.privacyConfig ?? null;\n }\n\n private _getContext() {\n const ctx = getActiveContext();\n return {\n userId: this._userId ?? ctx?.userId ?? 'unknown',\n sessionId: this._sessionId ?? ctx?.sessionId ?? undefined,\n agentId: this._agentId ?? ctx?.agentId ?? undefined,\n env: this._env ?? ctx?.env ?? undefined,\n traceId: ctx?.traceId ?? undefined,\n };\n }\n\n handleLLMStart(\n serialized: Record<string, unknown>,\n prompts: string[],\n runId: string,\n ): void {\n this._runStartTimes.set(runId, performance.now());\n const kwargs = serialized.kwargs as Record<string, unknown> | undefined;\n const idModel = Array.isArray(serialized.id)\n ? serialized.id.find(\n (v) =>\n typeof v === 'string' &&\n (v.includes('gpt') || v.includes('claude') || v.includes('gemini')),\n )\n : undefined;\n const modelName = String(\n kwargs?.model ?? kwargs?.modelName ?? kwargs?.model_name ?? idModel ?? '',\n );\n if (modelName) this._runModelNames.set(runId, modelName);\n\n const trackUserMessage = (\n this._ai as unknown as {\n trackUserMessage?: (opts: Record<string, unknown>) => void;\n }\n ).trackUserMessage;\n if (typeof trackUserMessage === 'function') {\n const ctx = this._getContext();\n for (const prompt of prompts) {\n if (!prompt) continue;\n trackUserMessage({\n userId: ctx.userId,\n content: prompt,\n sessionId: ctx.sessionId ?? 'langchain-session',\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n });\n }\n }\n }\n\n handleLLMEnd(output: Record<string, unknown>, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n\n const generations = output.generations as\n | Array<Array<Record<string, unknown>>>\n | undefined;\n const firstGen = generations?.[0]?.[0];\n const content = _extractLangchainText(firstGen);\n const llmOutput = output.llmOutput as Record<string, unknown> | undefined;\n const usage =\n (llmOutput?.tokenUsage as Record<string, unknown> | undefined) ??\n (llmOutput?.usage as Record<string, unknown> | undefined) ??\n (llmOutput?.usage_metadata as Record<string, unknown> | undefined);\n const modelFromStart = this._runModelNames.get(runId);\n this._runModelNames.delete(runId);\n\n const ctx = this._getContext();\n const modelName = String(\n llmOutput?.modelName ?? modelFromStart ?? 'unknown',\n );\n const inputTokens = _safeNumber(\n usage?.promptTokens ?? usage?.prompt_tokens ?? usage?.input_tokens,\n );\n const outputTokens = _safeNumber(\n usage?.completionTokens ??\n usage?.completion_tokens ??\n usage?.output_tokens,\n );\n\n let costUsd: number | undefined;\n if (\n modelName !== 'unknown' &&\n inputTokens != null &&\n outputTokens != null\n ) {\n try {\n const cost = calculateCost({ modelName, inputTokens, outputTokens });\n if (cost > 0) costUsd = cost;\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._ai.trackAiMessage({\n userId: ctx.userId,\n content,\n sessionId: ctx.sessionId ?? 'langchain-session',\n model: modelName,\n provider: 'langchain',\n latencyMs,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens,\n outputTokens,\n totalTokens: _safeNumber(usage?.totalTokens ?? usage?.total_tokens),\n totalCostUsd: costUsd,\n privacyConfig: this._privacyConfig,\n });\n }\n\n handleToolStart(\n serialized: Record<string, unknown>,\n input: string,\n runId: string,\n ): void {\n this._runStartTimes.set(runId, performance.now());\n this._toolInputs.set(runId, input);\n const name = String(\n serialized.name ??\n (serialized.id as string[] | undefined)?.slice(-1)[0] ??\n 'langchain-tool',\n );\n this._toolNames.set(runId, name);\n }\n\n handleToolEnd(output: string, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n const toolInput = this._toolInputs.get(runId);\n this._toolInputs.delete(runId);\n const toolName = this._toolNames.get(runId) ?? 'langchain-tool';\n this._toolNames.delete(runId);\n\n const ctx = this._getContext();\n this._ai.trackToolCall({\n userId: ctx.userId,\n toolName,\n latencyMs,\n success: true,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n input: toolInput,\n output,\n });\n }\n\n handleToolError(error: unknown, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n const toolInput = this._toolInputs.get(runId);\n this._toolInputs.delete(runId);\n const toolName = this._toolNames.get(runId) ?? 'langchain-tool';\n this._toolNames.delete(runId);\n\n const ctx = this._getContext();\n this._ai.trackToolCall({\n userId: ctx.userId,\n toolName,\n latencyMs,\n success: false,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n input: toolInput,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n }\n\n handleLLMError(error: unknown, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n\n const ctx = this._getContext();\n this._ai.trackAiMessage({\n userId: ctx.userId,\n content: '',\n sessionId: ctx.sessionId ?? 'langchain-session',\n model: 'unknown',\n provider: 'langchain',\n latencyMs,\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}\n\nexport function createAmplitudeCallback(\n options: CallbackHandlerOptions,\n): AmplitudeCallbackHandler {\n return new AmplitudeCallbackHandler(options);\n}\n\nfunction _safeNumber(value: unknown): number | undefined {\n return typeof value === 'number' ? value : undefined;\n}\n\nfunction _extractLangchainText(generation: unknown): string {\n if (generation == null || typeof generation !== 'object') return '';\n const gen = generation as Record<string, unknown>;\n if (typeof gen.text === 'string') return gen.text;\n const message = gen.message as Record<string, unknown> | undefined;\n if (message == null) return '';\n if (typeof message.content === 'string') return message.content;\n if (!Array.isArray(message.content)) return '';\n return message.content\n .map((part) => {\n if (typeof part === 'string') return part;\n const item = part as Record<string, unknown>;\n return typeof item.text === 'string' ? item.text : '';\n })\n .join('');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"langchain.js","names":["costUsd: number | undefined"],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":["/**\n * LangChain integration — AmplitudeCallbackHandler.\n *\n * Tracks LLM calls, tool calls, and chain events via LangChain's\n * callback system.\n */\n\nimport type { AmplitudeAI } from '../client.js';\nimport { getActiveContext } from '../context.js';\nimport type { PrivacyConfig } from '../core/privacy.js';\nimport { calculateCost, inferProvider } from '../utils/costs.js';\n\nexport interface CallbackHandlerOptions {\n amplitudeAI: AmplitudeAI;\n userId?: string;\n sessionId?: string;\n agentId?: string;\n env?: string;\n privacyConfig?: PrivacyConfig | null;\n}\n\nexport class AmplitudeCallbackHandler {\n private _ai: AmplitudeAI;\n private _userId: string | null;\n private _sessionId: string | null;\n private _agentId: string | null;\n private _env: string | null;\n private _privacyConfig: PrivacyConfig | null;\n private _runStartTimes: Map<string, number> = new Map();\n private _runModelNames: Map<string, string> = new Map();\n private _toolInputs: Map<string, unknown> = new Map();\n private _toolNames: Map<string, string> = new Map();\n\n constructor(options: CallbackHandlerOptions) {\n this._ai = options.amplitudeAI;\n this._userId = options.userId ?? null;\n this._sessionId = options.sessionId ?? null;\n this._agentId = options.agentId ?? null;\n this._env = options.env ?? null;\n this._privacyConfig = options.privacyConfig ?? null;\n }\n\n private _getContext() {\n const ctx = getActiveContext();\n return {\n userId: this._userId ?? ctx?.userId ?? 'unknown',\n sessionId: this._sessionId ?? ctx?.sessionId ?? undefined,\n agentId: this._agentId ?? ctx?.agentId ?? undefined,\n env: this._env ?? ctx?.env ?? undefined,\n traceId: ctx?.traceId ?? undefined,\n };\n }\n\n handleLLMStart(\n serialized: Record<string, unknown>,\n prompts: string[],\n runId: string,\n ): void {\n this._runStartTimes.set(runId, performance.now());\n const kwargs = serialized.kwargs as Record<string, unknown> | undefined;\n const idModel = Array.isArray(serialized.id)\n ? serialized.id.find(\n (v) =>\n typeof v === 'string' &&\n // Accept any id segment that looks like a model name: contains a\n // digit (version) or a dot (vendor.model). Avoids hardcoding\n // specific model families that would need updating over time.\n (/\\d/.test(v) || v.includes('.')),\n )\n : undefined;\n const modelName = String(\n kwargs?.model ?? kwargs?.modelName ?? kwargs?.model_name ?? idModel ?? '',\n );\n if (modelName) this._runModelNames.set(runId, modelName);\n\n const trackUserMessage = (\n this._ai as unknown as {\n trackUserMessage?: (opts: Record<string, unknown>) => void;\n }\n ).trackUserMessage;\n if (typeof trackUserMessage === 'function') {\n const ctx = this._getContext();\n for (const prompt of prompts) {\n if (!prompt) continue;\n trackUserMessage({\n userId: ctx.userId,\n content: prompt,\n sessionId: ctx.sessionId ?? 'langchain-session',\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n });\n }\n }\n }\n\n handleLLMEnd(output: Record<string, unknown>, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n\n const generations = output.generations as\n | Array<Array<Record<string, unknown>>>\n | undefined;\n const firstGen = generations?.[0]?.[0];\n const content = _extractLangchainText(firstGen);\n const llmOutput = output.llmOutput as Record<string, unknown> | undefined;\n const usage =\n (llmOutput?.tokenUsage as Record<string, unknown> | undefined) ??\n (llmOutput?.usage as Record<string, unknown> | undefined) ??\n (llmOutput?.usage_metadata as Record<string, unknown> | undefined);\n const modelFromStart = this._runModelNames.get(runId);\n this._runModelNames.delete(runId);\n\n const ctx = this._getContext();\n const modelName = String(\n llmOutput?.modelName ?? modelFromStart ?? 'unknown',\n );\n const { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens } =\n _extractLangchainUsage(usage);\n\n let costUsd: number | undefined;\n if (\n modelName !== 'unknown' &&\n inputTokens != null &&\n outputTokens != null\n ) {\n try {\n const cost = calculateCost({\n modelName,\n inputTokens,\n outputTokens,\n cacheReadInputTokens: cacheReadTokens,\n cacheCreationInputTokens: cacheCreationTokens,\n defaultProvider: inferProvider(modelName),\n });\n if (cost > 0) costUsd = cost;\n } catch {\n // cost calculation is best-effort\n }\n }\n\n this._ai.trackAiMessage({\n userId: ctx.userId,\n content,\n sessionId: ctx.sessionId ?? 'langchain-session',\n model: modelName,\n provider: 'langchain',\n latencyMs,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n inputTokens,\n outputTokens,\n totalTokens: _safeNumber(usage?.totalTokens ?? usage?.total_tokens),\n totalCostUsd: costUsd,\n privacyConfig: this._privacyConfig,\n });\n }\n\n handleToolStart(\n serialized: Record<string, unknown>,\n input: string,\n runId: string,\n ): void {\n this._runStartTimes.set(runId, performance.now());\n this._toolInputs.set(runId, input);\n const name = String(\n serialized.name ??\n (serialized.id as string[] | undefined)?.slice(-1)[0] ??\n 'langchain-tool',\n );\n this._toolNames.set(runId, name);\n }\n\n handleToolEnd(output: string, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n const toolInput = this._toolInputs.get(runId);\n this._toolInputs.delete(runId);\n const toolName = this._toolNames.get(runId) ?? 'langchain-tool';\n this._toolNames.delete(runId);\n\n const ctx = this._getContext();\n this._ai.trackToolCall({\n userId: ctx.userId,\n toolName,\n latencyMs,\n success: true,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n input: toolInput,\n output,\n });\n }\n\n handleToolError(error: unknown, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n const toolInput = this._toolInputs.get(runId);\n this._toolInputs.delete(runId);\n const toolName = this._toolNames.get(runId) ?? 'langchain-tool';\n this._toolNames.delete(runId);\n\n const ctx = this._getContext();\n this._ai.trackToolCall({\n userId: ctx.userId,\n toolName,\n latencyMs,\n success: false,\n sessionId: ctx.sessionId,\n traceId: ctx.traceId,\n agentId: ctx.agentId,\n env: ctx.env,\n input: toolInput,\n errorMessage: error instanceof Error ? error.message : String(error),\n });\n }\n\n handleLLMError(error: unknown, runId: string): void {\n const startTime = this._runStartTimes.get(runId) ?? performance.now();\n this._runStartTimes.delete(runId);\n const latencyMs = performance.now() - startTime;\n\n const ctx = this._getContext();\n this._ai.trackAiMessage({\n userId: ctx.userId,\n content: '',\n sessionId: ctx.sessionId ?? 'langchain-session',\n model: 'unknown',\n provider: 'langchain',\n latencyMs,\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}\n\nexport function createAmplitudeCallback(\n options: CallbackHandlerOptions,\n): AmplitudeCallbackHandler {\n return new AmplitudeCallbackHandler(options);\n}\n\nfunction _safeNumber(value: unknown): number | undefined {\n return typeof value === 'number' ? value : undefined;\n}\n\nfunction _extractLangchainUsage(usage: Record<string, unknown> | undefined): {\n inputTokens: number | undefined;\n outputTokens: number | undefined;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n} {\n if (!usage) {\n return { inputTokens: undefined, outputTokens: undefined, cacheReadTokens: 0, cacheCreationTokens: 0 };\n }\n\n const outputTokens = _safeNumber(\n usage.completionTokens ?? usage.completion_tokens ?? usage.output_tokens,\n );\n\n // OpenAI format: promptTokens / prompt_tokens (already total, includes cached)\n const promptTokens = _safeNumber(usage.promptTokens ?? usage.prompt_tokens);\n if (promptTokens != null) {\n const details = usage.prompt_tokens_details as Record<string, unknown> | undefined;\n const cached = _safeNumber(details?.cached_tokens ?? details?.cachedTokens) ?? 0;\n return { inputTokens: promptTokens, outputTokens, cacheReadTokens: cached, cacheCreationTokens: 0 };\n }\n\n // Anthropic format: input_tokens is non-cached only; normalize to total\n const rawInput = _safeNumber(usage.input_tokens);\n const cacheRead = _safeNumber(usage.cache_read_input_tokens) ?? 0;\n const cacheCreation = _safeNumber(usage.cache_creation_input_tokens) ?? 0;\n const totalInput = rawInput != null ? rawInput + cacheRead + cacheCreation : undefined;\n return { inputTokens: totalInput, outputTokens, cacheReadTokens: cacheRead, cacheCreationTokens: cacheCreation };\n}\n\nfunction _extractLangchainText(generation: unknown): string {\n if (generation == null || typeof generation !== 'object') return '';\n const gen = generation as Record<string, unknown>;\n if (typeof gen.text === 'string') return gen.text;\n const message = gen.message as Record<string, unknown> | undefined;\n if (message == null) return '';\n if (typeof message.content === 'string') return message.content;\n if (!Array.isArray(message.content)) return '';\n return message.content\n .map((part) => {\n if (typeof part === 'string') return part;\n const item = part as Record<string, unknown>;\n return typeof item.text === 'string' ? item.text : '';\n })\n .join('');\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llamaindex.d.ts","names":[],"sources":["../../src/integrations/llamaindex.ts"],"sourcesContent":[],"mappings":";;;;UAWiB,wBAAA;eACF;;;;;;cAOF,0BAAA;;;;;;;uBAQU;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"llamaindex.d.ts","names":[],"sources":["../../src/integrations/llamaindex.ts"],"sourcesContent":[],"mappings":";;;;UAWiB,wBAAA;eACF;;;;;;cAOF,0BAAA;;;;;;;uBAQU;;;;;;;;;;;;;;;;;;;;;;iBAoIP,gCAAA,UACL,2BACR"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getActiveContext } from "../context.js";
|
|
2
|
-
import { calculateCost } from "../utils/costs.js";
|
|
2
|
+
import { calculateCost, inferProvider } from "../utils/costs.js";
|
|
3
3
|
|
|
4
4
|
//#region src/integrations/llamaindex.ts
|
|
5
5
|
var AmplitudeLlamaIndexHandler = class {
|
|
@@ -40,7 +40,10 @@ var AmplitudeLlamaIndexHandler = class {
|
|
|
40
40
|
const cost = calculateCost({
|
|
41
41
|
modelName: normalized.model,
|
|
42
42
|
inputTokens: normalized.inputTokens,
|
|
43
|
-
outputTokens: normalized.outputTokens
|
|
43
|
+
outputTokens: normalized.outputTokens,
|
|
44
|
+
cacheReadInputTokens: normalized.cacheReadTokens,
|
|
45
|
+
cacheCreationInputTokens: normalized.cacheCreationTokens,
|
|
46
|
+
defaultProvider: inferProvider(normalized.model)
|
|
44
47
|
});
|
|
45
48
|
if (cost > 0) costUsd = cost;
|
|
46
49
|
} catch {}
|
|
@@ -111,11 +114,31 @@ function _normalizeLlamaLlmResponse(response) {
|
|
|
111
114
|
const message = resp.message;
|
|
112
115
|
const content = (typeof resp.content === "string" ? resp.content : void 0) ?? (typeof message?.content === "string" ? message.content : "") ?? "";
|
|
113
116
|
const usage = resp.usage ?? {};
|
|
117
|
+
const outputTokens = _toNumber(resp.outputTokens ?? usage.output_tokens ?? usage.completion_tokens);
|
|
118
|
+
const promptTokens = _toNumber(usage.prompt_tokens);
|
|
119
|
+
if (promptTokens != null) {
|
|
120
|
+
const details = usage.prompt_tokens_details;
|
|
121
|
+
const cached = _toNumber(details?.cached_tokens) ?? 0;
|
|
122
|
+
return {
|
|
123
|
+
content,
|
|
124
|
+
model: String(resp.model ?? message?.model ?? "unknown"),
|
|
125
|
+
inputTokens: _toNumber(resp.inputTokens) ?? promptTokens,
|
|
126
|
+
outputTokens,
|
|
127
|
+
cacheReadTokens: cached,
|
|
128
|
+
cacheCreationTokens: 0
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const rawInput = _toNumber(usage.input_tokens);
|
|
132
|
+
const cacheRead = _toNumber(usage.cache_read_input_tokens) ?? 0;
|
|
133
|
+
const cacheCreation = _toNumber(usage.cache_creation_input_tokens) ?? 0;
|
|
134
|
+
const totalInput = rawInput != null && (cacheRead > 0 || cacheCreation > 0) ? rawInput + cacheRead + cacheCreation : _toNumber(resp.inputTokens) ?? rawInput;
|
|
114
135
|
return {
|
|
115
136
|
content,
|
|
116
137
|
model: String(resp.model ?? message?.model ?? "unknown"),
|
|
117
|
-
inputTokens:
|
|
118
|
-
outputTokens
|
|
138
|
+
inputTokens: totalInput,
|
|
139
|
+
outputTokens,
|
|
140
|
+
cacheReadTokens: cacheRead,
|
|
141
|
+
cacheCreationTokens: cacheCreation
|
|
119
142
|
};
|
|
120
143
|
}
|
|
121
144
|
function _normalizeLlamaEmbeddingResponse(response) {
|