@dexcost/sdk 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/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/adapters/_netbytes.d.ts +31 -0
- package/dist/adapters/_netbytes.d.ts.map +1 -0
- package/dist/adapters/_netbytes.js +154 -0
- package/dist/adapters/_netbytes.js.map +1 -0
- package/dist/adapters/aws-lambda.d.ts +41 -0
- package/dist/adapters/aws-lambda.d.ts.map +1 -0
- package/dist/adapters/aws-lambda.js +65 -0
- package/dist/adapters/aws-lambda.js.map +1 -0
- package/dist/adapters/browser.d.ts +52 -0
- package/dist/adapters/browser.d.ts.map +1 -0
- package/dist/adapters/browser.js +127 -0
- package/dist/adapters/browser.js.map +1 -0
- package/dist/adapters/compute-wrap.d.ts +33 -0
- package/dist/adapters/compute-wrap.d.ts.map +1 -0
- package/dist/adapters/compute-wrap.js +188 -0
- package/dist/adapters/compute-wrap.js.map +1 -0
- package/dist/adapters/data/aws_lambda_pricing.json +61 -0
- package/dist/adapters/gpu-wrap.d.ts +31 -0
- package/dist/adapters/gpu-wrap.d.ts.map +1 -0
- package/dist/adapters/gpu-wrap.js +147 -0
- package/dist/adapters/gpu-wrap.js.map +1 -0
- package/dist/adapters/http.d.ts +58 -0
- package/dist/adapters/http.d.ts.map +1 -0
- package/dist/adapters/http.js +769 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +12 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/network-accountant.d.ts +63 -0
- package/dist/adapters/network-accountant.d.ts.map +1 -0
- package/dist/adapters/network-accountant.js +153 -0
- package/dist/adapters/network-accountant.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +225 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/scanner.d.ts +39 -0
- package/dist/cli/scanner.d.ts.map +1 -0
- package/dist/cli/scanner.js +480 -0
- package/dist/cli/scanner.js.map +1 -0
- package/dist/clients.d.ts +54 -0
- package/dist/clients.d.ts.map +1 -0
- package/dist/clients.js +240 -0
- package/dist/clients.js.map +1 -0
- package/dist/cloud-detect.d.ts +96 -0
- package/dist/cloud-detect.d.ts.map +1 -0
- package/dist/cloud-detect.js +545 -0
- package/dist/cloud-detect.js.map +1 -0
- package/dist/core/auto-task.d.ts +20 -0
- package/dist/core/auto-task.d.ts.map +1 -0
- package/dist/core/auto-task.js +34 -0
- package/dist/core/auto-task.js.map +1 -0
- package/dist/core/cgroup-reader.d.ts +45 -0
- package/dist/core/cgroup-reader.d.ts.map +1 -0
- package/dist/core/cgroup-reader.js +124 -0
- package/dist/core/cgroup-reader.js.map +1 -0
- package/dist/core/cgroup-walker.d.ts +60 -0
- package/dist/core/cgroup-walker.d.ts.map +1 -0
- package/dist/core/cgroup-walker.js +166 -0
- package/dist/core/cgroup-walker.js.map +1 -0
- package/dist/core/compute-accountant.d.ts +51 -0
- package/dist/core/compute-accountant.d.ts.map +1 -0
- package/dist/core/compute-accountant.js +179 -0
- package/dist/core/compute-accountant.js.map +1 -0
- package/dist/core/compute-runtime.d.ts +42 -0
- package/dist/core/compute-runtime.d.ts.map +1 -0
- package/dist/core/compute-runtime.js +80 -0
- package/dist/core/compute-runtime.js.map +1 -0
- package/dist/core/config.d.ts +44 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +66 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +76 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +91 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/fargate-metadata.d.ts +27 -0
- package/dist/core/fargate-metadata.d.ts.map +1 -0
- package/dist/core/fargate-metadata.js +102 -0
- package/dist/core/fargate-metadata.js.map +1 -0
- package/dist/core/gpu-accountant.d.ts +104 -0
- package/dist/core/gpu-accountant.d.ts.map +1 -0
- package/dist/core/gpu-accountant.js +383 -0
- package/dist/core/gpu-accountant.js.map +1 -0
- package/dist/core/gpu-runtime.d.ts +58 -0
- package/dist/core/gpu-runtime.d.ts.map +1 -0
- package/dist/core/gpu-runtime.js +131 -0
- package/dist/core/gpu-runtime.js.map +1 -0
- package/dist/core/heuristics.d.ts +74 -0
- package/dist/core/heuristics.d.ts.map +1 -0
- package/dist/core/heuristics.js +182 -0
- package/dist/core/heuristics.js.map +1 -0
- package/dist/core/models.d.ts +149 -0
- package/dist/core/models.d.ts.map +1 -0
- package/dist/core/models.js +226 -0
- package/dist/core/models.js.map +1 -0
- package/dist/core/nvml-reader.d.ts +114 -0
- package/dist/core/nvml-reader.d.ts.map +1 -0
- package/dist/core/nvml-reader.js +323 -0
- package/dist/core/nvml-reader.js.map +1 -0
- package/dist/core/session.d.ts +48 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +123 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/tracker.d.ts +364 -0
- package/dist/core/tracker.d.ts.map +1 -0
- package/dist/core/tracker.js +1073 -0
- package/dist/core/tracker.js.map +1 -0
- package/dist/data/compute_prices.json +180 -0
- package/dist/data/egress_prices.json +418 -0
- package/dist/data/gpu_prices.json +412 -0
- package/dist/data/service_prices.json +2595 -0
- package/dist/dev-console.d.ts +12 -0
- package/dist/dev-console.d.ts.map +1 -0
- package/dist/dev-console.js +60 -0
- package/dist/dev-console.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/instruments/anthropic.d.ts +26 -0
- package/dist/instruments/anthropic.d.ts.map +1 -0
- package/dist/instruments/anthropic.js +242 -0
- package/dist/instruments/anthropic.js.map +1 -0
- package/dist/instruments/bedrock.d.ts +29 -0
- package/dist/instruments/bedrock.d.ts.map +1 -0
- package/dist/instruments/bedrock.js +215 -0
- package/dist/instruments/bedrock.js.map +1 -0
- package/dist/instruments/cohere.d.ts +29 -0
- package/dist/instruments/cohere.d.ts.map +1 -0
- package/dist/instruments/cohere.js +237 -0
- package/dist/instruments/cohere.js.map +1 -0
- package/dist/instruments/gemini.d.ts +30 -0
- package/dist/instruments/gemini.d.ts.map +1 -0
- package/dist/instruments/gemini.js +247 -0
- package/dist/instruments/gemini.js.map +1 -0
- package/dist/instruments/index.d.ts +35 -0
- package/dist/instruments/index.d.ts.map +1 -0
- package/dist/instruments/index.js +54 -0
- package/dist/instruments/index.js.map +1 -0
- package/dist/instruments/mcp.d.ts +24 -0
- package/dist/instruments/mcp.d.ts.map +1 -0
- package/dist/instruments/mcp.js +459 -0
- package/dist/instruments/mcp.js.map +1 -0
- package/dist/instruments/openai.d.ts +26 -0
- package/dist/instruments/openai.d.ts.map +1 -0
- package/dist/instruments/openai.js +221 -0
- package/dist/instruments/openai.js.map +1 -0
- package/dist/instruments/vercel-ai.d.ts +28 -0
- package/dist/instruments/vercel-ai.d.ts.map +1 -0
- package/dist/instruments/vercel-ai.js +192 -0
- package/dist/instruments/vercel-ai.js.map +1 -0
- package/dist/integrations/langchain.d.ts +65 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +165 -0
- package/dist/integrations/langchain.js.map +1 -0
- package/dist/middleware/express.d.ts +55 -0
- package/dist/middleware/express.d.ts.map +1 -0
- package/dist/middleware/express.js +101 -0
- package/dist/middleware/express.js.map +1 -0
- package/dist/middleware/index.d.ts +6 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +5 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/pricing/compute-pricing.d.ts +57 -0
- package/dist/pricing/compute-pricing.d.ts.map +1 -0
- package/dist/pricing/compute-pricing.js +627 -0
- package/dist/pricing/compute-pricing.js.map +1 -0
- package/dist/pricing/cost_map.json +37665 -0
- package/dist/pricing/egress-pricing.d.ts +55 -0
- package/dist/pricing/egress-pricing.d.ts.map +1 -0
- package/dist/pricing/egress-pricing.js +226 -0
- package/dist/pricing/egress-pricing.js.map +1 -0
- package/dist/pricing/engine.d.ts +24 -0
- package/dist/pricing/engine.d.ts.map +1 -0
- package/dist/pricing/engine.js +148 -0
- package/dist/pricing/engine.js.map +1 -0
- package/dist/pricing/gpu-pricing.d.ts +63 -0
- package/dist/pricing/gpu-pricing.d.ts.map +1 -0
- package/dist/pricing/gpu-pricing.js +484 -0
- package/dist/pricing/gpu-pricing.js.map +1 -0
- package/dist/pricing/rates.d.ts +17 -0
- package/dist/pricing/rates.d.ts.map +1 -0
- package/dist/pricing/rates.js +102 -0
- package/dist/pricing/rates.js.map +1 -0
- package/dist/pricing/service-catalog.d.ts +87 -0
- package/dist/pricing/service-catalog.d.ts.map +1 -0
- package/dist/pricing/service-catalog.js +406 -0
- package/dist/pricing/service-catalog.js.map +1 -0
- package/dist/schema/dexcost-event.v1.json +111 -0
- package/dist/schema/dexcost-task.v1.json +160 -0
- package/dist/schema/validate.d.ts +15 -0
- package/dist/schema/validate.d.ts.map +1 -0
- package/dist/schema/validate.js +87 -0
- package/dist/schema/validate.js.map +1 -0
- package/dist/security/redaction.d.ts +55 -0
- package/dist/security/redaction.d.ts.map +1 -0
- package/dist/security/redaction.js +144 -0
- package/dist/security/redaction.js.map +1 -0
- package/dist/transport/buffer.d.ts +117 -0
- package/dist/transport/buffer.d.ts.map +1 -0
- package/dist/transport/buffer.js +759 -0
- package/dist/transport/buffer.js.map +1 -0
- package/dist/transport/pusher.d.ts +89 -0
- package/dist/transport/pusher.d.ts.map +1 -0
- package/dist/transport/pusher.js +323 -0
- package/dist/transport/pusher.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Bedrock auto-instrumentation for dexcost TypeScript SDK.
|
|
3
|
+
*
|
|
4
|
+
* Monkey-patches `BedrockRuntimeClient.prototype.send` to capture
|
|
5
|
+
* InvokeModel and InvokeModelWithResponseStream commands, automatically
|
|
6
|
+
* recording cost events and aggregating token usage on the active task context.
|
|
7
|
+
*
|
|
8
|
+
* Token usage is parsed from the response body JSON and varies by model
|
|
9
|
+
* family (Anthropic, Amazon Titan, Meta Llama, Cohere, Mistral, AI21).
|
|
10
|
+
*/
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { createCostEvent } from "../core/models.js";
|
|
13
|
+
import { getCurrentTask } from "../core/context.js";
|
|
14
|
+
import { createAutoTask } from "../core/auto-task.js";
|
|
15
|
+
import { registerInstrument } from "./index.js";
|
|
16
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
17
|
+
let _patched = false;
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
19
|
+
let _original = null;
|
|
20
|
+
let _clientClass = null;
|
|
21
|
+
let _buffer = null;
|
|
22
|
+
let _pricing = null;
|
|
23
|
+
/** Test helper: inject a mock BedrockRuntimeClient class so tests avoid importing @aws-sdk/client-bedrock-runtime. */
|
|
24
|
+
export function _setClientClass(cls) {
|
|
25
|
+
_clientClass = cls;
|
|
26
|
+
}
|
|
27
|
+
/** Test helper: reset to real module resolution. */
|
|
28
|
+
export function _resetClientClass() {
|
|
29
|
+
_clientClass = null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Patch `BedrockRuntimeClient.prototype.send` to record cost events for
|
|
33
|
+
* InvokeModelCommand calls.
|
|
34
|
+
*
|
|
35
|
+
* If `@aws-sdk/client-bedrock-runtime` is not installed and no mock class is
|
|
36
|
+
* injected, the dynamic import will throw and the function will reject.
|
|
37
|
+
*/
|
|
38
|
+
export async function instrumentBedrock(pricing, buffer) {
|
|
39
|
+
if (_patched)
|
|
40
|
+
return;
|
|
41
|
+
let ClientProto;
|
|
42
|
+
if (_clientClass) {
|
|
43
|
+
ClientProto = _clientClass.prototype;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// @aws-sdk/client-bedrock-runtime is an optional peer dependency; the
|
|
47
|
+
// dynamic import only succeeds at runtime if the user has installed it.
|
|
48
|
+
// @ts-expect-error -- aws-sdk types are not bundled with dexcost
|
|
49
|
+
const bedrockModule = await import("@aws-sdk/client-bedrock-runtime");
|
|
50
|
+
const mod = bedrockModule.default ?? bedrockModule;
|
|
51
|
+
ClientProto = mod.BedrockRuntimeClient.prototype;
|
|
52
|
+
}
|
|
53
|
+
_original = ClientProto.send;
|
|
54
|
+
_buffer = buffer;
|
|
55
|
+
_pricing = pricing;
|
|
56
|
+
ClientProto.send = async function (command, ...rest) {
|
|
57
|
+
// Only intercept InvokeModelCommand (by constructor name convention)
|
|
58
|
+
const commandName = command?.constructor?.name ?? "";
|
|
59
|
+
if (commandName !== "InvokeModelCommand") {
|
|
60
|
+
return _original.call(this, command, ...rest);
|
|
61
|
+
}
|
|
62
|
+
let task = getCurrentTask();
|
|
63
|
+
// Auto-create a task when no explicit task is active so LLM costs
|
|
64
|
+
// are never silently lost (mirrors Python create_auto_task).
|
|
65
|
+
if (!task) {
|
|
66
|
+
task = createAutoTask("bedrock.invokeModel");
|
|
67
|
+
_buffer?.upsertTask(task);
|
|
68
|
+
}
|
|
69
|
+
const startTime = performance.now();
|
|
70
|
+
const response = await _original.call(this, command, ...rest);
|
|
71
|
+
try {
|
|
72
|
+
const latencyMs = Math.round(performance.now() - startTime);
|
|
73
|
+
const modelId = command?.input?.modelId ?? "unknown";
|
|
74
|
+
recordEvent(response, modelId, task, latencyMs);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// dexcost errors must never crash user code
|
|
78
|
+
}
|
|
79
|
+
return response;
|
|
80
|
+
};
|
|
81
|
+
_patched = true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Remove the monkey-patch and restore the original `send` method.
|
|
85
|
+
*/
|
|
86
|
+
export function uninstrumentBedrock() {
|
|
87
|
+
if (!_patched || !_original)
|
|
88
|
+
return;
|
|
89
|
+
if (_clientClass) {
|
|
90
|
+
_clientClass.prototype.send = _original;
|
|
91
|
+
}
|
|
92
|
+
_original = null;
|
|
93
|
+
_buffer = null;
|
|
94
|
+
_pricing = null;
|
|
95
|
+
_patched = false;
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Internal helpers
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
/**
|
|
101
|
+
* Parse token usage from a Bedrock InvokeModel response body.
|
|
102
|
+
*
|
|
103
|
+
* Different model families embed token usage in different JSON structures:
|
|
104
|
+
* - Anthropic Claude: usage.input_tokens / usage.output_tokens
|
|
105
|
+
* - Amazon Titan: inputTextTokenCount / results[0].tokenCount
|
|
106
|
+
* - Meta Llama: prompt_token_count / generation_token_count
|
|
107
|
+
* - Cohere: meta.billed_units.input_tokens / meta.billed_units.output_tokens
|
|
108
|
+
* - Mistral: usage.prompt_tokens / usage.completion_tokens
|
|
109
|
+
* - AI21: usage.prompt_tokens / usage.completion_tokens (Jamba)
|
|
110
|
+
*/
|
|
111
|
+
function parseUsage(body, modelId) {
|
|
112
|
+
let inputTokens = 0;
|
|
113
|
+
let outputTokens = 0;
|
|
114
|
+
if (!body)
|
|
115
|
+
return { inputTokens, outputTokens };
|
|
116
|
+
const lowerModel = modelId.toLowerCase();
|
|
117
|
+
if (lowerModel.includes("anthropic") || lowerModel.includes("claude")) {
|
|
118
|
+
// Anthropic Claude on Bedrock
|
|
119
|
+
inputTokens = body?.usage?.input_tokens ?? 0;
|
|
120
|
+
outputTokens = body?.usage?.output_tokens ?? 0;
|
|
121
|
+
}
|
|
122
|
+
else if (lowerModel.includes("titan")) {
|
|
123
|
+
// Amazon Titan
|
|
124
|
+
inputTokens = body?.inputTextTokenCount ?? 0;
|
|
125
|
+
outputTokens = body?.results?.[0]?.tokenCount ?? 0;
|
|
126
|
+
}
|
|
127
|
+
else if (lowerModel.includes("llama") || lowerModel.includes("meta")) {
|
|
128
|
+
// Meta Llama
|
|
129
|
+
inputTokens = body?.prompt_token_count ?? 0;
|
|
130
|
+
outputTokens = body?.generation_token_count ?? 0;
|
|
131
|
+
}
|
|
132
|
+
else if (lowerModel.includes("cohere")) {
|
|
133
|
+
// Cohere on Bedrock
|
|
134
|
+
inputTokens = body?.meta?.billed_units?.input_tokens ?? 0;
|
|
135
|
+
outputTokens = body?.meta?.billed_units?.output_tokens ?? 0;
|
|
136
|
+
}
|
|
137
|
+
else if (lowerModel.includes("mistral")) {
|
|
138
|
+
// Mistral on Bedrock
|
|
139
|
+
inputTokens = body?.usage?.prompt_tokens ?? 0;
|
|
140
|
+
outputTokens = body?.usage?.completion_tokens ?? 0;
|
|
141
|
+
}
|
|
142
|
+
else if (lowerModel.includes("ai21") || lowerModel.includes("jamba")) {
|
|
143
|
+
// AI21 Jamba
|
|
144
|
+
inputTokens = body?.usage?.prompt_tokens ?? 0;
|
|
145
|
+
outputTokens = body?.usage?.completion_tokens ?? 0;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// Fallback: try common field names
|
|
149
|
+
inputTokens =
|
|
150
|
+
body?.usage?.input_tokens ??
|
|
151
|
+
body?.usage?.prompt_tokens ??
|
|
152
|
+
body?.inputTextTokenCount ??
|
|
153
|
+
0;
|
|
154
|
+
outputTokens =
|
|
155
|
+
body?.usage?.output_tokens ??
|
|
156
|
+
body?.usage?.completion_tokens ??
|
|
157
|
+
body?.results?.[0]?.tokenCount ??
|
|
158
|
+
0;
|
|
159
|
+
}
|
|
160
|
+
return { inputTokens, outputTokens };
|
|
161
|
+
}
|
|
162
|
+
function recordEvent(response, modelId, task, latencyMs) {
|
|
163
|
+
if (!_buffer || !_pricing)
|
|
164
|
+
return;
|
|
165
|
+
let parsedBody = null;
|
|
166
|
+
try {
|
|
167
|
+
const rawBody = response?.body;
|
|
168
|
+
if (rawBody instanceof Uint8Array) {
|
|
169
|
+
parsedBody = JSON.parse(new TextDecoder().decode(rawBody));
|
|
170
|
+
}
|
|
171
|
+
else if (typeof rawBody === "string") {
|
|
172
|
+
parsedBody = JSON.parse(rawBody);
|
|
173
|
+
}
|
|
174
|
+
else if (rawBody && typeof rawBody === "object") {
|
|
175
|
+
parsedBody = rawBody;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// body parse failure — record event with zero tokens
|
|
180
|
+
}
|
|
181
|
+
const { inputTokens, outputTokens } = parseUsage(parsedBody, modelId);
|
|
182
|
+
const hasUsage = inputTokens > 0 || outputTokens > 0;
|
|
183
|
+
let costUsd = 0;
|
|
184
|
+
let costConfidence = "estimated";
|
|
185
|
+
let pricingSource = "unknown";
|
|
186
|
+
if (hasUsage) {
|
|
187
|
+
const result = _pricing.getCost(modelId, inputTokens, outputTokens);
|
|
188
|
+
costUsd = result.costUsd;
|
|
189
|
+
costConfidence = result.costConfidence;
|
|
190
|
+
pricingSource = result.pricingSource;
|
|
191
|
+
}
|
|
192
|
+
const event = createCostEvent({
|
|
193
|
+
eventId: randomUUID(),
|
|
194
|
+
taskId: task.taskId,
|
|
195
|
+
eventType: "llm_call",
|
|
196
|
+
costUsd,
|
|
197
|
+
costConfidence,
|
|
198
|
+
pricingSource,
|
|
199
|
+
provider: "aws-bedrock",
|
|
200
|
+
model: modelId,
|
|
201
|
+
inputTokens,
|
|
202
|
+
outputTokens,
|
|
203
|
+
latencyMs,
|
|
204
|
+
isRetry: false,
|
|
205
|
+
});
|
|
206
|
+
_buffer.addEvent(event);
|
|
207
|
+
task.llmCostUsd += costUsd;
|
|
208
|
+
task.totalCostUsd += costUsd;
|
|
209
|
+
task.totalInputTokens += inputTokens;
|
|
210
|
+
task.totalOutputTokens += outputTokens;
|
|
211
|
+
_buffer.upsertTask(task);
|
|
212
|
+
}
|
|
213
|
+
// Self-register so importing this module is enough to make the instrument available.
|
|
214
|
+
registerInstrument("bedrock", instrumentBedrock, uninstrumentBedrock);
|
|
215
|
+
//# sourceMappingURL=bedrock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../src/instruments/bedrock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,uDAAuD;AAEvD,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,sEAAsE;AACtE,IAAI,SAAS,GAAoB,IAAI,CAAC;AACtC,IAAI,YAAY,GAAQ,IAAI,CAAC;AAC7B,IAAI,OAAO,GAAuB,IAAI,CAAC;AACvC,IAAI,QAAQ,GAAyB,IAAI,CAAC;AAE1C,sHAAsH;AACtH,MAAM,UAAU,eAAe,CAAC,GAAQ;IACtC,YAAY,GAAG,GAAG,CAAC;AACrB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,iBAAiB;IAC/B,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAsB,EACtB,MAAmB;IAEnB,IAAI,QAAQ;QAAE,OAAO;IAErB,IAAI,WAAgB,CAAC;IACrB,IAAI,YAAY,EAAE,CAAC;QACjB,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,sEAAsE;QACtE,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;QACtE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC;QACnD,WAAW,GAAG,GAAG,CAAC,oBAAoB,CAAC,SAAS,CAAC;IACnD,CAAC;IAED,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC;IAC7B,OAAO,GAAG,MAAM,CAAC;IACjB,QAAQ,GAAG,OAAO,CAAC;IAEnB,WAAW,CAAC,IAAI,GAAG,KAAK,WAEtB,OAAY,EACZ,GAAG,IAAW;QAEd,qEAAqE;QACrE,MAAM,WAAW,GAAW,OAAO,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC;QAC7D,IAAI,WAAW,KAAK,oBAAoB,EAAE,CAAC;YACzC,OAAO,SAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,IAAI,GAAG,cAAc,EAAE,CAAC;QAE5B,kEAAkE;QAClE,6DAA6D;QAC7D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,cAAc,CAAC,qBAAqB,CAAC,CAAC;YAC7C,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,SAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAW,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,SAAS,CAAC;YAC7D,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,QAAQ,GAAG,IAAI,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS;QAAE,OAAO;IAEpC,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC;IAC1C,CAAC;IAED,SAAS,GAAG,IAAI,CAAC;IACjB,OAAO,GAAG,IAAI,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAChB,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,SAAS,UAAU,CAAC,IAAS,EAAE,OAAe;IAC5C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;IAEhD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEzC,IAAI,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtE,8BAA8B;QAC9B,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC;QAC7C,YAAY,GAAG,IAAI,EAAE,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,eAAe;QACf,WAAW,GAAG,IAAI,EAAE,mBAAmB,IAAI,CAAC,CAAC;QAC7C,YAAY,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvE,aAAa;QACb,WAAW,GAAG,IAAI,EAAE,kBAAkB,IAAI,CAAC,CAAC;QAC5C,YAAY,GAAG,IAAI,EAAE,sBAAsB,IAAI,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,oBAAoB;QACpB,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,IAAI,CAAC,CAAC;QAC1D,YAAY,GAAG,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,IAAI,CAAC,CAAC;IAC9D,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1C,qBAAqB;QACrB,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC;QAC9C,YAAY,GAAG,IAAI,EAAE,KAAK,EAAE,iBAAiB,IAAI,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACvE,aAAa;QACb,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC;QAC9C,YAAY,GAAG,IAAI,EAAE,KAAK,EAAE,iBAAiB,IAAI,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,mCAAmC;QACnC,WAAW;YACT,IAAI,EAAE,KAAK,EAAE,YAAY;gBACzB,IAAI,EAAE,KAAK,EAAE,aAAa;gBAC1B,IAAI,EAAE,mBAAmB;gBACzB,CAAC,CAAC;QACJ,YAAY;YACV,IAAI,EAAE,KAAK,EAAE,aAAa;gBAC1B,IAAI,EAAE,KAAK,EAAE,iBAAiB;gBAC9B,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU;gBAC9B,CAAC,CAAC;IACN,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,WAAW,CAAC,QAAa,EAAE,OAAe,EAAE,IAAU,EAAE,SAAiB;IAChF,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;QAAE,OAAO;IAElC,IAAI,UAAU,GAAQ,IAAI,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,EAAE,IAAI,CAAC;QAC/B,IAAI,OAAO,YAAY,UAAU,EAAE,CAAC;YAClC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACvC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAClD,UAAU,GAAG,OAAO,CAAC;QACvB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,WAAW,GAAG,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;IAErD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,cAAc,GAAmB,WAAW,CAAC;IACjD,IAAI,aAAa,GAAkB,SAAS,CAAC;IAE7C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAe,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QAChF,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACzB,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QACvC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;IACvC,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC;QAC5B,OAAO,EAAE,UAAU,EAAE;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,UAAU;QACrB,OAAO;QACP,cAAc;QACd,aAAa;QACb,QAAQ,EAAE,aAAa;QACvB,KAAK,EAAE,OAAO;QACd,WAAW;QACX,YAAY;QACZ,SAAS;QACT,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IAEH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExB,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC;IAC3B,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC;IAC7B,IAAI,CAAC,gBAAgB,IAAI,WAAW,CAAC;IACrC,IAAI,CAAC,iBAAiB,IAAI,YAAY,CAAC;IACvC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,qFAAqF;AACrF,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cohere auto-instrumentation for dexcost TypeScript SDK.
|
|
3
|
+
*
|
|
4
|
+
* Monkey-patches `CohereClient.prototype.chat` to automatically
|
|
5
|
+
* record cost events and aggregate token usage on the active task context.
|
|
6
|
+
*
|
|
7
|
+
* Token usage from response.meta.billedUnits (inputTokens, outputTokens).
|
|
8
|
+
*
|
|
9
|
+
* Supports both non-streaming and streaming responses (chatStream).
|
|
10
|
+
*/
|
|
11
|
+
import type { EventBuffer } from "../transport/buffer.js";
|
|
12
|
+
import type { PricingEngine } from "../pricing/engine.js";
|
|
13
|
+
/** Test helper: inject a mock CohereClient class so tests avoid importing cohere-ai. */
|
|
14
|
+
export declare function _setClientClass(cls: any): void;
|
|
15
|
+
/** Test helper: reset to real module resolution. */
|
|
16
|
+
export declare function _resetClientClass(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Patch `CohereClient.prototype.chat` and `CohereClient.prototype.chatStream`
|
|
19
|
+
* to record cost events.
|
|
20
|
+
*
|
|
21
|
+
* If `cohere-ai` is not installed and no mock class is injected, the dynamic
|
|
22
|
+
* import will throw and the function will reject.
|
|
23
|
+
*/
|
|
24
|
+
export declare function instrumentCohere(pricing: PricingEngine, buffer: EventBuffer): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Remove the monkey-patches and restore the original methods.
|
|
27
|
+
*/
|
|
28
|
+
export declare function uninstrumentCohere(): void;
|
|
29
|
+
//# sourceMappingURL=cohere.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohere.d.ts","sourceRoot":"","sources":["../../src/instruments/cohere.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAC;AActE,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAE9C;AAED,oDAAoD;AACpD,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC,CAmEf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAezC"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cohere auto-instrumentation for dexcost TypeScript SDK.
|
|
3
|
+
*
|
|
4
|
+
* Monkey-patches `CohereClient.prototype.chat` to automatically
|
|
5
|
+
* record cost events and aggregate token usage on the active task context.
|
|
6
|
+
*
|
|
7
|
+
* Token usage from response.meta.billedUnits (inputTokens, outputTokens).
|
|
8
|
+
*
|
|
9
|
+
* Supports both non-streaming and streaming responses (chatStream).
|
|
10
|
+
*/
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { createCostEvent } from "../core/models.js";
|
|
13
|
+
import { getCurrentTask } from "../core/context.js";
|
|
14
|
+
import { createAutoTask } from "../core/auto-task.js";
|
|
15
|
+
import { registerInstrument } from "./index.js";
|
|
16
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
17
|
+
let _patched = false;
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
19
|
+
let _originalChat = null;
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
21
|
+
let _originalChatStream = null;
|
|
22
|
+
let _clientClass = null;
|
|
23
|
+
let _buffer = null;
|
|
24
|
+
let _pricing = null;
|
|
25
|
+
/** Test helper: inject a mock CohereClient class so tests avoid importing cohere-ai. */
|
|
26
|
+
export function _setClientClass(cls) {
|
|
27
|
+
_clientClass = cls;
|
|
28
|
+
}
|
|
29
|
+
/** Test helper: reset to real module resolution. */
|
|
30
|
+
export function _resetClientClass() {
|
|
31
|
+
_clientClass = null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Patch `CohereClient.prototype.chat` and `CohereClient.prototype.chatStream`
|
|
35
|
+
* to record cost events.
|
|
36
|
+
*
|
|
37
|
+
* If `cohere-ai` is not installed and no mock class is injected, the dynamic
|
|
38
|
+
* import will throw and the function will reject.
|
|
39
|
+
*/
|
|
40
|
+
export async function instrumentCohere(pricing, buffer) {
|
|
41
|
+
if (_patched)
|
|
42
|
+
return;
|
|
43
|
+
let ClientProto;
|
|
44
|
+
if (_clientClass) {
|
|
45
|
+
ClientProto = _clientClass.prototype;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// cohere-ai is an optional peer dependency; the dynamic import
|
|
49
|
+
// only succeeds at runtime if the user has installed it.
|
|
50
|
+
// @ts-expect-error -- cohere-ai types are not bundled with dexcost
|
|
51
|
+
const cohereModule = await import("cohere-ai");
|
|
52
|
+
const mod = cohereModule.default ?? cohereModule;
|
|
53
|
+
ClientProto = mod.CohereClient.prototype;
|
|
54
|
+
}
|
|
55
|
+
_originalChat = ClientProto.chat;
|
|
56
|
+
_originalChatStream = ClientProto.chatStream ?? null;
|
|
57
|
+
_buffer = buffer;
|
|
58
|
+
_pricing = pricing;
|
|
59
|
+
ClientProto.chat = async function (body, options) {
|
|
60
|
+
let task = getCurrentTask();
|
|
61
|
+
// Auto-create a task when no explicit task is active so LLM costs
|
|
62
|
+
// are never silently lost (mirrors Python create_auto_task).
|
|
63
|
+
if (!task) {
|
|
64
|
+
task = createAutoTask("cohere.chat");
|
|
65
|
+
_buffer?.upsertTask(task);
|
|
66
|
+
}
|
|
67
|
+
const startTime = performance.now();
|
|
68
|
+
const response = await _originalChat.call(this, body, options);
|
|
69
|
+
try {
|
|
70
|
+
const latencyMs = Math.round(performance.now() - startTime);
|
|
71
|
+
const model = body?.model ?? response?.model ?? "command-r-plus";
|
|
72
|
+
recordEvent(response, model, task, latencyMs);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// dexcost errors must never crash user code
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
};
|
|
79
|
+
if (_originalChatStream) {
|
|
80
|
+
ClientProto.chatStream = async function (body, options) {
|
|
81
|
+
let task = getCurrentTask();
|
|
82
|
+
if (!task) {
|
|
83
|
+
task = createAutoTask("cohere.chatStream");
|
|
84
|
+
_buffer?.upsertTask(task);
|
|
85
|
+
}
|
|
86
|
+
const startTime = performance.now();
|
|
87
|
+
const rawStream = await _originalChatStream.call(this, body, options);
|
|
88
|
+
const model = body?.model ?? "command-r-plus";
|
|
89
|
+
return wrapStream(rawStream, model, task, startTime);
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
_patched = true;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Remove the monkey-patches and restore the original methods.
|
|
96
|
+
*/
|
|
97
|
+
export function uninstrumentCohere() {
|
|
98
|
+
if (!_patched || !_originalChat)
|
|
99
|
+
return;
|
|
100
|
+
if (_clientClass) {
|
|
101
|
+
_clientClass.prototype.chat = _originalChat;
|
|
102
|
+
if (_originalChatStream) {
|
|
103
|
+
_clientClass.prototype.chatStream = _originalChatStream;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
_originalChat = null;
|
|
107
|
+
_originalChatStream = null;
|
|
108
|
+
_buffer = null;
|
|
109
|
+
_pricing = null;
|
|
110
|
+
_patched = false;
|
|
111
|
+
}
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// Internal helpers
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
function recordEvent(response, model, task, latencyMs) {
|
|
116
|
+
if (!_buffer || !_pricing)
|
|
117
|
+
return;
|
|
118
|
+
const billedUnits = response?.meta?.billedUnits;
|
|
119
|
+
const hasUsage = billedUnits != null;
|
|
120
|
+
const inputTokens = billedUnits?.inputTokens ?? 0;
|
|
121
|
+
const outputTokens = billedUnits?.outputTokens ?? 0;
|
|
122
|
+
let costUsd = 0;
|
|
123
|
+
let costConfidence = "estimated";
|
|
124
|
+
let pricingSource = "unknown";
|
|
125
|
+
if (hasUsage) {
|
|
126
|
+
const result = _pricing.getCost(model, inputTokens, outputTokens);
|
|
127
|
+
costUsd = result.costUsd;
|
|
128
|
+
costConfidence = result.costConfidence;
|
|
129
|
+
pricingSource = result.pricingSource;
|
|
130
|
+
}
|
|
131
|
+
const event = createCostEvent({
|
|
132
|
+
eventId: randomUUID(),
|
|
133
|
+
taskId: task.taskId,
|
|
134
|
+
eventType: "llm_call",
|
|
135
|
+
costUsd,
|
|
136
|
+
costConfidence,
|
|
137
|
+
pricingSource,
|
|
138
|
+
provider: "cohere",
|
|
139
|
+
model,
|
|
140
|
+
inputTokens,
|
|
141
|
+
outputTokens,
|
|
142
|
+
latencyMs,
|
|
143
|
+
isRetry: false,
|
|
144
|
+
});
|
|
145
|
+
_buffer.addEvent(event);
|
|
146
|
+
task.llmCostUsd += costUsd;
|
|
147
|
+
task.totalCostUsd += costUsd;
|
|
148
|
+
task.totalInputTokens += inputTokens;
|
|
149
|
+
task.totalOutputTokens += outputTokens;
|
|
150
|
+
_buffer.upsertTask(task);
|
|
151
|
+
}
|
|
152
|
+
function wrapStream(rawStream, model, task, startTime) {
|
|
153
|
+
let inputTokens = 0;
|
|
154
|
+
let outputTokens = 0;
|
|
155
|
+
let hasUsage = false;
|
|
156
|
+
let finalized = false;
|
|
157
|
+
return {
|
|
158
|
+
[Symbol.asyncIterator]() {
|
|
159
|
+
const iter = rawStream[Symbol.asyncIterator]();
|
|
160
|
+
return {
|
|
161
|
+
async next() {
|
|
162
|
+
const result = await iter.next();
|
|
163
|
+
if (result.done) {
|
|
164
|
+
if (finalized)
|
|
165
|
+
return result;
|
|
166
|
+
finalized = true;
|
|
167
|
+
try {
|
|
168
|
+
const latencyMs = Math.round(performance.now() - startTime);
|
|
169
|
+
if (hasUsage && _pricing && _buffer) {
|
|
170
|
+
const costResult = _pricing.getCost(model, inputTokens, outputTokens);
|
|
171
|
+
const event = createCostEvent({
|
|
172
|
+
eventId: randomUUID(),
|
|
173
|
+
taskId: task.taskId,
|
|
174
|
+
eventType: "llm_call",
|
|
175
|
+
costUsd: costResult.costUsd,
|
|
176
|
+
costConfidence: costResult.costConfidence,
|
|
177
|
+
pricingSource: costResult.pricingSource,
|
|
178
|
+
provider: "cohere",
|
|
179
|
+
model,
|
|
180
|
+
inputTokens,
|
|
181
|
+
outputTokens,
|
|
182
|
+
latencyMs,
|
|
183
|
+
isRetry: false,
|
|
184
|
+
});
|
|
185
|
+
_buffer.addEvent(event);
|
|
186
|
+
task.llmCostUsd += costResult.costUsd;
|
|
187
|
+
task.totalCostUsd += costResult.costUsd;
|
|
188
|
+
task.totalInputTokens += inputTokens;
|
|
189
|
+
task.totalOutputTokens += outputTokens;
|
|
190
|
+
_buffer.upsertTask(task);
|
|
191
|
+
}
|
|
192
|
+
else if (_buffer) {
|
|
193
|
+
const event = createCostEvent({
|
|
194
|
+
eventId: randomUUID(),
|
|
195
|
+
taskId: task.taskId,
|
|
196
|
+
eventType: "llm_call",
|
|
197
|
+
costUsd: 0,
|
|
198
|
+
costConfidence: "estimated",
|
|
199
|
+
pricingSource: "unknown",
|
|
200
|
+
provider: "cohere",
|
|
201
|
+
model,
|
|
202
|
+
inputTokens: 0,
|
|
203
|
+
outputTokens: 0,
|
|
204
|
+
latencyMs,
|
|
205
|
+
isRetry: false,
|
|
206
|
+
});
|
|
207
|
+
_buffer.addEvent(event);
|
|
208
|
+
_buffer.upsertTask(task);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// dexcost errors must never crash user code
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
const chunk = result.value;
|
|
217
|
+
// Cohere streaming events: look for usage in stream-end or meta events
|
|
218
|
+
if (chunk?.eventType === "stream-end" && chunk?.response?.meta?.billedUnits) {
|
|
219
|
+
hasUsage = true;
|
|
220
|
+
inputTokens = chunk.response.meta.billedUnits.inputTokens ?? inputTokens;
|
|
221
|
+
outputTokens = chunk.response.meta.billedUnits.outputTokens ?? outputTokens;
|
|
222
|
+
}
|
|
223
|
+
// Also check for meta.billedUnits directly on chunks
|
|
224
|
+
if (chunk?.meta?.billedUnits) {
|
|
225
|
+
hasUsage = true;
|
|
226
|
+
inputTokens = chunk.meta.billedUnits.inputTokens ?? inputTokens;
|
|
227
|
+
outputTokens = chunk.meta.billedUnits.outputTokens ?? outputTokens;
|
|
228
|
+
}
|
|
229
|
+
return result;
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
// Self-register so importing this module is enough to make the instrument available.
|
|
236
|
+
registerInstrument("cohere", instrumentCohere, uninstrumentCohere);
|
|
237
|
+
//# sourceMappingURL=cohere.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohere.js","sourceRoot":"","sources":["../../src/instruments/cohere.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Gemini auto-instrumentation for dexcost TypeScript SDK.
|
|
3
|
+
*
|
|
4
|
+
* Monkey-patches `GenerativeModel.prototype.generateContent` to automatically
|
|
5
|
+
* record cost events and aggregate token usage on the active task context.
|
|
6
|
+
*
|
|
7
|
+
* Token usage from response.usageMetadata (promptTokenCount,
|
|
8
|
+
* candidatesTokenCount, cachedContentTokenCount).
|
|
9
|
+
*
|
|
10
|
+
* Supports both non-streaming and streaming responses (generateContentStream).
|
|
11
|
+
*/
|
|
12
|
+
import type { EventBuffer } from "../transport/buffer.js";
|
|
13
|
+
import type { PricingEngine } from "../pricing/engine.js";
|
|
14
|
+
/** Test helper: inject a mock GenerativeModel class so tests avoid importing @google/generative-ai. */
|
|
15
|
+
export declare function _setGenerativeModelClass(cls: any): void;
|
|
16
|
+
/** Test helper: reset to real module resolution. */
|
|
17
|
+
export declare function _resetGenerativeModelClass(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Patch `GenerativeModel.prototype.generateContent` and
|
|
20
|
+
* `GenerativeModel.prototype.generateContentStream` to record cost events.
|
|
21
|
+
*
|
|
22
|
+
* If `@google/generative-ai` is not installed and no mock class is injected,
|
|
23
|
+
* the dynamic import will throw and the function will reject.
|
|
24
|
+
*/
|
|
25
|
+
export declare function instrumentGemini(pricing: PricingEngine, buffer: EventBuffer): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Remove the monkey-patches and restore the original methods.
|
|
28
|
+
*/
|
|
29
|
+
export declare function uninstrumentGemini(): void;
|
|
30
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/instruments/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAC;AActE,uGAAuG;AACvG,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,oDAAoD;AACpD,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC,CA+Df;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAezC"}
|