@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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Catalog — cost extraction engine for non-LLM services.
|
|
3
|
+
*
|
|
4
|
+
* Loads the bundled service_prices.json catalog and matches HTTP requests
|
|
5
|
+
* against known service domains to extract per-request costs automatically.
|
|
6
|
+
*
|
|
7
|
+
* Implements US-035 service catalog cost extraction.
|
|
8
|
+
*/
|
|
9
|
+
/** A cost extraction definition from the catalog. */
|
|
10
|
+
export interface CostExtractionDef {
|
|
11
|
+
type: "response_body" | "response_header" | "endpoint_match" | "fixed";
|
|
12
|
+
path?: string;
|
|
13
|
+
header?: string;
|
|
14
|
+
transform?: string;
|
|
15
|
+
fallback_credits?: number;
|
|
16
|
+
units?: number;
|
|
17
|
+
}
|
|
18
|
+
/** A single service entry from the catalog JSON. */
|
|
19
|
+
export interface ServiceEntry {
|
|
20
|
+
display_name: string;
|
|
21
|
+
domains: string[];
|
|
22
|
+
endpoints?: string[];
|
|
23
|
+
category: string;
|
|
24
|
+
pricing_model: string;
|
|
25
|
+
cost_extraction: CostExtractionDef;
|
|
26
|
+
source: string;
|
|
27
|
+
last_verified: string;
|
|
28
|
+
note?: string;
|
|
29
|
+
cost_per_credit_usd?: string;
|
|
30
|
+
default_credits_per_request?: number;
|
|
31
|
+
cost_per_request_usd?: string;
|
|
32
|
+
cost_per_page_usd?: string;
|
|
33
|
+
cost_per_minute_usd?: string;
|
|
34
|
+
cost_per_compute_unit_usd?: string;
|
|
35
|
+
cost_per_message_usd?: string;
|
|
36
|
+
cost_per_email_usd?: string;
|
|
37
|
+
cost_per_second_usd?: string;
|
|
38
|
+
cost_per_search_usd?: string;
|
|
39
|
+
cost_per_query_usd?: string;
|
|
40
|
+
cost_per_read_unit_usd?: string;
|
|
41
|
+
cost_per_1k_characters_usd?: string;
|
|
42
|
+
percentage?: string;
|
|
43
|
+
fixed_fee_usd?: string;
|
|
44
|
+
}
|
|
45
|
+
/** Result of extracting cost from a service response. */
|
|
46
|
+
export interface CostExtractionResult {
|
|
47
|
+
costUsd: number;
|
|
48
|
+
confidence: string;
|
|
49
|
+
serviceName: string;
|
|
50
|
+
pricingSource: string;
|
|
51
|
+
}
|
|
52
|
+
export declare class ServiceCatalog {
|
|
53
|
+
private _entries;
|
|
54
|
+
private _overrides;
|
|
55
|
+
private _version;
|
|
56
|
+
constructor(catalogPath?: string);
|
|
57
|
+
/** Deterministic hash of the loaded catalog. */
|
|
58
|
+
get catalogVersion(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Look up a service entry by URL.
|
|
61
|
+
*
|
|
62
|
+
* Domain matching supports wildcards (e.g. `*.pinecone.io`).
|
|
63
|
+
* Endpoint matching checks if the URL pathname starts with any entry endpoint.
|
|
64
|
+
*/
|
|
65
|
+
lookup(url: string): ServiceEntry | null;
|
|
66
|
+
/**
|
|
67
|
+
* Extract cost from a service response.
|
|
68
|
+
*
|
|
69
|
+
* @param entry The matched ServiceEntry from lookup()
|
|
70
|
+
* @param headers Response headers
|
|
71
|
+
* @param body Parsed response body (or null/undefined if not available)
|
|
72
|
+
*/
|
|
73
|
+
extractCost(entry: ServiceEntry, headers: Headers, body: unknown): CostExtractionResult | null;
|
|
74
|
+
/**
|
|
75
|
+
* Register a user override for a service key. Overrides take precedence
|
|
76
|
+
* over catalog-extracted costs.
|
|
77
|
+
*/
|
|
78
|
+
registerOverride(serviceKey: string, costPerUnit: number, per: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Refresh the catalog from a remote URL.
|
|
81
|
+
*/
|
|
82
|
+
refreshFromUrl(url: string): Promise<void>;
|
|
83
|
+
private _loadFromJson;
|
|
84
|
+
private _computeCostFromUnits;
|
|
85
|
+
private _fallbackResult;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=service-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-catalog.d.ts","sourceRoot":"","sources":["../../src/pricing/service-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,iBAAiB,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AA2ID,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,UAAU,CAAgE;IAClF,OAAO,CAAC,QAAQ,CAAS;gBAEb,WAAW,CAAC,EAAE,MAAM;IAsBhC,gDAAgD;IAChD,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IA8CxC;;;;;;OAMG;IACH,WAAW,CACT,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,GACZ,oBAAoB,GAAG,IAAI;IAyF9B;;;OAGG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAI5E;;OAEG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BhD,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,qBAAqB;IAgC7B,OAAO,CAAC,eAAe;CAsBxB"}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Catalog — cost extraction engine for non-LLM services.
|
|
3
|
+
*
|
|
4
|
+
* Loads the bundled service_prices.json catalog and matches HTTP requests
|
|
5
|
+
* against known service domains to extract per-request costs automatically.
|
|
6
|
+
*
|
|
7
|
+
* Implements US-035 service catalog cost extraction.
|
|
8
|
+
*/
|
|
9
|
+
import { createHash } from "node:crypto";
|
|
10
|
+
import { createRequire } from "node:module";
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Helpers
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Check if a hostname matches a domain pattern (supports `*.example.com` wildcards).
|
|
17
|
+
*/
|
|
18
|
+
function domainMatches(hostname, pattern) {
|
|
19
|
+
if (pattern.startsWith("*.")) {
|
|
20
|
+
const suffix = pattern.slice(1); // ".example.com"
|
|
21
|
+
return hostname.endsWith(suffix) || hostname === pattern.slice(2);
|
|
22
|
+
}
|
|
23
|
+
return hostname === pattern;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Navigate a nested object by dot-separated path (e.g. "data.stats.computeUnits").
|
|
27
|
+
*/
|
|
28
|
+
function getNestedValue(obj, path) {
|
|
29
|
+
let current = obj;
|
|
30
|
+
for (const key of path.split(".")) {
|
|
31
|
+
if (current === null || current === undefined || typeof current !== "object") {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
current = current[key];
|
|
35
|
+
}
|
|
36
|
+
return current;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Apply a named transform to a raw numeric value + service entry to get costUsd.
|
|
40
|
+
*/
|
|
41
|
+
function applyTransform(transform, rawValue, entry) {
|
|
42
|
+
switch (transform) {
|
|
43
|
+
case "ms_to_seconds": {
|
|
44
|
+
const seconds = rawValue / 1000;
|
|
45
|
+
const rate = parseFloat(entry.cost_per_second_usd ?? "0");
|
|
46
|
+
if (isNaN(rate))
|
|
47
|
+
return null;
|
|
48
|
+
return seconds * rate;
|
|
49
|
+
}
|
|
50
|
+
case "ms_to_minutes": {
|
|
51
|
+
const minutes = rawValue / 60000;
|
|
52
|
+
const rate = parseFloat(entry.cost_per_minute_usd ?? "0");
|
|
53
|
+
if (isNaN(rate))
|
|
54
|
+
return null;
|
|
55
|
+
return minutes * rate;
|
|
56
|
+
}
|
|
57
|
+
case "stripe_fee": {
|
|
58
|
+
// rawValue is amount in cents; Stripe charges 2.9% + $0.30
|
|
59
|
+
const percentage = parseFloat(entry.percentage ?? "0.029");
|
|
60
|
+
if (isNaN(percentage))
|
|
61
|
+
return null;
|
|
62
|
+
const fixedFee = parseFloat(entry.fixed_fee_usd ?? "0.30");
|
|
63
|
+
if (isNaN(fixedFee))
|
|
64
|
+
return null;
|
|
65
|
+
const amountUsd = rawValue / 100;
|
|
66
|
+
return amountUsd * percentage + fixedFee;
|
|
67
|
+
}
|
|
68
|
+
default:
|
|
69
|
+
return rawValue;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the fixed per-unit cost from a service entry.
|
|
74
|
+
*/
|
|
75
|
+
function getFixedCost(entry) {
|
|
76
|
+
// Try each known cost field
|
|
77
|
+
if (entry.cost_per_request_usd !== undefined) {
|
|
78
|
+
const v = parseFloat(entry.cost_per_request_usd);
|
|
79
|
+
return isNaN(v) ? null : v;
|
|
80
|
+
}
|
|
81
|
+
if (entry.cost_per_page_usd !== undefined) {
|
|
82
|
+
const v = parseFloat(entry.cost_per_page_usd);
|
|
83
|
+
return isNaN(v) ? null : v;
|
|
84
|
+
}
|
|
85
|
+
if (entry.cost_per_search_usd !== undefined) {
|
|
86
|
+
const v = parseFloat(entry.cost_per_search_usd);
|
|
87
|
+
return isNaN(v) ? null : v;
|
|
88
|
+
}
|
|
89
|
+
if (entry.cost_per_query_usd !== undefined) {
|
|
90
|
+
const v = parseFloat(entry.cost_per_query_usd);
|
|
91
|
+
return isNaN(v) ? null : v;
|
|
92
|
+
}
|
|
93
|
+
if (entry.cost_per_message_usd !== undefined) {
|
|
94
|
+
const v = parseFloat(entry.cost_per_message_usd);
|
|
95
|
+
return isNaN(v) ? null : v;
|
|
96
|
+
}
|
|
97
|
+
if (entry.cost_per_email_usd !== undefined) {
|
|
98
|
+
const v = parseFloat(entry.cost_per_email_usd);
|
|
99
|
+
return isNaN(v) ? null : v;
|
|
100
|
+
}
|
|
101
|
+
if (entry.cost_per_second_usd !== undefined) {
|
|
102
|
+
const v = parseFloat(entry.cost_per_second_usd);
|
|
103
|
+
return isNaN(v) ? null : v;
|
|
104
|
+
}
|
|
105
|
+
if (entry.cost_per_minute_usd !== undefined) {
|
|
106
|
+
const v = parseFloat(entry.cost_per_minute_usd);
|
|
107
|
+
return isNaN(v) ? null : v;
|
|
108
|
+
}
|
|
109
|
+
if (entry.cost_per_credit_usd !== undefined) {
|
|
110
|
+
const credits = entry.default_credits_per_request ?? 1;
|
|
111
|
+
const v = parseFloat(entry.cost_per_credit_usd);
|
|
112
|
+
return isNaN(v) ? null : v * credits;
|
|
113
|
+
}
|
|
114
|
+
if (entry.cost_per_read_unit_usd !== undefined) {
|
|
115
|
+
const v = parseFloat(entry.cost_per_read_unit_usd);
|
|
116
|
+
return isNaN(v) ? null : v;
|
|
117
|
+
}
|
|
118
|
+
if (entry.cost_per_compute_unit_usd !== undefined) {
|
|
119
|
+
const v = parseFloat(entry.cost_per_compute_unit_usd);
|
|
120
|
+
return isNaN(v) ? null : v;
|
|
121
|
+
}
|
|
122
|
+
if (entry.cost_per_1k_characters_usd !== undefined) {
|
|
123
|
+
const v = parseFloat(entry.cost_per_1k_characters_usd);
|
|
124
|
+
return isNaN(v) ? null : v;
|
|
125
|
+
}
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// ServiceCatalog
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
export class ServiceCatalog {
|
|
132
|
+
_entries = new Map();
|
|
133
|
+
_overrides = new Map();
|
|
134
|
+
_version;
|
|
135
|
+
constructor(catalogPath) {
|
|
136
|
+
let raw;
|
|
137
|
+
if (catalogPath) {
|
|
138
|
+
try {
|
|
139
|
+
const content = readFileSync(catalogPath, "utf-8");
|
|
140
|
+
raw = JSON.parse(content);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Fall back to bundled catalog on any error (missing file, corrupt JSON)
|
|
144
|
+
const req = createRequire(import.meta.url);
|
|
145
|
+
raw = req("../data/service_prices.json");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const req = createRequire(import.meta.url);
|
|
150
|
+
raw = req("../data/service_prices.json");
|
|
151
|
+
}
|
|
152
|
+
this._loadFromJson(raw);
|
|
153
|
+
this._version = createHash("sha256")
|
|
154
|
+
.update(JSON.stringify(raw))
|
|
155
|
+
.digest("hex")
|
|
156
|
+
.slice(0, 12);
|
|
157
|
+
}
|
|
158
|
+
/** Deterministic hash of the loaded catalog. */
|
|
159
|
+
get catalogVersion() {
|
|
160
|
+
return this._version;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Look up a service entry by URL.
|
|
164
|
+
*
|
|
165
|
+
* Domain matching supports wildcards (e.g. `*.pinecone.io`).
|
|
166
|
+
* Endpoint matching checks if the URL pathname starts with any entry endpoint.
|
|
167
|
+
*/
|
|
168
|
+
lookup(url) {
|
|
169
|
+
let parsedUrl;
|
|
170
|
+
try {
|
|
171
|
+
parsedUrl = new URL(url);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
const hostname = parsedUrl.hostname;
|
|
177
|
+
const pathname = parsedUrl.pathname;
|
|
178
|
+
// First pass: find all entries whose domain matches
|
|
179
|
+
const candidates = [];
|
|
180
|
+
for (const [key, entry] of this._entries) {
|
|
181
|
+
for (const domain of entry.domains) {
|
|
182
|
+
if (domainMatches(hostname, domain)) {
|
|
183
|
+
candidates.push({ key, entry });
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (candidates.length === 0)
|
|
189
|
+
return null;
|
|
190
|
+
// If any candidate has endpoint restrictions, prefer exact endpoint match
|
|
191
|
+
for (const { entry } of candidates) {
|
|
192
|
+
if (entry.endpoints && entry.endpoints.length > 0) {
|
|
193
|
+
for (const ep of entry.endpoints) {
|
|
194
|
+
if (pathname.startsWith(ep)) {
|
|
195
|
+
return entry;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Return first candidate without endpoint restriction
|
|
201
|
+
for (const { entry } of candidates) {
|
|
202
|
+
if (!entry.endpoints || entry.endpoints.length === 0) {
|
|
203
|
+
return entry;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// All candidates had endpoints but none matched
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Extract cost from a service response.
|
|
211
|
+
*
|
|
212
|
+
* @param entry The matched ServiceEntry from lookup()
|
|
213
|
+
* @param headers Response headers
|
|
214
|
+
* @param body Parsed response body (or null/undefined if not available)
|
|
215
|
+
*/
|
|
216
|
+
extractCost(entry, headers, body) {
|
|
217
|
+
const extraction = entry.cost_extraction;
|
|
218
|
+
const serviceName = entry.display_name;
|
|
219
|
+
// Check for user override first
|
|
220
|
+
for (const [key, override] of this._overrides) {
|
|
221
|
+
const catalogEntry = this._entries.get(key);
|
|
222
|
+
if (catalogEntry && catalogEntry.display_name === serviceName) {
|
|
223
|
+
return {
|
|
224
|
+
costUsd: override.costPerUnit,
|
|
225
|
+
confidence: "computed",
|
|
226
|
+
serviceName,
|
|
227
|
+
pricingSource: "user_override",
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
switch (extraction.type) {
|
|
232
|
+
case "response_body": {
|
|
233
|
+
if (body === null || body === undefined) {
|
|
234
|
+
// Fall back to defaults
|
|
235
|
+
return this._fallbackResult(entry, serviceName);
|
|
236
|
+
}
|
|
237
|
+
const path = extraction.path;
|
|
238
|
+
if (!path)
|
|
239
|
+
return this._fallbackResult(entry, serviceName);
|
|
240
|
+
const rawValue = getNestedValue(body, path);
|
|
241
|
+
if (rawValue === undefined || rawValue === null) {
|
|
242
|
+
return this._fallbackResult(entry, serviceName);
|
|
243
|
+
}
|
|
244
|
+
const numValue = typeof rawValue === "number" ? rawValue : parseFloat(String(rawValue));
|
|
245
|
+
if (isNaN(numValue))
|
|
246
|
+
return this._fallbackResult(entry, serviceName);
|
|
247
|
+
let costUsd;
|
|
248
|
+
if (extraction.transform) {
|
|
249
|
+
costUsd = applyTransform(extraction.transform, numValue, entry);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
// Multiply raw value by per-unit cost
|
|
253
|
+
costUsd = this._computeCostFromUnits(numValue, entry);
|
|
254
|
+
}
|
|
255
|
+
if (costUsd === null)
|
|
256
|
+
return null;
|
|
257
|
+
return {
|
|
258
|
+
costUsd,
|
|
259
|
+
confidence: "exact",
|
|
260
|
+
serviceName,
|
|
261
|
+
pricingSource: "service_catalog",
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
case "response_header": {
|
|
265
|
+
const headerName = extraction.header;
|
|
266
|
+
if (!headerName)
|
|
267
|
+
return this._fallbackResult(entry, serviceName);
|
|
268
|
+
const headerValue = headers.get(headerName);
|
|
269
|
+
if (headerValue === null)
|
|
270
|
+
return this._fallbackResult(entry, serviceName);
|
|
271
|
+
const numValue = parseFloat(headerValue);
|
|
272
|
+
if (isNaN(numValue))
|
|
273
|
+
return null;
|
|
274
|
+
const costUsd = this._computeCostFromUnits(numValue, entry);
|
|
275
|
+
if (costUsd === null)
|
|
276
|
+
return null;
|
|
277
|
+
return {
|
|
278
|
+
costUsd,
|
|
279
|
+
confidence: "exact",
|
|
280
|
+
serviceName,
|
|
281
|
+
pricingSource: "service_catalog",
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
case "endpoint_match":
|
|
285
|
+
case "fixed": {
|
|
286
|
+
const costUsd = getFixedCost(entry);
|
|
287
|
+
if (costUsd === null)
|
|
288
|
+
return null;
|
|
289
|
+
return {
|
|
290
|
+
costUsd,
|
|
291
|
+
confidence: "computed",
|
|
292
|
+
serviceName,
|
|
293
|
+
pricingSource: "service_catalog",
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
default:
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Register a user override for a service key. Overrides take precedence
|
|
302
|
+
* over catalog-extracted costs.
|
|
303
|
+
*/
|
|
304
|
+
registerOverride(serviceKey, costPerUnit, per) {
|
|
305
|
+
this._overrides.set(serviceKey, { costPerUnit, per });
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Refresh the catalog from a remote URL.
|
|
309
|
+
*/
|
|
310
|
+
async refreshFromUrl(url) {
|
|
311
|
+
try {
|
|
312
|
+
const response = await fetch(url);
|
|
313
|
+
if (!response.ok)
|
|
314
|
+
return;
|
|
315
|
+
const text = await response.text();
|
|
316
|
+
let raw;
|
|
317
|
+
try {
|
|
318
|
+
raw = JSON.parse(text);
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
return; // Malformed JSON — keep using existing catalog
|
|
322
|
+
}
|
|
323
|
+
this._entries.clear();
|
|
324
|
+
this._loadFromJson(raw);
|
|
325
|
+
this._version = createHash("sha256")
|
|
326
|
+
.update(JSON.stringify(raw))
|
|
327
|
+
.digest("hex")
|
|
328
|
+
.slice(0, 12);
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// Network error — keep using existing catalog
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// -------------------------------------------------------------------------
|
|
335
|
+
// Private helpers
|
|
336
|
+
// -------------------------------------------------------------------------
|
|
337
|
+
_loadFromJson(raw) {
|
|
338
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
339
|
+
if (key === "_meta")
|
|
340
|
+
continue;
|
|
341
|
+
this._entries.set(key, value);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
_computeCostFromUnits(units, entry) {
|
|
345
|
+
if (entry.cost_per_credit_usd !== undefined) {
|
|
346
|
+
const rate = parseFloat(entry.cost_per_credit_usd);
|
|
347
|
+
if (isNaN(rate))
|
|
348
|
+
return null;
|
|
349
|
+
return units * rate;
|
|
350
|
+
}
|
|
351
|
+
if (entry.cost_per_read_unit_usd !== undefined) {
|
|
352
|
+
const rate = parseFloat(entry.cost_per_read_unit_usd);
|
|
353
|
+
if (isNaN(rate))
|
|
354
|
+
return null;
|
|
355
|
+
return units * rate;
|
|
356
|
+
}
|
|
357
|
+
if (entry.cost_per_compute_unit_usd !== undefined) {
|
|
358
|
+
const rate = parseFloat(entry.cost_per_compute_unit_usd);
|
|
359
|
+
if (isNaN(rate))
|
|
360
|
+
return null;
|
|
361
|
+
return units * rate;
|
|
362
|
+
}
|
|
363
|
+
if (entry.cost_per_1k_characters_usd !== undefined) {
|
|
364
|
+
const rate = parseFloat(entry.cost_per_1k_characters_usd);
|
|
365
|
+
if (isNaN(rate))
|
|
366
|
+
return null;
|
|
367
|
+
return (units / 1000) * rate;
|
|
368
|
+
}
|
|
369
|
+
if (entry.cost_per_minute_usd !== undefined) {
|
|
370
|
+
const rate = parseFloat(entry.cost_per_minute_usd);
|
|
371
|
+
if (isNaN(rate))
|
|
372
|
+
return null;
|
|
373
|
+
return units * rate;
|
|
374
|
+
}
|
|
375
|
+
// Default: multiply units by fixed cost
|
|
376
|
+
const fixedCost = getFixedCost(entry);
|
|
377
|
+
if (fixedCost === null)
|
|
378
|
+
return null;
|
|
379
|
+
return units * fixedCost;
|
|
380
|
+
}
|
|
381
|
+
_fallbackResult(entry, serviceName) {
|
|
382
|
+
const extraction = entry.cost_extraction;
|
|
383
|
+
if (extraction.fallback_credits !== undefined && entry.cost_per_credit_usd !== undefined) {
|
|
384
|
+
const rate = parseFloat(entry.cost_per_credit_usd);
|
|
385
|
+
if (isNaN(rate))
|
|
386
|
+
return null;
|
|
387
|
+
return {
|
|
388
|
+
costUsd: extraction.fallback_credits * rate,
|
|
389
|
+
confidence: "estimated",
|
|
390
|
+
serviceName,
|
|
391
|
+
pricingSource: "service_catalog",
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
// Fall back to fixed cost
|
|
395
|
+
const costUsd = getFixedCost(entry);
|
|
396
|
+
if (costUsd === null)
|
|
397
|
+
return null;
|
|
398
|
+
return {
|
|
399
|
+
costUsd,
|
|
400
|
+
confidence: costUsd > 0 ? "estimated" : "unknown",
|
|
401
|
+
serviceName,
|
|
402
|
+
pricingSource: "service_catalog",
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=service-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-catalog.js","sourceRoot":"","sources":["../../src/pricing/service-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://dexcost.io/schemas/dexcost-event.v1.json",
|
|
4
|
+
"title": "Dexcost Event v1",
|
|
5
|
+
"description": "Standard Event Schema v1 — Event payload. Represents a single cost-generating event within a task.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"event_id",
|
|
9
|
+
"task_id",
|
|
10
|
+
"event_type",
|
|
11
|
+
"occurred_at",
|
|
12
|
+
"cost_usd",
|
|
13
|
+
"cost_confidence",
|
|
14
|
+
"schema_version"
|
|
15
|
+
],
|
|
16
|
+
"additionalProperties": false,
|
|
17
|
+
"properties": {
|
|
18
|
+
"event_id": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"format": "uuid",
|
|
21
|
+
"description": "Unique identifier for the event."
|
|
22
|
+
},
|
|
23
|
+
"task_id": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"format": "uuid",
|
|
26
|
+
"description": "UUID of the parent task this event belongs to."
|
|
27
|
+
},
|
|
28
|
+
"event_type": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"enum": ["llm_call", "external_cost", "compute_cost", "retry_marker", "network", "gpu_cost", "gpu_utilization_signal"],
|
|
31
|
+
"description": "Discriminator for the event category."
|
|
32
|
+
},
|
|
33
|
+
"occurred_at": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"format": "date-time",
|
|
36
|
+
"description": "ISO-8601 timestamp when the event occurred."
|
|
37
|
+
},
|
|
38
|
+
"cost_usd": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"pattern": "^-?\\d+(\\.\\d+)?$",
|
|
41
|
+
"description": "Cost of this event in USD (Decimal as string)."
|
|
42
|
+
},
|
|
43
|
+
"cost_confidence": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"enum": ["exact", "computed", "estimated", "unknown"],
|
|
46
|
+
"description": "How trustworthy the reported cost_usd value is."
|
|
47
|
+
},
|
|
48
|
+
"pricing_source": {
|
|
49
|
+
"type": ["string", "null"],
|
|
50
|
+
"description": "Where the cost_usd figure was derived from (litellm, tokencost, provider_response, manual)."
|
|
51
|
+
},
|
|
52
|
+
"pricing_version": {
|
|
53
|
+
"type": ["string", "null"],
|
|
54
|
+
"description": "Version of the pricing data used."
|
|
55
|
+
},
|
|
56
|
+
"service_name": {
|
|
57
|
+
"type": ["string", "null"],
|
|
58
|
+
"description": "Name of the service that generated this cost event."
|
|
59
|
+
},
|
|
60
|
+
"provider": {
|
|
61
|
+
"type": ["string", "null"],
|
|
62
|
+
"description": "LLM provider name (e.g. openai, anthropic). Null for non-LLM events."
|
|
63
|
+
},
|
|
64
|
+
"model": {
|
|
65
|
+
"type": ["string", "null"],
|
|
66
|
+
"description": "LLM model identifier (e.g. gpt-4o). Null for non-LLM events."
|
|
67
|
+
},
|
|
68
|
+
"input_tokens": {
|
|
69
|
+
"type": ["integer", "null"],
|
|
70
|
+
"minimum": 0,
|
|
71
|
+
"description": "Input token count. Null for non-LLM events."
|
|
72
|
+
},
|
|
73
|
+
"output_tokens": {
|
|
74
|
+
"type": ["integer", "null"],
|
|
75
|
+
"minimum": 0,
|
|
76
|
+
"description": "Output token count. Null for non-LLM events."
|
|
77
|
+
},
|
|
78
|
+
"cached_tokens": {
|
|
79
|
+
"type": ["integer", "null"],
|
|
80
|
+
"minimum": 0,
|
|
81
|
+
"description": "Cached token count. Null for non-LLM events."
|
|
82
|
+
},
|
|
83
|
+
"latency_ms": {
|
|
84
|
+
"type": ["integer", "null"],
|
|
85
|
+
"minimum": 0,
|
|
86
|
+
"description": "Latency in milliseconds. Null for non-LLM events."
|
|
87
|
+
},
|
|
88
|
+
"is_retry": {
|
|
89
|
+
"type": "boolean",
|
|
90
|
+
"description": "Whether this event is a retry of a previous event."
|
|
91
|
+
},
|
|
92
|
+
"retry_reason": {
|
|
93
|
+
"type": ["string", "null"],
|
|
94
|
+
"description": "Reason for the retry (rate_limit, timeout, parse_error, 5xx)."
|
|
95
|
+
},
|
|
96
|
+
"retry_of": {
|
|
97
|
+
"type": ["string", "null"],
|
|
98
|
+
"format": "uuid",
|
|
99
|
+
"description": "UUID of the original event this is a retry of."
|
|
100
|
+
},
|
|
101
|
+
"details": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"description": "Extensible type-specific details."
|
|
104
|
+
},
|
|
105
|
+
"schema_version": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"const": "1",
|
|
108
|
+
"description": "Schema version — always '1' for v1 payloads."
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|