tokenmeter 0.9.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 +346 -0
- package/dist/__tests__/context.test.d.ts +2 -0
- package/dist/__tests__/context.test.d.ts.map +1 -0
- package/dist/__tests__/context.test.js +94 -0
- package/dist/__tests__/context.test.js.map +1 -0
- package/dist/__tests__/elevenlabs.test.d.ts +2 -0
- package/dist/__tests__/elevenlabs.test.d.ts.map +1 -0
- package/dist/__tests__/elevenlabs.test.js +108 -0
- package/dist/__tests__/elevenlabs.test.js.map +1 -0
- package/dist/__tests__/fal.test.d.ts +2 -0
- package/dist/__tests__/fal.test.d.ts.map +1 -0
- package/dist/__tests__/fal.test.js +153 -0
- package/dist/__tests__/fal.test.js.map +1 -0
- package/dist/__tests__/pricing.test.d.ts +2 -0
- package/dist/__tests__/pricing.test.d.ts.map +1 -0
- package/dist/__tests__/pricing.test.js +76 -0
- package/dist/__tests__/pricing.test.js.map +1 -0
- package/dist/__tests__/recorder.test.d.ts +2 -0
- package/dist/__tests__/recorder.test.d.ts.map +1 -0
- package/dist/__tests__/recorder.test.js +133 -0
- package/dist/__tests__/recorder.test.js.map +1 -0
- package/dist/__tests__/storage.test.d.ts +2 -0
- package/dist/__tests__/storage.test.d.ts.map +1 -0
- package/dist/__tests__/storage.test.js +106 -0
- package/dist/__tests__/storage.test.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config.d.ts +92 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +166 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +80 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +131 -0
- package/dist/context.js.map +1 -0
- package/dist/exporter/PostgresExporter.d.ts +82 -0
- package/dist/exporter/PostgresExporter.d.ts.map +1 -0
- package/dist/exporter/PostgresExporter.js +237 -0
- package/dist/exporter/PostgresExporter.js.map +1 -0
- package/dist/exporter/index.d.ts +8 -0
- package/dist/exporter/index.d.ts.map +1 -0
- package/dist/exporter/index.js +7 -0
- package/dist/exporter/index.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation/proxy.d.ts +26 -0
- package/dist/instrumentation/proxy.d.ts.map +1 -0
- package/dist/instrumentation/proxy.js +337 -0
- package/dist/instrumentation/proxy.js.map +1 -0
- package/dist/instrumentation/strategies/index.d.ts +55 -0
- package/dist/instrumentation/strategies/index.d.ts.map +1 -0
- package/dist/instrumentation/strategies/index.js +429 -0
- package/dist/instrumentation/strategies/index.js.map +1 -0
- package/dist/integrations/express/index.d.ts +137 -0
- package/dist/integrations/express/index.d.ts.map +1 -0
- package/dist/integrations/express/index.js +186 -0
- package/dist/integrations/express/index.js.map +1 -0
- package/dist/integrations/inngest/index.d.ts +222 -0
- package/dist/integrations/inngest/index.d.ts.map +1 -0
- package/dist/integrations/inngest/index.js +223 -0
- package/dist/integrations/inngest/index.js.map +1 -0
- package/dist/integrations/langfuse/index.d.ts +170 -0
- package/dist/integrations/langfuse/index.d.ts.map +1 -0
- package/dist/integrations/langfuse/index.js +225 -0
- package/dist/integrations/langfuse/index.js.map +1 -0
- package/dist/integrations/next/index.d.ts +138 -0
- package/dist/integrations/next/index.d.ts.map +1 -0
- package/dist/integrations/next/index.js +170 -0
- package/dist/integrations/next/index.js.map +1 -0
- package/dist/integrations/nextjs/index.d.ts +198 -0
- package/dist/integrations/nextjs/index.d.ts.map +1 -0
- package/dist/integrations/nextjs/index.js +181 -0
- package/dist/integrations/nextjs/index.js.map +1 -0
- package/dist/integrations/vercel-ai/index.d.ts +288 -0
- package/dist/integrations/vercel-ai/index.d.ts.map +1 -0
- package/dist/integrations/vercel-ai/index.js +260 -0
- package/dist/integrations/vercel-ai/index.js.map +1 -0
- package/dist/logger.d.ts +58 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +89 -0
- package/dist/logger.js.map +1 -0
- package/dist/pricing/catalog.d.ts +10 -0
- package/dist/pricing/catalog.d.ts.map +1 -0
- package/dist/pricing/catalog.js +297 -0
- package/dist/pricing/catalog.js.map +1 -0
- package/dist/pricing/index.d.ts +77 -0
- package/dist/pricing/index.d.ts.map +1 -0
- package/dist/pricing/index.js +251 -0
- package/dist/pricing/index.js.map +1 -0
- package/dist/pricing/manifest.d.ts +156 -0
- package/dist/pricing/manifest.d.ts.map +1 -0
- package/dist/pricing/manifest.js +381 -0
- package/dist/pricing/manifest.js.map +1 -0
- package/dist/pricing/manifest.json +12786 -0
- package/dist/pricing/providers/anthropic.json +253 -0
- package/dist/pricing/providers/bedrock.json +341 -0
- package/dist/pricing/providers/bfl.json +220 -0
- package/dist/pricing/providers/elevenlabs.json +142 -0
- package/dist/pricing/providers/fal.json +15866 -0
- package/dist/pricing/providers/google.json +346 -0
- package/dist/pricing/providers/openai.json +1035 -0
- package/dist/pricing/schema.d.ts +102 -0
- package/dist/pricing/schema.d.ts.map +1 -0
- package/dist/pricing/schema.js +56 -0
- package/dist/pricing/schema.js.map +1 -0
- package/dist/processor/TokenMeterProcessor.d.ts +55 -0
- package/dist/processor/TokenMeterProcessor.d.ts.map +1 -0
- package/dist/processor/TokenMeterProcessor.js +132 -0
- package/dist/processor/TokenMeterProcessor.js.map +1 -0
- package/dist/query/client.d.ts +61 -0
- package/dist/query/client.d.ts.map +1 -0
- package/dist/query/client.js +206 -0
- package/dist/query/client.js.map +1 -0
- package/dist/query/index.d.ts +8 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +7 -0
- package/dist/query/index.js.map +1 -0
- package/dist/recorder.d.ts +74 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +227 -0
- package/dist/recorder.js.map +1 -0
- package/dist/sdks/anthropic.d.ts +21 -0
- package/dist/sdks/anthropic.d.ts.map +1 -0
- package/dist/sdks/anthropic.js +258 -0
- package/dist/sdks/anthropic.js.map +1 -0
- package/dist/sdks/elevenlabs.d.ts +59 -0
- package/dist/sdks/elevenlabs.d.ts.map +1 -0
- package/dist/sdks/elevenlabs.js +192 -0
- package/dist/sdks/elevenlabs.js.map +1 -0
- package/dist/sdks/fal.d.ts +102 -0
- package/dist/sdks/fal.d.ts.map +1 -0
- package/dist/sdks/fal.js +306 -0
- package/dist/sdks/fal.js.map +1 -0
- package/dist/sdks/openai.d.ts +17 -0
- package/dist/sdks/openai.d.ts.map +1 -0
- package/dist/sdks/openai.js +191 -0
- package/dist/sdks/openai.js.map +1 -0
- package/dist/storage/interface.d.ts +15 -0
- package/dist/storage/interface.d.ts.map +1 -0
- package/dist/storage/interface.js +53 -0
- package/dist/storage/interface.js.map +1 -0
- package/dist/storage/prisma.d.ts +15 -0
- package/dist/storage/prisma.d.ts.map +1 -0
- package/dist/storage/prisma.js +135 -0
- package/dist/storage/prisma.js.map +1 -0
- package/dist/types.d.ts +206 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/types.js.map +1 -0
- package/dist/vercel-ai/index.d.ts +89 -0
- package/dist/vercel-ai/index.d.ts.map +1 -0
- package/dist/vercel-ai/index.js +298 -0
- package/dist/vercel-ai/index.js.map +1 -0
- package/package.json +119 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Span Exporter
|
|
3
|
+
*
|
|
4
|
+
* Exports tokenmeter cost spans to PostgreSQL for persistence and querying.
|
|
5
|
+
*/
|
|
6
|
+
import { ExportResultCode } from "@opentelemetry/core";
|
|
7
|
+
import { TM_ATTRIBUTES } from "../types.js";
|
|
8
|
+
import { logger } from "../logger.js";
|
|
9
|
+
/**
|
|
10
|
+
* PostgreSQL exporter for tokenmeter cost spans
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
|
|
15
|
+
* import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
16
|
+
* import { PostgresExporter } from 'tokenmeter/exporter';
|
|
17
|
+
*
|
|
18
|
+
* const exporter = new PostgresExporter({
|
|
19
|
+
* connectionString: process.env.DATABASE_URL,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* const provider = new NodeTracerProvider();
|
|
23
|
+
* provider.addSpanProcessor(new BatchSpanProcessor(exporter));
|
|
24
|
+
* provider.register();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class PostgresExporter {
|
|
28
|
+
config;
|
|
29
|
+
pool = null;
|
|
30
|
+
buffer = [];
|
|
31
|
+
flushTimer = null;
|
|
32
|
+
flushPromise = null;
|
|
33
|
+
isShuttingDown = false;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = {
|
|
36
|
+
connectionString: config.connectionString,
|
|
37
|
+
tableName: config.tableName ?? "tokenmeter_events",
|
|
38
|
+
batchSize: config.batchSize ?? 100,
|
|
39
|
+
flushIntervalMs: config.flushIntervalMs ?? 5000,
|
|
40
|
+
};
|
|
41
|
+
// Start flush interval
|
|
42
|
+
this.flushTimer = setInterval(() => {
|
|
43
|
+
this.flushBuffer().catch((err) => {
|
|
44
|
+
logger.error("Error flushing buffer:", err);
|
|
45
|
+
});
|
|
46
|
+
}, this.config.flushIntervalMs);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Lazily initialize the database pool
|
|
50
|
+
*/
|
|
51
|
+
async getPool() {
|
|
52
|
+
if (this.pool) {
|
|
53
|
+
return this.pool;
|
|
54
|
+
}
|
|
55
|
+
// Dynamic import to avoid requiring pg at load time
|
|
56
|
+
const { Pool } = await import("pg");
|
|
57
|
+
this.pool = new Pool({
|
|
58
|
+
connectionString: this.config.connectionString,
|
|
59
|
+
});
|
|
60
|
+
return this.pool;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Export spans to PostgreSQL
|
|
64
|
+
*/
|
|
65
|
+
export(spans, resultCallback) {
|
|
66
|
+
if (this.isShuttingDown) {
|
|
67
|
+
resultCallback({ code: ExportResultCode.FAILED });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Filter and convert spans to cost records
|
|
71
|
+
const records = spans
|
|
72
|
+
.map((span) => this.spanToCostRecord(span))
|
|
73
|
+
.filter((record) => record !== null);
|
|
74
|
+
if (records.length === 0) {
|
|
75
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Add to buffer
|
|
79
|
+
this.buffer.push(...records);
|
|
80
|
+
// Flush if buffer is full
|
|
81
|
+
if (this.buffer.length >= this.config.batchSize) {
|
|
82
|
+
this.flushBuffer()
|
|
83
|
+
.then(() => {
|
|
84
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
85
|
+
})
|
|
86
|
+
.catch((err) => {
|
|
87
|
+
logger.error("Export error:", err);
|
|
88
|
+
resultCallback({ code: ExportResultCode.FAILED });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Convert a ReadableSpan to a CostRecord
|
|
97
|
+
* Returns null if the span doesn't have cost data
|
|
98
|
+
*/
|
|
99
|
+
spanToCostRecord(span) {
|
|
100
|
+
const attrs = span.attributes;
|
|
101
|
+
// Only export spans with tokenmeter cost data
|
|
102
|
+
const costUsd = attrs[TM_ATTRIBUTES.COST_USD];
|
|
103
|
+
const provider = attrs[TM_ATTRIBUTES.PROVIDER];
|
|
104
|
+
const model = attrs[TM_ATTRIBUTES.MODEL];
|
|
105
|
+
// Skip spans without cost data
|
|
106
|
+
if (costUsd === undefined || !provider || !model) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const spanContext = span.spanContext();
|
|
110
|
+
return {
|
|
111
|
+
id: crypto.randomUUID(),
|
|
112
|
+
traceId: spanContext.traceId,
|
|
113
|
+
spanId: spanContext.spanId,
|
|
114
|
+
provider,
|
|
115
|
+
model,
|
|
116
|
+
organizationId: attrs[TM_ATTRIBUTES.ORG_ID],
|
|
117
|
+
userId: attrs[TM_ATTRIBUTES.USER_ID],
|
|
118
|
+
costUsd,
|
|
119
|
+
inputUnits: attrs[TM_ATTRIBUTES.INPUT_UNITS],
|
|
120
|
+
outputUnits: attrs[TM_ATTRIBUTES.OUTPUT_UNITS],
|
|
121
|
+
attributes: this.extractCustomAttributes(attrs),
|
|
122
|
+
createdAt: this.hrTimeToDate(span.startTime),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Extract custom attributes (exclude standard tokenmeter attributes)
|
|
127
|
+
*/
|
|
128
|
+
extractCustomAttributes(attrs) {
|
|
129
|
+
const standardKeys = new Set(Object.values(TM_ATTRIBUTES));
|
|
130
|
+
const custom = {};
|
|
131
|
+
let hasCustom = false;
|
|
132
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
133
|
+
if (!standardKeys.has(key) && !key.startsWith("gen_ai.")) {
|
|
134
|
+
custom[key] = value;
|
|
135
|
+
hasCustom = true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return hasCustom ? custom : undefined;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Convert HrTime to Date
|
|
142
|
+
*/
|
|
143
|
+
hrTimeToDate(hrTime) {
|
|
144
|
+
const milliseconds = hrTime[0] * 1000 + hrTime[1] / 1_000_000;
|
|
145
|
+
return new Date(milliseconds);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Flush buffered records to the database
|
|
149
|
+
*/
|
|
150
|
+
async flushBuffer() {
|
|
151
|
+
// If already flushing, wait for that to complete
|
|
152
|
+
if (this.flushPromise) {
|
|
153
|
+
return this.flushPromise;
|
|
154
|
+
}
|
|
155
|
+
if (this.buffer.length === 0) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// Take current buffer and clear it
|
|
159
|
+
const records = this.buffer;
|
|
160
|
+
this.buffer = [];
|
|
161
|
+
this.flushPromise = this.insertRecords(records).finally(() => {
|
|
162
|
+
this.flushPromise = null;
|
|
163
|
+
});
|
|
164
|
+
return this.flushPromise;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Insert records into the database
|
|
168
|
+
*/
|
|
169
|
+
async insertRecords(records) {
|
|
170
|
+
if (records.length === 0) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const pool = await this.getPool();
|
|
174
|
+
const tableName = this.config.tableName;
|
|
175
|
+
// Build bulk insert query
|
|
176
|
+
const columns = [
|
|
177
|
+
"id",
|
|
178
|
+
"trace_id",
|
|
179
|
+
"span_id",
|
|
180
|
+
"provider",
|
|
181
|
+
"model",
|
|
182
|
+
"organization_id",
|
|
183
|
+
"user_id",
|
|
184
|
+
"cost_usd",
|
|
185
|
+
"input_tokens",
|
|
186
|
+
"output_tokens",
|
|
187
|
+
"metadata",
|
|
188
|
+
"created_at",
|
|
189
|
+
];
|
|
190
|
+
const values = [];
|
|
191
|
+
const placeholders = [];
|
|
192
|
+
records.forEach((record, i) => {
|
|
193
|
+
const offset = i * columns.length;
|
|
194
|
+
const rowPlaceholders = columns.map((_, j) => `$${offset + j + 1}`);
|
|
195
|
+
placeholders.push(`(${rowPlaceholders.join(", ")})`);
|
|
196
|
+
values.push(record.id, record.traceId, record.spanId, record.provider, record.model, record.organizationId ?? null, record.userId ?? null, record.costUsd, record.inputUnits ?? null, record.outputUnits ?? null, record.attributes ? JSON.stringify(record.attributes) : null, record.createdAt);
|
|
197
|
+
});
|
|
198
|
+
const query = `
|
|
199
|
+
INSERT INTO ${tableName} (${columns.join(", ")})
|
|
200
|
+
VALUES ${placeholders.join(", ")}
|
|
201
|
+
ON CONFLICT (id) DO NOTHING
|
|
202
|
+
`;
|
|
203
|
+
try {
|
|
204
|
+
await pool.query(query, values);
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
logger.error("Failed to insert records:", err);
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Shutdown the exporter
|
|
213
|
+
*/
|
|
214
|
+
async shutdown() {
|
|
215
|
+
this.isShuttingDown = true;
|
|
216
|
+
// Stop flush timer
|
|
217
|
+
if (this.flushTimer) {
|
|
218
|
+
clearInterval(this.flushTimer);
|
|
219
|
+
this.flushTimer = null;
|
|
220
|
+
}
|
|
221
|
+
// Flush remaining records
|
|
222
|
+
await this.flushBuffer();
|
|
223
|
+
// Close pool
|
|
224
|
+
if (this.pool) {
|
|
225
|
+
await this.pool.end();
|
|
226
|
+
this.pool = null;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Force flush (for testing or manual control)
|
|
231
|
+
*/
|
|
232
|
+
async forceFlush() {
|
|
233
|
+
await this.flushBuffer();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export default PostgresExporter;
|
|
237
|
+
//# sourceMappingURL=PostgresExporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresExporter.js","sourceRoot":"","sources":["../../src/exporter/PostgresExporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exporter/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exporter/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenMeter v5
|
|
3
|
+
*
|
|
4
|
+
* OpenTelemetry-native cost tracking for AI workflows.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import OpenAI from 'openai';
|
|
9
|
+
* import { monitor, withAttributes } from 'tokenmeter';
|
|
10
|
+
*
|
|
11
|
+
* // 1. Wrap your client
|
|
12
|
+
* const openai = monitor(new OpenAI({ apiKey: '...' }));
|
|
13
|
+
*
|
|
14
|
+
* // 2. Track with attributes
|
|
15
|
+
* await withAttributes({ 'org.id': 'org_123' }, async () => {
|
|
16
|
+
* await openai.chat.completions.create({
|
|
17
|
+
* model: 'gpt-4o',
|
|
18
|
+
* messages: [{ role: 'user', content: 'Hello!' }]
|
|
19
|
+
* });
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { monitor } from "./instrumentation/proxy.js";
|
|
24
|
+
export { withAttributes, withAttributesSync, getCurrentAttributes, getAttribute, extractTraceHeaders, contextFromHeaders, withExtractedContext, } from "./context.js";
|
|
25
|
+
export { TokenMeterProcessor } from "./processor/TokenMeterProcessor.js";
|
|
26
|
+
export { loadManifest, getModelPricing, calculateCost, getCachedManifest, clearManifestCache, configurePricing, getPricingConfig, setModelAliases, clearModelAliases, getModelAliases, type PricingConfig, type ModelAlias, } from "./pricing/manifest.js";
|
|
27
|
+
export type { PricingUnit, ModelPricing, ProviderPricing, PricingManifest, MonitorOptions, UsageData, ExtractionStrategy, TokenMeterAttributes, TokenMeterProcessorConfig, PostgresExporterConfig, CostRecord, CostQueryOptions, CostResult, } from "./types.js";
|
|
28
|
+
export { TM_ATTRIBUTES, GEN_AI_ATTRIBUTES } from "./types.js";
|
|
29
|
+
export { configureLogger, getLoggerConfig, resetLogger, type LogLevel, type LoggerConfig, } from "./logger.js";
|
|
30
|
+
export { strategies, findStrategy, extractUsage, openaiStrategy, anthropicStrategy, bedrockStrategy, vertexAIStrategy, falStrategy, bflStrategy, elevenlabsStrategy, vercelAIStrategy, } from "./instrumentation/strategies/index.js";
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGrD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EAEV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,eAAe,EAEf,cAAc,EACd,SAAS,EACT,kBAAkB,EAElB,oBAAoB,EAEpB,yBAAyB,EAEzB,sBAAsB,EACtB,UAAU,EAEV,gBAAgB,EAChB,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG9D,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,KAAK,QAAQ,EACb,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,uCAAuC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenMeter v5
|
|
3
|
+
*
|
|
4
|
+
* OpenTelemetry-native cost tracking for AI workflows.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import OpenAI from 'openai';
|
|
9
|
+
* import { monitor, withAttributes } from 'tokenmeter';
|
|
10
|
+
*
|
|
11
|
+
* // 1. Wrap your client
|
|
12
|
+
* const openai = monitor(new OpenAI({ apiKey: '...' }));
|
|
13
|
+
*
|
|
14
|
+
* // 2. Track with attributes
|
|
15
|
+
* await withAttributes({ 'org.id': 'org_123' }, async () => {
|
|
16
|
+
* await openai.chat.completions.create({
|
|
17
|
+
* model: 'gpt-4o',
|
|
18
|
+
* messages: [{ role: 'user', content: 'Hello!' }]
|
|
19
|
+
* });
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
// Core instrumentation
|
|
24
|
+
export { monitor } from "./instrumentation/proxy.js";
|
|
25
|
+
// Context management
|
|
26
|
+
export { withAttributes, withAttributesSync, getCurrentAttributes, getAttribute, extractTraceHeaders, contextFromHeaders, withExtractedContext, } from "./context.js";
|
|
27
|
+
// Processor
|
|
28
|
+
export { TokenMeterProcessor } from "./processor/TokenMeterProcessor.js";
|
|
29
|
+
// Pricing utilities
|
|
30
|
+
export { loadManifest, getModelPricing, calculateCost, getCachedManifest, clearManifestCache, configurePricing, getPricingConfig, setModelAliases, clearModelAliases, getModelAliases, } from "./pricing/manifest.js";
|
|
31
|
+
// Semantic conventions
|
|
32
|
+
export { TM_ATTRIBUTES, GEN_AI_ATTRIBUTES } from "./types.js";
|
|
33
|
+
// Logger configuration
|
|
34
|
+
export { configureLogger, getLoggerConfig, resetLogger, } from "./logger.js";
|
|
35
|
+
// Extraction strategies (for custom implementations)
|
|
36
|
+
export { strategies, findStrategy, extractUsage, openaiStrategy, anthropicStrategy, bedrockStrategy, vertexAIStrategy, falStrategy, bflStrategy, elevenlabsStrategy, vercelAIStrategy, } from "./instrumentation/strategies/index.js";
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,uBAAuB;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,qBAAqB;AACrB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,YAAY;AACZ,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,oBAAoB;AACpB,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAGhB,MAAM,uBAAuB,CAAC;AAyB/B,uBAAuB;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE9D,uBAAuB;AACvB,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,GAGZ,MAAM,aAAa,CAAC;AAErB,qDAAqD;AACrD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy Engine
|
|
3
|
+
*
|
|
4
|
+
* Creates a recursive Proxy that intercepts method calls and creates OTel spans.
|
|
5
|
+
* Calculates costs and adds them to spans before export.
|
|
6
|
+
*/
|
|
7
|
+
import type { MonitorOptions } from "../types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Create a monitored proxy for a client instance
|
|
10
|
+
*
|
|
11
|
+
* @param client - The SDK client instance to wrap
|
|
12
|
+
* @param options - Configuration options
|
|
13
|
+
* @returns A proxied version of the client that creates spans for method calls
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import OpenAI from 'openai';
|
|
18
|
+
* import { monitor } from 'tokenmeter';
|
|
19
|
+
*
|
|
20
|
+
* const openai = monitor(new OpenAI({ apiKey: '...' }));
|
|
21
|
+
* await openai.chat.completions.create({ model: 'gpt-4o', messages: [...] });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function monitor<T extends object>(client: T, options?: MonitorOptions): T;
|
|
25
|
+
export default monitor;
|
|
26
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/instrumentation/proxy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmBH,OAAO,KAAK,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAC;AAsQ9E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EACtC,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,cAAmB,GAC3B,CAAC,CA4IH;AAED,eAAe,OAAO,CAAC"}
|