@grislabs/agentmeter 0.1.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/README.md +208 -0
- package/dist/auto-patch.d.ts +48 -0
- package/dist/auto-patch.d.ts.map +1 -0
- package/dist/auto-patch.js +129 -0
- package/dist/auto-patch.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/event-buffer.d.ts +19 -0
- package/dist/event-buffer.d.ts.map +1 -0
- package/dist/event-buffer.js +54 -0
- package/dist/event-buffer.js.map +1 -0
- package/dist/extractors.d.ts +50 -0
- package/dist/extractors.d.ts.map +1 -0
- package/dist/extractors.js +46 -0
- package/dist/extractors.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +175 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +66 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +90 -0
- package/dist/mcp.js.map +1 -0
- package/dist/pricing.d.ts +14 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +61 -0
- package/dist/pricing.js.map +1 -0
- package/dist/trace-context.d.ts +86 -0
- package/dist/trace-context.d.ts.map +1 -0
- package/dist/trace-context.js +216 -0
- package/dist/trace-context.js.map +1 -0
- package/dist/types.d.ts +102 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventBuffer = void 0;
|
|
4
|
+
class EventBuffer {
|
|
5
|
+
_buffer = [];
|
|
6
|
+
_flushTimer = null;
|
|
7
|
+
_flushSize;
|
|
8
|
+
_flushIntervalMs;
|
|
9
|
+
_onFlush;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this._flushSize = opts.flushSize;
|
|
12
|
+
this._flushIntervalMs = opts.flushIntervalMs;
|
|
13
|
+
this._onFlush = opts.onFlush;
|
|
14
|
+
}
|
|
15
|
+
start() {
|
|
16
|
+
if (this._flushTimer)
|
|
17
|
+
return;
|
|
18
|
+
this._flushTimer = setInterval(() => {
|
|
19
|
+
void this.flush();
|
|
20
|
+
}, this._flushIntervalMs);
|
|
21
|
+
// Don't keep the process alive just for flushing
|
|
22
|
+
if (this._flushTimer.unref)
|
|
23
|
+
this._flushTimer.unref();
|
|
24
|
+
}
|
|
25
|
+
stop() {
|
|
26
|
+
if (this._flushTimer) {
|
|
27
|
+
clearInterval(this._flushTimer);
|
|
28
|
+
this._flushTimer = null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
push(event) {
|
|
32
|
+
this._buffer.push(event);
|
|
33
|
+
if (this._buffer.length >= this._flushSize) {
|
|
34
|
+
void this.flush();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async flush() {
|
|
38
|
+
if (this._buffer.length === 0)
|
|
39
|
+
return;
|
|
40
|
+
const batch = this._buffer.splice(0);
|
|
41
|
+
try {
|
|
42
|
+
await this._onFlush(batch);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Re-add failed events to front of buffer for retry
|
|
46
|
+
this._buffer.unshift(...batch);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
get pending() {
|
|
50
|
+
return this._buffer.length;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.EventBuffer = EventBuffer;
|
|
54
|
+
//# sourceMappingURL=event-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-buffer.js","sourceRoot":"","sources":["../src/event-buffer.ts"],"names":[],"mappings":";;;AAEA,MAAa,WAAW;IACd,OAAO,GAAsB,EAAE,CAAC;IAChC,WAAW,GAA0C,IAAI,CAAC;IAC1D,UAAU,CAAS;IACnB,gBAAgB,CAAS;IACzB,QAAQ,CAA+C;IAE/D,YAAY,IAIX;QACC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC;QAC7C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1B,iDAAiD;QACjD,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK;YAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IACvD,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAChC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,CAAC,KAAsB;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;CACF;AAtDD,kCAsDC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-specific response extractors.
|
|
3
|
+
* These pull model + token usage from raw API responses.
|
|
4
|
+
*/
|
|
5
|
+
interface UsageInfo {
|
|
6
|
+
model: string;
|
|
7
|
+
inputTokens: number;
|
|
8
|
+
outputTokens: number;
|
|
9
|
+
cachedInputTokens?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extract usage from Anthropic Messages API response.
|
|
13
|
+
* Works with @anthropic-ai/sdk response objects.
|
|
14
|
+
*/
|
|
15
|
+
export declare function anthropic(response: {
|
|
16
|
+
model: string;
|
|
17
|
+
usage: {
|
|
18
|
+
input_tokens: number;
|
|
19
|
+
output_tokens: number;
|
|
20
|
+
cache_read_input_tokens?: number;
|
|
21
|
+
cache_creation_input_tokens?: number;
|
|
22
|
+
};
|
|
23
|
+
}): UsageInfo;
|
|
24
|
+
/**
|
|
25
|
+
* Extract usage from OpenAI Chat Completions API response.
|
|
26
|
+
* Works with openai SDK response objects.
|
|
27
|
+
*/
|
|
28
|
+
export declare function openai(response: {
|
|
29
|
+
model: string;
|
|
30
|
+
usage?: {
|
|
31
|
+
prompt_tokens: number;
|
|
32
|
+
completion_tokens: number;
|
|
33
|
+
prompt_tokens_details?: {
|
|
34
|
+
cached_tokens?: number;
|
|
35
|
+
};
|
|
36
|
+
} | null;
|
|
37
|
+
}): UsageInfo;
|
|
38
|
+
/**
|
|
39
|
+
* Extract usage from Google Generative AI response.
|
|
40
|
+
*/
|
|
41
|
+
export declare function google(response: {
|
|
42
|
+
modelVersion?: string;
|
|
43
|
+
usageMetadata?: {
|
|
44
|
+
promptTokenCount: number;
|
|
45
|
+
candidatesTokenCount: number;
|
|
46
|
+
cachedContentTokenCount?: number;
|
|
47
|
+
};
|
|
48
|
+
}): UsageInfo;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=extractors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractors.d.ts","sourceRoot":"","sources":["../src/extractors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;KACtC,CAAC;CACH,GAAG,SAAS,CASZ;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,qBAAqB,CAAC,EAAE;YAAE,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACpD,GAAG,IAAI,CAAC;CACV,GAAG,SAAS,CAOZ;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE;QACd,gBAAgB,EAAE,MAAM,CAAC;QACzB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAC;KAClC,CAAC;CACH,GAAG,SAAS,CAOZ"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider-specific response extractors.
|
|
4
|
+
* These pull model + token usage from raw API responses.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.anthropic = anthropic;
|
|
8
|
+
exports.openai = openai;
|
|
9
|
+
exports.google = google;
|
|
10
|
+
/**
|
|
11
|
+
* Extract usage from Anthropic Messages API response.
|
|
12
|
+
* Works with @anthropic-ai/sdk response objects.
|
|
13
|
+
*/
|
|
14
|
+
function anthropic(response) {
|
|
15
|
+
return {
|
|
16
|
+
model: response.model,
|
|
17
|
+
inputTokens: response.usage.input_tokens,
|
|
18
|
+
outputTokens: response.usage.output_tokens,
|
|
19
|
+
cachedInputTokens: (response.usage.cache_read_input_tokens ?? 0) +
|
|
20
|
+
(response.usage.cache_creation_input_tokens ?? 0),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extract usage from OpenAI Chat Completions API response.
|
|
25
|
+
* Works with openai SDK response objects.
|
|
26
|
+
*/
|
|
27
|
+
function openai(response) {
|
|
28
|
+
return {
|
|
29
|
+
model: response.model,
|
|
30
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
31
|
+
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
32
|
+
cachedInputTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extract usage from Google Generative AI response.
|
|
37
|
+
*/
|
|
38
|
+
function google(response) {
|
|
39
|
+
return {
|
|
40
|
+
model: response.modelVersion ?? "gemini-unknown",
|
|
41
|
+
inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
|
|
42
|
+
outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0,
|
|
43
|
+
cachedInputTokens: response.usageMetadata?.cachedContentTokenCount ?? 0,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=extractors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractors.js","sourceRoot":"","sources":["../src/extractors.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAaH,8BAiBC;AAMD,wBAcC;AAKD,wBAcC;AA5DD;;;GAGG;AACH,SAAgB,SAAS,CAAC,QAQzB;IACC,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY;QACxC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa;QAC1C,iBAAiB,EACf,CAAC,QAAQ,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC;YAC7C,CAAC,QAAQ,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC;KACpD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,MAAM,CAAC,QAOtB;IACC,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;QAC/C,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;QACpD,iBAAiB,EAAE,QAAQ,CAAC,KAAK,EAAE,qBAAqB,EAAE,aAAa,IAAI,CAAC;KAC7E,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,MAAM,CAAC,QAOtB;IACC,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,YAAY,IAAI,gBAAgB;QAChD,WAAW,EAAE,QAAQ,CAAC,aAAa,EAAE,gBAAgB,IAAI,CAAC;QAC1D,YAAY,EAAE,QAAQ,CAAC,aAAa,EAAE,oBAAoB,IAAI,CAAC;QAC/D,iBAAiB,EAAE,QAAQ,CAAC,aAAa,EAAE,uBAAuB,IAAI,CAAC;KACxE,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TraceContext } from "./trace-context.js";
|
|
2
|
+
import type { AgentMeterConfig, TraceTags, BudgetRule } from "./types.js";
|
|
3
|
+
export * as extractors from "./extractors.js";
|
|
4
|
+
export { TraceContext } from "./trace-context.js";
|
|
5
|
+
export { patchAnthropic, patchOpenAI } from "./auto-patch.js";
|
|
6
|
+
export type { AgentMeterConfig, AgentMeterEvent, TraceTags, BudgetRule, CostType, LLMCallEvent, ToolCallEvent, PaymentEvent, TraceCompleteEvent, } from "./types.js";
|
|
7
|
+
export { calculateCost, setCustomPricing, getModelPricing } from "./pricing.js";
|
|
8
|
+
export declare function init(config: AgentMeterConfig): void;
|
|
9
|
+
export declare function budget(workflow: string, rule: BudgetRule): void;
|
|
10
|
+
export declare function trace<T>(workflow: string, tags: TraceTags, fn: (ctx: TraceContext) => Promise<T>): Promise<T>;
|
|
11
|
+
export declare function flush(): Promise<void>;
|
|
12
|
+
export declare function shutdown(): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIlD,OAAO,KAAK,EACV,gBAAgB,EAEhB,SAAS,EACT,UAAU,EAEX,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAchF,wBAAgB,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAgBnD;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAE/D;AAED,wBAAsB,KAAK,CAAC,CAAC,EAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,GACpC,OAAO,CAAC,CAAC,CAAC,CAoCZ;AAED,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3C;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getModelPricing = exports.setCustomPricing = exports.calculateCost = exports.patchOpenAI = exports.patchAnthropic = exports.TraceContext = exports.extractors = void 0;
|
|
37
|
+
exports.init = init;
|
|
38
|
+
exports.budget = budget;
|
|
39
|
+
exports.trace = trace;
|
|
40
|
+
exports.flush = flush;
|
|
41
|
+
exports.shutdown = shutdown;
|
|
42
|
+
const trace_context_js_1 = require("./trace-context.js");
|
|
43
|
+
const event_buffer_js_1 = require("./event-buffer.js");
|
|
44
|
+
const pricing_js_1 = require("./pricing.js");
|
|
45
|
+
const auto_patch_js_1 = require("./auto-patch.js");
|
|
46
|
+
exports.extractors = __importStar(require("./extractors.js"));
|
|
47
|
+
var trace_context_js_2 = require("./trace-context.js");
|
|
48
|
+
Object.defineProperty(exports, "TraceContext", { enumerable: true, get: function () { return trace_context_js_2.TraceContext; } });
|
|
49
|
+
var auto_patch_js_2 = require("./auto-patch.js");
|
|
50
|
+
Object.defineProperty(exports, "patchAnthropic", { enumerable: true, get: function () { return auto_patch_js_2.patchAnthropic; } });
|
|
51
|
+
Object.defineProperty(exports, "patchOpenAI", { enumerable: true, get: function () { return auto_patch_js_2.patchOpenAI; } });
|
|
52
|
+
var pricing_js_2 = require("./pricing.js");
|
|
53
|
+
Object.defineProperty(exports, "calculateCost", { enumerable: true, get: function () { return pricing_js_2.calculateCost; } });
|
|
54
|
+
Object.defineProperty(exports, "setCustomPricing", { enumerable: true, get: function () { return pricing_js_2.setCustomPricing; } });
|
|
55
|
+
Object.defineProperty(exports, "getModelPricing", { enumerable: true, get: function () { return pricing_js_2.getModelPricing; } });
|
|
56
|
+
let _config = {
|
|
57
|
+
flushIntervalMs: 10_000,
|
|
58
|
+
flushSize: 100,
|
|
59
|
+
local: false,
|
|
60
|
+
};
|
|
61
|
+
let _buffer = null;
|
|
62
|
+
const _budgets = new Map();
|
|
63
|
+
function init(config) {
|
|
64
|
+
_config = { ..._config, ...config };
|
|
65
|
+
if (config.pricing) {
|
|
66
|
+
(0, pricing_js_1.setCustomPricing)(config.pricing);
|
|
67
|
+
}
|
|
68
|
+
_buffer = new event_buffer_js_1.EventBuffer({
|
|
69
|
+
flushSize: _config.flushSize,
|
|
70
|
+
flushIntervalMs: _config.flushIntervalMs,
|
|
71
|
+
onFlush: flushEvents,
|
|
72
|
+
});
|
|
73
|
+
_buffer.start();
|
|
74
|
+
// Wire auto-patch emitter so patched clients can emit events
|
|
75
|
+
(0, auto_patch_js_1.setAutoPatchEmitter)(emitEvent);
|
|
76
|
+
}
|
|
77
|
+
function budget(workflow, rule) {
|
|
78
|
+
_budgets.set(workflow, rule);
|
|
79
|
+
}
|
|
80
|
+
async function trace(workflow, tags, fn) {
|
|
81
|
+
const budgetRule = _budgets.get(workflow);
|
|
82
|
+
const ctx = new trace_context_js_1.TraceContext(workflow, tags, budgetRule, emitEvent);
|
|
83
|
+
let success = true;
|
|
84
|
+
let error;
|
|
85
|
+
try {
|
|
86
|
+
const result = await fn(ctx);
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
success = false;
|
|
91
|
+
error = err instanceof Error ? err.message : String(err);
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
const completeEvent = {
|
|
96
|
+
type: "trace_complete",
|
|
97
|
+
traceId: ctx.traceId,
|
|
98
|
+
workflow: ctx.workflow,
|
|
99
|
+
tags: ctx.tags,
|
|
100
|
+
totalCost: ctx.totalCost,
|
|
101
|
+
llmCost: ctx.llmCost,
|
|
102
|
+
toolCost: ctx.toolCost,
|
|
103
|
+
paymentCost: ctx.paymentCost,
|
|
104
|
+
totalInputTokens: ctx.totalInputTokens,
|
|
105
|
+
totalOutputTokens: ctx.totalOutputTokens,
|
|
106
|
+
llmCalls: ctx.llmCallCount,
|
|
107
|
+
toolCalls: ctx.toolCallCount,
|
|
108
|
+
payments: ctx.paymentCount,
|
|
109
|
+
durationMs: ctx.durationMs,
|
|
110
|
+
success,
|
|
111
|
+
error,
|
|
112
|
+
timestamp: Date.now(),
|
|
113
|
+
};
|
|
114
|
+
emitEvent(completeEvent);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function flush() {
|
|
118
|
+
if (_buffer)
|
|
119
|
+
await _buffer.flush();
|
|
120
|
+
}
|
|
121
|
+
async function shutdown() {
|
|
122
|
+
if (_buffer) {
|
|
123
|
+
await _buffer.flush();
|
|
124
|
+
_buffer.stop();
|
|
125
|
+
_buffer = null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function emitEvent(event) {
|
|
129
|
+
if (_config.local) {
|
|
130
|
+
printLocal(event);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!_buffer) {
|
|
134
|
+
console.warn("AgentMeter: not initialized. Call init() before tracing. Event dropped.");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
_buffer.push(event);
|
|
138
|
+
}
|
|
139
|
+
function printLocal(event) {
|
|
140
|
+
if (event.type === "trace_complete") {
|
|
141
|
+
const { workflow, totalCost, llmCost, toolCost, paymentCost, llmCalls, toolCalls, payments, durationMs, tags } = event;
|
|
142
|
+
const customer = tags.customerId ? ` [${tags.customerId}]` : "";
|
|
143
|
+
const parts = [`LLM: $${llmCost.toFixed(4)}`];
|
|
144
|
+
if (toolCost > 0)
|
|
145
|
+
parts.push(`Tools: $${toolCost.toFixed(4)}`);
|
|
146
|
+
if (paymentCost > 0)
|
|
147
|
+
parts.push(`Payments: $${paymentCost.toFixed(4)}`);
|
|
148
|
+
console.log(`[agentmeter] ${workflow}${customer}: $${totalCost.toFixed(4)} (${parts.join(", ")}) | ` +
|
|
149
|
+
`${llmCalls} LLM, ${toolCalls} tools, ${payments} payments | ${durationMs}ms`);
|
|
150
|
+
}
|
|
151
|
+
else if (event.type === "llm" && event.traceId === "auto") {
|
|
152
|
+
console.log(`[agentmeter] auto: ${event.model} $${event.cost.toFixed(4)} | ` +
|
|
153
|
+
`${event.inputTokens}in/${event.outputTokens}out | ${event.durationMs}ms`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function flushEvents(events) {
|
|
157
|
+
if (!_config.endpoint || !_config.apiKey) {
|
|
158
|
+
for (const event of events) {
|
|
159
|
+
printLocal(event);
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const response = await fetch(`${_config.endpoint}/v1/events`, {
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers: {
|
|
166
|
+
"Content-Type": "application/json",
|
|
167
|
+
Authorization: `Bearer ${_config.apiKey}`,
|
|
168
|
+
},
|
|
169
|
+
body: JSON.stringify({ events }),
|
|
170
|
+
});
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
throw new Error(`AgentMeter API error: ${response.status}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { TraceContext } from "./trace-context.js";
|
|
2
|
+
/**
|
|
3
|
+
* MCP tool cost configuration.
|
|
4
|
+
* Users define per-server or per-tool costs.
|
|
5
|
+
*/
|
|
6
|
+
export interface MCPCostConfig {
|
|
7
|
+
/** Default cost per tool call for this server */
|
|
8
|
+
defaultCostPerCall?: number;
|
|
9
|
+
/** Cost overrides per tool name */
|
|
10
|
+
toolCosts?: Record<string, number>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Wraps an MCP client's callTool method to auto-track costs.
|
|
14
|
+
*
|
|
15
|
+
* Works with any MCP client that has a `callTool` method matching
|
|
16
|
+
* the MCP SDK signature: callTool({ name, arguments }) => Promise<result>
|
|
17
|
+
*
|
|
18
|
+
* @example Manual setup per trace:
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { trace } from "agentmeter";
|
|
21
|
+
* import { wrapMCPClient } from "agentmeter/mcp";
|
|
22
|
+
*
|
|
23
|
+
* await trace("my-workflow", {}, async (ctx) => {
|
|
24
|
+
* const tracked = wrapMCPClient(mcpClient, ctx, {
|
|
25
|
+
* defaultCostPerCall: 0.01,
|
|
26
|
+
* toolCosts: { "expensive-tool": 0.05 },
|
|
27
|
+
* });
|
|
28
|
+
* const result = await tracked.callTool({ name: "search", arguments: { q: "test" } });
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function wrapMCPClient<T extends {
|
|
33
|
+
callTool: (params: {
|
|
34
|
+
name: string;
|
|
35
|
+
arguments?: Record<string, unknown>;
|
|
36
|
+
}) => Promise<unknown>;
|
|
37
|
+
}>(client: T, ctx: TraceContext, costConfig?: MCPCostConfig): T;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a reusable MCP middleware factory.
|
|
40
|
+
* Configure once, wrap any trace context.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { createMCPMiddleware } from "agentmeter/mcp";
|
|
45
|
+
*
|
|
46
|
+
* const mcpMeter = createMCPMiddleware(mcpClient, {
|
|
47
|
+
* defaultCostPerCall: 0.01,
|
|
48
|
+
* toolCosts: { "premium-search": 0.10 },
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* // In each trace:
|
|
52
|
+
* await trace("workflow", {}, async (ctx) => {
|
|
53
|
+
* const client = mcpMeter.wrap(ctx);
|
|
54
|
+
* await client.callTool({ name: "search", arguments: {} });
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function createMCPMiddleware<T extends {
|
|
59
|
+
callTool: (params: {
|
|
60
|
+
name: string;
|
|
61
|
+
arguments?: Record<string, unknown>;
|
|
62
|
+
}) => Promise<unknown>;
|
|
63
|
+
}>(client: T, costConfig?: MCPCostConfig): {
|
|
64
|
+
wrap(ctx: TraceContext): T;
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS;IAAE,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EAE3G,MAAM,EAAE,CAAC,EACT,GAAG,EAAE,YAAY,EACjB,UAAU,CAAC,EAAE,aAAa,GACzB,CAAC,CAsCH;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,SAAS;IAAE,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EAE3G,MAAM,EAAE,CAAC,EACT,UAAU,CAAC,EAAE,aAAa;cAGd,YAAY,GAAG,CAAC;EAI7B"}
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapMCPClient = wrapMCPClient;
|
|
4
|
+
exports.createMCPMiddleware = createMCPMiddleware;
|
|
5
|
+
/**
|
|
6
|
+
* Wraps an MCP client's callTool method to auto-track costs.
|
|
7
|
+
*
|
|
8
|
+
* Works with any MCP client that has a `callTool` method matching
|
|
9
|
+
* the MCP SDK signature: callTool({ name, arguments }) => Promise<result>
|
|
10
|
+
*
|
|
11
|
+
* @example Manual setup per trace:
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { trace } from "agentmeter";
|
|
14
|
+
* import { wrapMCPClient } from "agentmeter/mcp";
|
|
15
|
+
*
|
|
16
|
+
* await trace("my-workflow", {}, async (ctx) => {
|
|
17
|
+
* const tracked = wrapMCPClient(mcpClient, ctx, {
|
|
18
|
+
* defaultCostPerCall: 0.01,
|
|
19
|
+
* toolCosts: { "expensive-tool": 0.05 },
|
|
20
|
+
* });
|
|
21
|
+
* const result = await tracked.callTool({ name: "search", arguments: { q: "test" } });
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function wrapMCPClient(client, ctx, costConfig) {
|
|
26
|
+
const original = client.callTool.bind(client);
|
|
27
|
+
const wrapped = async (params) => {
|
|
28
|
+
const toolName = `mcp:${params.name}`;
|
|
29
|
+
const cost = costConfig?.toolCosts?.[params.name]
|
|
30
|
+
?? costConfig?.defaultCostPerCall
|
|
31
|
+
?? 0;
|
|
32
|
+
const start = Date.now();
|
|
33
|
+
try {
|
|
34
|
+
const result = await original(params);
|
|
35
|
+
ctx.trackTool({
|
|
36
|
+
toolName,
|
|
37
|
+
cost,
|
|
38
|
+
costType: "mcp",
|
|
39
|
+
durationMs: Date.now() - start,
|
|
40
|
+
});
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
ctx.trackTool({
|
|
45
|
+
toolName,
|
|
46
|
+
cost,
|
|
47
|
+
costType: "mcp",
|
|
48
|
+
durationMs: Date.now() - start,
|
|
49
|
+
success: false,
|
|
50
|
+
error: err instanceof Error ? err.message : String(err),
|
|
51
|
+
});
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return new Proxy(client, {
|
|
56
|
+
get(target, prop) {
|
|
57
|
+
if (prop === "callTool")
|
|
58
|
+
return wrapped;
|
|
59
|
+
return Reflect.get(target, prop);
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Creates a reusable MCP middleware factory.
|
|
65
|
+
* Configure once, wrap any trace context.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { createMCPMiddleware } from "agentmeter/mcp";
|
|
70
|
+
*
|
|
71
|
+
* const mcpMeter = createMCPMiddleware(mcpClient, {
|
|
72
|
+
* defaultCostPerCall: 0.01,
|
|
73
|
+
* toolCosts: { "premium-search": 0.10 },
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* // In each trace:
|
|
77
|
+
* await trace("workflow", {}, async (ctx) => {
|
|
78
|
+
* const client = mcpMeter.wrap(ctx);
|
|
79
|
+
* await client.callTool({ name: "search", arguments: {} });
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
function createMCPMiddleware(client, costConfig) {
|
|
84
|
+
return {
|
|
85
|
+
wrap(ctx) {
|
|
86
|
+
return wrapMCPClient(client, ctx, costConfig);
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";;AAiCA,sCA4CC;AAsBD,kDAWC;AAjGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,aAAa,CAG3B,MAAS,EACT,GAAiB,EACjB,UAA0B;IAE1B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,KAAK,EAAE,MAA6D,EAAE,EAAE;QACtF,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,UAAU,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;eAC5C,UAAU,EAAE,kBAAkB;eAC9B,CAAC,CAAC;QAEP,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtC,GAAG,CAAC,SAAS,CAAC;gBACZ,QAAQ;gBACR,IAAI;gBACJ,QAAQ,EAAE,KAAK;gBACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAC/B,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC;gBACZ,QAAQ;gBACR,IAAI;gBACJ,QAAQ,EAAE,KAAK;gBACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAC9B,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;YACH,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,IAAI,IAAI,KAAK,UAAU;gBAAE,OAAO,OAAO,CAAC;YACxC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;KACF,CAAM,CAAC;AACV,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,mBAAmB,CAGjC,MAAS,EACT,UAA0B;IAE1B,OAAO;QACL,IAAI,CAAC,GAAiB;YACpB,OAAO,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QAChD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model pricing table — cost per 1M tokens.
|
|
3
|
+
* Updated regularly. Users can override with custom pricing.
|
|
4
|
+
*/
|
|
5
|
+
export interface ModelPricing {
|
|
6
|
+
input: number;
|
|
7
|
+
output: number;
|
|
8
|
+
cachedInput?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function setCustomPricing(pricing: Record<string, ModelPricing>): void;
|
|
11
|
+
export declare function resolveModel(model: string): string;
|
|
12
|
+
export declare function getModelPricing(model: string): ModelPricing | null;
|
|
13
|
+
export declare function calculateCost(model: string, inputTokens: number, outputTokens: number, cachedInputTokens?: number): number;
|
|
14
|
+
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAoCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,IAAI,CAE5E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAGlE;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,iBAAiB,SAAI,GACpB,MAAM,CAWR"}
|
package/dist/pricing.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Model pricing table — cost per 1M tokens.
|
|
4
|
+
* Updated regularly. Users can override with custom pricing.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.setCustomPricing = setCustomPricing;
|
|
8
|
+
exports.resolveModel = resolveModel;
|
|
9
|
+
exports.getModelPricing = getModelPricing;
|
|
10
|
+
exports.calculateCost = calculateCost;
|
|
11
|
+
// Prices in USD per 1M tokens
|
|
12
|
+
const PRICING = {
|
|
13
|
+
// Anthropic
|
|
14
|
+
"claude-opus-4": { input: 15, output: 75, cachedInput: 1.5 },
|
|
15
|
+
"claude-sonnet-4": { input: 3, output: 15, cachedInput: 0.3 },
|
|
16
|
+
"claude-haiku-3.5": { input: 0.8, output: 4, cachedInput: 0.08 },
|
|
17
|
+
// OpenAI
|
|
18
|
+
"gpt-4o": { input: 2.5, output: 10 },
|
|
19
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
20
|
+
"gpt-4-turbo": { input: 10, output: 30 },
|
|
21
|
+
"o1": { input: 15, output: 60 },
|
|
22
|
+
"o1-mini": { input: 3, output: 12 },
|
|
23
|
+
"o3-mini": { input: 1.1, output: 4.4 },
|
|
24
|
+
// Google
|
|
25
|
+
"gemini-2.0-flash": { input: 0.1, output: 0.4 },
|
|
26
|
+
"gemini-2.0-pro": { input: 1.25, output: 5 },
|
|
27
|
+
"gemini-1.5-pro": { input: 1.25, output: 5 },
|
|
28
|
+
"gemini-1.5-flash": { input: 0.075, output: 0.3 },
|
|
29
|
+
};
|
|
30
|
+
// Normalize model names to handle variants
|
|
31
|
+
const ALIASES = {
|
|
32
|
+
"claude-3-5-haiku-latest": "claude-haiku-3.5",
|
|
33
|
+
"claude-3-5-haiku-20241022": "claude-haiku-3.5",
|
|
34
|
+
"claude-sonnet-4-20250514": "claude-sonnet-4",
|
|
35
|
+
"claude-opus-4-20250514": "claude-opus-4",
|
|
36
|
+
"gpt-4o-2024-11-20": "gpt-4o",
|
|
37
|
+
"gpt-4o-mini-2024-07-18": "gpt-4o-mini",
|
|
38
|
+
};
|
|
39
|
+
let customPricing = {};
|
|
40
|
+
function setCustomPricing(pricing) {
|
|
41
|
+
customPricing = { ...customPricing, ...pricing };
|
|
42
|
+
}
|
|
43
|
+
function resolveModel(model) {
|
|
44
|
+
return ALIASES[model] ?? model;
|
|
45
|
+
}
|
|
46
|
+
function getModelPricing(model) {
|
|
47
|
+
const resolved = resolveModel(model);
|
|
48
|
+
return customPricing[resolved] ?? PRICING[resolved] ?? null;
|
|
49
|
+
}
|
|
50
|
+
function calculateCost(model, inputTokens, outputTokens, cachedInputTokens = 0) {
|
|
51
|
+
const pricing = getModelPricing(model);
|
|
52
|
+
if (!pricing)
|
|
53
|
+
return 0;
|
|
54
|
+
const inputCost = ((inputTokens - cachedInputTokens) / 1_000_000) * pricing.input;
|
|
55
|
+
const cachedCost = pricing.cachedInput
|
|
56
|
+
? (cachedInputTokens / 1_000_000) * pricing.cachedInput
|
|
57
|
+
: 0;
|
|
58
|
+
const outputCost = (outputTokens / 1_000_000) * pricing.output;
|
|
59
|
+
return inputCost + cachedCost + outputCost;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"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"}
|