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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -0
  3. package/dist/__tests__/context.test.d.ts +2 -0
  4. package/dist/__tests__/context.test.d.ts.map +1 -0
  5. package/dist/__tests__/context.test.js +94 -0
  6. package/dist/__tests__/context.test.js.map +1 -0
  7. package/dist/__tests__/elevenlabs.test.d.ts +2 -0
  8. package/dist/__tests__/elevenlabs.test.d.ts.map +1 -0
  9. package/dist/__tests__/elevenlabs.test.js +108 -0
  10. package/dist/__tests__/elevenlabs.test.js.map +1 -0
  11. package/dist/__tests__/fal.test.d.ts +2 -0
  12. package/dist/__tests__/fal.test.d.ts.map +1 -0
  13. package/dist/__tests__/fal.test.js +153 -0
  14. package/dist/__tests__/fal.test.js.map +1 -0
  15. package/dist/__tests__/pricing.test.d.ts +2 -0
  16. package/dist/__tests__/pricing.test.d.ts.map +1 -0
  17. package/dist/__tests__/pricing.test.js +76 -0
  18. package/dist/__tests__/pricing.test.js.map +1 -0
  19. package/dist/__tests__/recorder.test.d.ts +2 -0
  20. package/dist/__tests__/recorder.test.d.ts.map +1 -0
  21. package/dist/__tests__/recorder.test.js +133 -0
  22. package/dist/__tests__/recorder.test.js.map +1 -0
  23. package/dist/__tests__/storage.test.d.ts +2 -0
  24. package/dist/__tests__/storage.test.d.ts.map +1 -0
  25. package/dist/__tests__/storage.test.js +106 -0
  26. package/dist/__tests__/storage.test.js.map +1 -0
  27. package/dist/client/index.d.ts +8 -0
  28. package/dist/client/index.d.ts.map +1 -0
  29. package/dist/client/index.js +7 -0
  30. package/dist/client/index.js.map +1 -0
  31. package/dist/config.d.ts +92 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +166 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/context.d.ts +80 -0
  36. package/dist/context.d.ts.map +1 -0
  37. package/dist/context.js +131 -0
  38. package/dist/context.js.map +1 -0
  39. package/dist/exporter/PostgresExporter.d.ts +82 -0
  40. package/dist/exporter/PostgresExporter.d.ts.map +1 -0
  41. package/dist/exporter/PostgresExporter.js +237 -0
  42. package/dist/exporter/PostgresExporter.js.map +1 -0
  43. package/dist/exporter/index.d.ts +8 -0
  44. package/dist/exporter/index.d.ts.map +1 -0
  45. package/dist/exporter/index.js +7 -0
  46. package/dist/exporter/index.js.map +1 -0
  47. package/dist/index.d.ts +31 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +37 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/instrumentation/proxy.d.ts +26 -0
  52. package/dist/instrumentation/proxy.d.ts.map +1 -0
  53. package/dist/instrumentation/proxy.js +337 -0
  54. package/dist/instrumentation/proxy.js.map +1 -0
  55. package/dist/instrumentation/strategies/index.d.ts +55 -0
  56. package/dist/instrumentation/strategies/index.d.ts.map +1 -0
  57. package/dist/instrumentation/strategies/index.js +429 -0
  58. package/dist/instrumentation/strategies/index.js.map +1 -0
  59. package/dist/integrations/express/index.d.ts +137 -0
  60. package/dist/integrations/express/index.d.ts.map +1 -0
  61. package/dist/integrations/express/index.js +186 -0
  62. package/dist/integrations/express/index.js.map +1 -0
  63. package/dist/integrations/inngest/index.d.ts +222 -0
  64. package/dist/integrations/inngest/index.d.ts.map +1 -0
  65. package/dist/integrations/inngest/index.js +223 -0
  66. package/dist/integrations/inngest/index.js.map +1 -0
  67. package/dist/integrations/langfuse/index.d.ts +170 -0
  68. package/dist/integrations/langfuse/index.d.ts.map +1 -0
  69. package/dist/integrations/langfuse/index.js +225 -0
  70. package/dist/integrations/langfuse/index.js.map +1 -0
  71. package/dist/integrations/next/index.d.ts +138 -0
  72. package/dist/integrations/next/index.d.ts.map +1 -0
  73. package/dist/integrations/next/index.js +170 -0
  74. package/dist/integrations/next/index.js.map +1 -0
  75. package/dist/integrations/nextjs/index.d.ts +198 -0
  76. package/dist/integrations/nextjs/index.d.ts.map +1 -0
  77. package/dist/integrations/nextjs/index.js +181 -0
  78. package/dist/integrations/nextjs/index.js.map +1 -0
  79. package/dist/integrations/vercel-ai/index.d.ts +288 -0
  80. package/dist/integrations/vercel-ai/index.d.ts.map +1 -0
  81. package/dist/integrations/vercel-ai/index.js +260 -0
  82. package/dist/integrations/vercel-ai/index.js.map +1 -0
  83. package/dist/logger.d.ts +58 -0
  84. package/dist/logger.d.ts.map +1 -0
  85. package/dist/logger.js +89 -0
  86. package/dist/logger.js.map +1 -0
  87. package/dist/pricing/catalog.d.ts +10 -0
  88. package/dist/pricing/catalog.d.ts.map +1 -0
  89. package/dist/pricing/catalog.js +297 -0
  90. package/dist/pricing/catalog.js.map +1 -0
  91. package/dist/pricing/index.d.ts +77 -0
  92. package/dist/pricing/index.d.ts.map +1 -0
  93. package/dist/pricing/index.js +251 -0
  94. package/dist/pricing/index.js.map +1 -0
  95. package/dist/pricing/manifest.d.ts +156 -0
  96. package/dist/pricing/manifest.d.ts.map +1 -0
  97. package/dist/pricing/manifest.js +381 -0
  98. package/dist/pricing/manifest.js.map +1 -0
  99. package/dist/pricing/manifest.json +12786 -0
  100. package/dist/pricing/providers/anthropic.json +253 -0
  101. package/dist/pricing/providers/bedrock.json +341 -0
  102. package/dist/pricing/providers/bfl.json +220 -0
  103. package/dist/pricing/providers/elevenlabs.json +142 -0
  104. package/dist/pricing/providers/fal.json +15866 -0
  105. package/dist/pricing/providers/google.json +346 -0
  106. package/dist/pricing/providers/openai.json +1035 -0
  107. package/dist/pricing/schema.d.ts +102 -0
  108. package/dist/pricing/schema.d.ts.map +1 -0
  109. package/dist/pricing/schema.js +56 -0
  110. package/dist/pricing/schema.js.map +1 -0
  111. package/dist/processor/TokenMeterProcessor.d.ts +55 -0
  112. package/dist/processor/TokenMeterProcessor.d.ts.map +1 -0
  113. package/dist/processor/TokenMeterProcessor.js +132 -0
  114. package/dist/processor/TokenMeterProcessor.js.map +1 -0
  115. package/dist/query/client.d.ts +61 -0
  116. package/dist/query/client.d.ts.map +1 -0
  117. package/dist/query/client.js +206 -0
  118. package/dist/query/client.js.map +1 -0
  119. package/dist/query/index.d.ts +8 -0
  120. package/dist/query/index.d.ts.map +1 -0
  121. package/dist/query/index.js +7 -0
  122. package/dist/query/index.js.map +1 -0
  123. package/dist/recorder.d.ts +74 -0
  124. package/dist/recorder.d.ts.map +1 -0
  125. package/dist/recorder.js +227 -0
  126. package/dist/recorder.js.map +1 -0
  127. package/dist/sdks/anthropic.d.ts +21 -0
  128. package/dist/sdks/anthropic.d.ts.map +1 -0
  129. package/dist/sdks/anthropic.js +258 -0
  130. package/dist/sdks/anthropic.js.map +1 -0
  131. package/dist/sdks/elevenlabs.d.ts +59 -0
  132. package/dist/sdks/elevenlabs.d.ts.map +1 -0
  133. package/dist/sdks/elevenlabs.js +192 -0
  134. package/dist/sdks/elevenlabs.js.map +1 -0
  135. package/dist/sdks/fal.d.ts +102 -0
  136. package/dist/sdks/fal.d.ts.map +1 -0
  137. package/dist/sdks/fal.js +306 -0
  138. package/dist/sdks/fal.js.map +1 -0
  139. package/dist/sdks/openai.d.ts +17 -0
  140. package/dist/sdks/openai.d.ts.map +1 -0
  141. package/dist/sdks/openai.js +191 -0
  142. package/dist/sdks/openai.js.map +1 -0
  143. package/dist/storage/interface.d.ts +15 -0
  144. package/dist/storage/interface.d.ts.map +1 -0
  145. package/dist/storage/interface.js +53 -0
  146. package/dist/storage/interface.js.map +1 -0
  147. package/dist/storage/prisma.d.ts +15 -0
  148. package/dist/storage/prisma.d.ts.map +1 -0
  149. package/dist/storage/prisma.js +135 -0
  150. package/dist/storage/prisma.js.map +1 -0
  151. package/dist/types.d.ts +206 -0
  152. package/dist/types.d.ts.map +1 -0
  153. package/dist/types.js +45 -0
  154. package/dist/types.js.map +1 -0
  155. package/dist/vercel-ai/index.d.ts +89 -0
  156. package/dist/vercel-ai/index.d.ts.map +1 -0
  157. package/dist/vercel-ai/index.js +298 -0
  158. package/dist/vercel-ai/index.js.map +1 -0
  159. package/package.json +119 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,74 @@
1
+ import type { RecordEventInput, TrackCostInput } from "./types.js";
2
+ /**
3
+ * Record a cost event (called by SDK wrappers)
4
+ */
5
+ export declare function recordEvent(input: RecordEventInput): void;
6
+ /**
7
+ * Manually track a cost event for custom or unsupported providers.
8
+ *
9
+ * Use this when you're calling an AI provider that doesn't have a tokenmeter
10
+ * SDK wrapper, or when you need to track custom costs.
11
+ *
12
+ * @param input - The cost event details
13
+ * @param input.provider - The provider name (e.g., "custom-provider")
14
+ * @param input.model - The model identifier
15
+ * @param input.costUsd - The cost in USD
16
+ * @param input.operation - Optional operation type (e.g., "chat", "embed")
17
+ * @param input.inputTokens - Optional input token count
18
+ * @param input.outputTokens - Optional output token count
19
+ * @param input.status - Optional status ("success", "failed", "partial")
20
+ * @param input.billable - Whether this cost is billable (default: true)
21
+ * @param input.errorMessage - Error message if status is "failed"
22
+ * @param input.metadata - Optional custom metadata
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * await withCostTrace({ identifier: "user_123" }, async () => {
27
+ * const response = await customProvider.generate({ ... });
28
+ *
29
+ * trackCost({
30
+ * provider: "custom-provider",
31
+ * model: "custom-model",
32
+ * costUsd: response.usage.totalCost,
33
+ * inputTokens: response.usage.input,
34
+ * outputTokens: response.usage.output,
35
+ * });
36
+ * });
37
+ * ```
38
+ */
39
+ export declare function trackCost(input: TrackCostInput): void;
40
+ /**
41
+ * Flush all pending events to storage immediately.
42
+ *
43
+ * By default, tokenmeter batches events and flushes them periodically.
44
+ * Call this function to force an immediate flush, useful for:
45
+ * - Before process exit
46
+ * - After completing a batch of operations
47
+ * - When you need to ensure events are persisted
48
+ *
49
+ * @returns A promise that resolves when all pending events are written
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * await withCostTrace({ identifier: "user_123" }, async () => {
54
+ * await openai.chat.completions.create({ ... });
55
+ * });
56
+ *
57
+ * // Ensure all events are written before continuing
58
+ * await flush();
59
+ * ```
60
+ */
61
+ export declare function flush(): Promise<void>;
62
+ /**
63
+ * Shutdown handler - flushes events and cleans up
64
+ */
65
+ export declare function shutdownRecorder(): Promise<void>;
66
+ /**
67
+ * Initialize the recorder (called from init())
68
+ */
69
+ export declare function initRecorder(): void;
70
+ /**
71
+ * Register process exit handlers for graceful shutdown
72
+ */
73
+ export declare function registerShutdownHooks(): void;
74
+ //# sourceMappingURL=recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA6E9E;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAuDzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAarD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAsB5C"}
@@ -0,0 +1,227 @@
1
+ import { getStorage, getBatching, isInitialized } from "./config.js";
2
+ import { getCurrentContext, addCostToContext, addEventToContext, } from "./context.js";
3
+ /**
4
+ * Event queue for batching
5
+ */
6
+ let eventQueue = [];
7
+ let flushTimer = null;
8
+ let isShuttingDown = false;
9
+ let isFlushing = false;
10
+ let flushPromise = null;
11
+ let shutdownHooksRegistered = false;
12
+ /**
13
+ * Start the flush timer if batching is enabled
14
+ */
15
+ function startFlushTimer() {
16
+ const batching = getBatching();
17
+ if (batching.enabled && !flushTimer && !isShuttingDown) {
18
+ flushTimer = setInterval(() => {
19
+ void flushInternal();
20
+ }, batching.flushInterval);
21
+ flushTimer.unref(); // Don't keep process alive just for flushing
22
+ }
23
+ }
24
+ /**
25
+ * Stop the flush timer
26
+ */
27
+ function stopFlushTimer() {
28
+ if (flushTimer) {
29
+ clearInterval(flushTimer);
30
+ flushTimer = null;
31
+ }
32
+ }
33
+ /**
34
+ * Internal flush function with mutex to prevent race conditions
35
+ */
36
+ async function flushInternal() {
37
+ // If already flushing, wait for the current flush to complete
38
+ if (isFlushing && flushPromise) {
39
+ await flushPromise;
40
+ // After waiting, check if there are still events to flush
41
+ if (eventQueue.length === 0)
42
+ return;
43
+ }
44
+ if (eventQueue.length === 0)
45
+ return;
46
+ isFlushing = true;
47
+ // Create the flush promise
48
+ flushPromise = (async () => {
49
+ const events = eventQueue;
50
+ eventQueue = [];
51
+ try {
52
+ const storage = getStorage();
53
+ await storage.writeBatch(events);
54
+ }
55
+ catch (error) {
56
+ // Put events back in queue on failure (at the front)
57
+ eventQueue = [...events, ...eventQueue];
58
+ console.error("[tokenmeter] Failed to flush events:", error);
59
+ }
60
+ finally {
61
+ isFlushing = false;
62
+ flushPromise = null;
63
+ }
64
+ })();
65
+ await flushPromise;
66
+ }
67
+ /**
68
+ * Record a cost event (called by SDK wrappers)
69
+ */
70
+ export function recordEvent(input) {
71
+ if (!isInitialized()) {
72
+ console.warn("[tokenmeter] Not initialized. Call init() before recording events.");
73
+ return;
74
+ }
75
+ const context = getCurrentContext();
76
+ if (!context) {
77
+ console.warn("[tokenmeter] No trace context. Wrap your code in withCostTrace().");
78
+ return;
79
+ }
80
+ const event = {
81
+ identifier: context.identifier,
82
+ secondaryIdentifier: context.secondaryIdentifier,
83
+ requestId: context.requestId,
84
+ workflowId: context.workflowId,
85
+ workflowType: context.workflowType,
86
+ provider: input.provider,
87
+ model: input.model,
88
+ operation: input.operation,
89
+ inputTokens: input.inputTokens,
90
+ outputTokens: input.outputTokens,
91
+ costUsd: input.costUsd ?? 0,
92
+ status: input.status ?? "success",
93
+ billable: input.billable ?? true,
94
+ errorMessage: input.errorMessage,
95
+ metadata: { ...context.metadata, ...input.metadata },
96
+ createdAt: new Date(),
97
+ };
98
+ // Update context with cost
99
+ addCostToContext(event.costUsd);
100
+ addEventToContext(event);
101
+ // Add to queue
102
+ const batching = getBatching();
103
+ if (batching.enabled) {
104
+ eventQueue.push(event);
105
+ // Start timer if not running
106
+ startFlushTimer();
107
+ // Flush if batch size reached
108
+ if (eventQueue.length >= batching.maxBatchSize) {
109
+ void flushInternal();
110
+ }
111
+ }
112
+ else {
113
+ // Write immediately
114
+ void getStorage().writeEvent(event);
115
+ }
116
+ }
117
+ /**
118
+ * Manually track a cost event for custom or unsupported providers.
119
+ *
120
+ * Use this when you're calling an AI provider that doesn't have a tokenmeter
121
+ * SDK wrapper, or when you need to track custom costs.
122
+ *
123
+ * @param input - The cost event details
124
+ * @param input.provider - The provider name (e.g., "custom-provider")
125
+ * @param input.model - The model identifier
126
+ * @param input.costUsd - The cost in USD
127
+ * @param input.operation - Optional operation type (e.g., "chat", "embed")
128
+ * @param input.inputTokens - Optional input token count
129
+ * @param input.outputTokens - Optional output token count
130
+ * @param input.status - Optional status ("success", "failed", "partial")
131
+ * @param input.billable - Whether this cost is billable (default: true)
132
+ * @param input.errorMessage - Error message if status is "failed"
133
+ * @param input.metadata - Optional custom metadata
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * await withCostTrace({ identifier: "user_123" }, async () => {
138
+ * const response = await customProvider.generate({ ... });
139
+ *
140
+ * trackCost({
141
+ * provider: "custom-provider",
142
+ * model: "custom-model",
143
+ * costUsd: response.usage.totalCost,
144
+ * inputTokens: response.usage.input,
145
+ * outputTokens: response.usage.output,
146
+ * });
147
+ * });
148
+ * ```
149
+ */
150
+ export function trackCost(input) {
151
+ recordEvent({
152
+ provider: input.provider,
153
+ model: input.model,
154
+ operation: input.operation,
155
+ inputTokens: input.inputTokens,
156
+ outputTokens: input.outputTokens,
157
+ costUsd: input.costUsd,
158
+ status: input.status,
159
+ billable: input.billable,
160
+ errorMessage: input.errorMessage,
161
+ metadata: input.metadata,
162
+ });
163
+ }
164
+ /**
165
+ * Flush all pending events to storage immediately.
166
+ *
167
+ * By default, tokenmeter batches events and flushes them periodically.
168
+ * Call this function to force an immediate flush, useful for:
169
+ * - Before process exit
170
+ * - After completing a batch of operations
171
+ * - When you need to ensure events are persisted
172
+ *
173
+ * @returns A promise that resolves when all pending events are written
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * await withCostTrace({ identifier: "user_123" }, async () => {
178
+ * await openai.chat.completions.create({ ... });
179
+ * });
180
+ *
181
+ * // Ensure all events are written before continuing
182
+ * await flush();
183
+ * ```
184
+ */
185
+ export async function flush() {
186
+ stopFlushTimer();
187
+ await flushInternal();
188
+ }
189
+ /**
190
+ * Shutdown handler - flushes events and cleans up
191
+ */
192
+ export async function shutdownRecorder() {
193
+ isShuttingDown = true;
194
+ stopFlushTimer();
195
+ await flushInternal();
196
+ }
197
+ /**
198
+ * Initialize the recorder (called from init())
199
+ */
200
+ export function initRecorder() {
201
+ registerShutdownHooks();
202
+ }
203
+ /**
204
+ * Register process exit handlers for graceful shutdown
205
+ */
206
+ export function registerShutdownHooks() {
207
+ // Only register once to avoid memory leak warnings
208
+ if (shutdownHooksRegistered)
209
+ return;
210
+ const batching = getBatching();
211
+ if (!batching.flushOnExit)
212
+ return;
213
+ shutdownHooksRegistered = true;
214
+ const handleShutdown = async (signal) => {
215
+ console.log(`[tokenmeter] Received ${signal}, flushing events...`);
216
+ await shutdownRecorder();
217
+ process.exit(0);
218
+ };
219
+ process.on("SIGTERM", () => void handleShutdown("SIGTERM"));
220
+ process.on("SIGINT", () => void handleShutdown("SIGINT"));
221
+ // Handle beforeExit for graceful shutdown
222
+ process.on("beforeExit", () => {
223
+ void flushInternal();
224
+ });
225
+ }
226
+ // Shutdown hooks are now registered via initRecorder() called from init()
227
+ //# sourceMappingURL=recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,IAAI,UAAU,GAAgB,EAAE,CAAC;AACjC,IAAI,UAAU,GAA0B,IAAI,CAAC;AAC7C,IAAI,cAAc,GAAG,KAAK,CAAC;AAC3B,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,IAAI,YAAY,GAAyB,IAAI,CAAC;AAC9C,IAAI,uBAAuB,GAAG,KAAK,CAAC;AAEpC;;GAEG;AACH,SAAS,eAAe;IACtB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,QAAQ,CAAC,OAAO,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,EAAE,CAAC;QACvD,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,KAAK,aAAa,EAAE,CAAC;QACvB,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC3B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,6CAA6C;IACnE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,aAAa,CAAC,UAAU,CAAC,CAAC;QAC1B,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa;IAC1B,8DAA8D;IAC9D,IAAI,UAAU,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,YAAY,CAAC;QACnB,0DAA0D;QAC1D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;IACtC,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEpC,UAAU,GAAG,IAAI,CAAC;IAElB,2BAA2B;IAC3B,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC;QAC1B,UAAU,GAAG,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;YAC7B,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qDAAqD;YACrD,UAAU,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;gBAAS,CAAC;YACT,UAAU,GAAG,KAAK,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,MAAM,YAAY,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,oEAAoE,CACrE,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,mEAAmE,CACpE,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAc;QACvB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;QAChD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC;QAC3B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,SAAS;QACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;QAChC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE;QACpD,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC;IAEF,2BAA2B;IAC3B,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAEzB,eAAe;IACf,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEvB,6BAA6B;QAC7B,eAAe,EAAE,CAAC;QAElB,8BAA8B;QAC9B,IAAI,UAAU,CAAC,MAAM,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;YAC/C,KAAK,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,oBAAoB;QACpB,KAAK,UAAU,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,WAAW,CAAC;QACV,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,cAAc,EAAE,CAAC;IACjB,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,cAAc,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,CAAC;IACjB,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,qBAAqB,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,mDAAmD;IACnD,IAAI,uBAAuB;QAAE,OAAO;IAEpC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ,CAAC,WAAW;QAAE,OAAO;IAElC,uBAAuB,GAAG,IAAI,CAAC;IAE/B,MAAM,cAAc,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QAC7D,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,sBAAsB,CAAC,CAAC;QACnE,MAAM,gBAAgB,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE1D,0CAA0C;IAC1C,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;QAC5B,KAAK,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,0EAA0E"}
@@ -0,0 +1,21 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import type { ClientOptions } from "@anthropic-ai/sdk";
3
+ /**
4
+ * Wrapped Anthropic client that automatically tracks costs
5
+ */
6
+ export declare class TrackedAnthropic extends Anthropic {
7
+ constructor(opts?: ClientOptions);
8
+ }
9
+ /**
10
+ * Create a tracked Anthropic client
11
+ */
12
+ export declare function createAnthropic(opts?: ClientOptions): TrackedAnthropic;
13
+ /**
14
+ * Wrap an existing Anthropic client to track costs
15
+ */
16
+ export declare function trackAnthropic<T extends Anthropic>(client: T): T;
17
+ /**
18
+ * Default export - a function to create tracked clients
19
+ */
20
+ export default createAnthropic;
21
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/sdks/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAmUvD;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,SAAS;gBACjC,IAAI,CAAC,EAAE,aAAa;CAQjC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,gBAAgB,CAEtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAIhE;AAED;;GAEG;AACH,eAAe,eAAe,CAAC"}
@@ -0,0 +1,258 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import { recordEvent } from "../recorder.js";
3
+ import { getPricing, resolveModel } from "../config.js";
4
+ import { calculateCost } from "../pricing/index.js";
5
+ /**
6
+ * Normalize model name to match pricing catalog format
7
+ */
8
+ function normalizeModel(model) {
9
+ // Add anthropic/ prefix if not present
10
+ if (!model.startsWith("anthropic/")) {
11
+ return `anthropic/${model}`;
12
+ }
13
+ return model;
14
+ }
15
+ /**
16
+ * Create a tracked messages API
17
+ */
18
+ function createTrackedMessages(messages) {
19
+ const originalCreate = messages.create.bind(messages);
20
+ const originalStream = messages.stream.bind(messages);
21
+ async function trackedCreate(body, options) {
22
+ const startTime = Date.now();
23
+ const model = resolveModel(body.model);
24
+ const normalizedModel = normalizeModel(model);
25
+ if (body.stream) {
26
+ // Streaming request via create()
27
+ try {
28
+ const stream = (await originalCreate(body, options));
29
+ return wrapRawStream(stream, normalizedModel, startTime);
30
+ }
31
+ catch (error) {
32
+ recordEvent({
33
+ provider: "anthropic",
34
+ model: normalizedModel,
35
+ operation: "messages",
36
+ status: "failed",
37
+ billable: false,
38
+ errorMessage: error instanceof Error ? error.message : String(error),
39
+ costUsd: 0,
40
+ metadata: {
41
+ durationMs: Date.now() - startTime,
42
+ },
43
+ });
44
+ throw error;
45
+ }
46
+ }
47
+ else {
48
+ // Non-streaming request
49
+ try {
50
+ const response = (await originalCreate(body, options));
51
+ const inputTokens = response.usage.input_tokens;
52
+ const outputTokens = response.usage.output_tokens;
53
+ const cacheCreationTokens = response.usage
54
+ .cache_creation_input_tokens || 0;
55
+ const cacheReadTokens = response.usage
56
+ .cache_read_input_tokens || 0;
57
+ const pricing = getPricing();
58
+ const cost = calculateCost(normalizedModel, inputTokens, outputTokens, pricing, cacheReadTokens);
59
+ recordEvent({
60
+ provider: "anthropic",
61
+ model: normalizedModel,
62
+ operation: "messages",
63
+ inputTokens,
64
+ outputTokens,
65
+ costUsd: cost,
66
+ status: "success",
67
+ metadata: {
68
+ durationMs: Date.now() - startTime,
69
+ stopReason: response.stop_reason,
70
+ cacheCreationTokens: cacheCreationTokens > 0 ? cacheCreationTokens : undefined,
71
+ cacheReadTokens: cacheReadTokens > 0 ? cacheReadTokens : undefined,
72
+ },
73
+ });
74
+ return response;
75
+ }
76
+ catch (error) {
77
+ recordEvent({
78
+ provider: "anthropic",
79
+ model: normalizedModel,
80
+ operation: "messages",
81
+ status: "failed",
82
+ billable: false,
83
+ errorMessage: error instanceof Error ? error.message : String(error),
84
+ costUsd: 0,
85
+ metadata: {
86
+ durationMs: Date.now() - startTime,
87
+ },
88
+ });
89
+ throw error;
90
+ }
91
+ }
92
+ }
93
+ // Wrap the stream method (returns MessageStream helper)
94
+ function trackedStream(body, options) {
95
+ const startTime = Date.now();
96
+ const model = resolveModel(body.model);
97
+ const normalizedModel = normalizeModel(model);
98
+ const messageStream = originalStream(body, options);
99
+ // Track when the stream completes
100
+ messageStream
101
+ .finalMessage()
102
+ .then((message) => {
103
+ const inputTokens = message.usage.input_tokens;
104
+ const outputTokens = message.usage.output_tokens;
105
+ const cacheCreationTokens = message.usage
106
+ .cache_creation_input_tokens || 0;
107
+ const cacheReadTokens = message.usage
108
+ .cache_read_input_tokens || 0;
109
+ const pricing = getPricing();
110
+ const cost = calculateCost(normalizedModel, inputTokens, outputTokens, pricing, cacheReadTokens);
111
+ recordEvent({
112
+ provider: "anthropic",
113
+ model: normalizedModel,
114
+ operation: "messages",
115
+ inputTokens,
116
+ outputTokens,
117
+ costUsd: cost,
118
+ status: "success",
119
+ metadata: {
120
+ durationMs: Date.now() - startTime,
121
+ stopReason: message.stop_reason,
122
+ streamed: true,
123
+ cacheCreationTokens: cacheCreationTokens > 0 ? cacheCreationTokens : undefined,
124
+ cacheReadTokens: cacheReadTokens > 0 ? cacheReadTokens : undefined,
125
+ },
126
+ });
127
+ })
128
+ .catch((error) => {
129
+ recordEvent({
130
+ provider: "anthropic",
131
+ model: normalizedModel,
132
+ operation: "messages",
133
+ status: "failed",
134
+ billable: false,
135
+ errorMessage: error instanceof Error ? error.message : String(error),
136
+ costUsd: 0,
137
+ metadata: {
138
+ durationMs: Date.now() - startTime,
139
+ streamed: true,
140
+ },
141
+ });
142
+ });
143
+ return messageStream;
144
+ }
145
+ // Create result with wrapped methods
146
+ const result = Object.create(messages);
147
+ result.create = trackedCreate;
148
+ result.stream = trackedStream;
149
+ return result;
150
+ }
151
+ /**
152
+ * Wrap a raw stream (from create with stream: true) to track usage
153
+ */
154
+ function wrapRawStream(stream, model, startTime) {
155
+ let inputTokens = 0;
156
+ let outputTokens = 0;
157
+ let stopReason = null;
158
+ let cacheCreationTokens = 0;
159
+ let cacheReadTokens = 0;
160
+ const originalIterator = stream[Symbol.asyncIterator].bind(stream);
161
+ const wrappedIterator = async function* () {
162
+ try {
163
+ for await (const event of { [Symbol.asyncIterator]: originalIterator }) {
164
+ // Track usage from events
165
+ if (event.type === "message_start" && event.message?.usage) {
166
+ inputTokens = event.message.usage.input_tokens;
167
+ const usage = event.message.usage;
168
+ cacheCreationTokens = usage.cache_creation_input_tokens || 0;
169
+ cacheReadTokens = usage.cache_read_input_tokens || 0;
170
+ }
171
+ if (event.type === "message_delta") {
172
+ if (event.usage) {
173
+ outputTokens = event.usage.output_tokens;
174
+ }
175
+ if (event.delta?.stop_reason) {
176
+ stopReason = event.delta.stop_reason;
177
+ }
178
+ }
179
+ yield event;
180
+ }
181
+ // Stream completed successfully
182
+ const pricing = getPricing();
183
+ const cost = calculateCost(model, inputTokens, outputTokens, pricing, cacheReadTokens);
184
+ recordEvent({
185
+ provider: "anthropic",
186
+ model,
187
+ operation: "messages",
188
+ inputTokens,
189
+ outputTokens,
190
+ costUsd: cost,
191
+ status: "success",
192
+ metadata: {
193
+ durationMs: Date.now() - startTime,
194
+ stopReason,
195
+ streamed: true,
196
+ cacheCreationTokens: cacheCreationTokens > 0 ? cacheCreationTokens : undefined,
197
+ cacheReadTokens: cacheReadTokens > 0 ? cacheReadTokens : undefined,
198
+ },
199
+ });
200
+ }
201
+ catch (error) {
202
+ // Stream failed
203
+ const pricing = getPricing();
204
+ const cost = inputTokens > 0 || outputTokens > 0
205
+ ? calculateCost(model, inputTokens, outputTokens, pricing)
206
+ : 0;
207
+ recordEvent({
208
+ provider: "anthropic",
209
+ model,
210
+ operation: "messages",
211
+ inputTokens,
212
+ outputTokens,
213
+ status: "partial",
214
+ billable: inputTokens > 0 || outputTokens > 0,
215
+ errorMessage: error instanceof Error ? error.message : String(error),
216
+ costUsd: cost,
217
+ metadata: {
218
+ durationMs: Date.now() - startTime,
219
+ streamed: true,
220
+ },
221
+ });
222
+ throw error;
223
+ }
224
+ };
225
+ // Return a new stream with the wrapped iterator
226
+ const wrappedStream = Object.create(stream);
227
+ wrappedStream[Symbol.asyncIterator] = wrappedIterator;
228
+ return wrappedStream;
229
+ }
230
+ /**
231
+ * Wrapped Anthropic client that automatically tracks costs
232
+ */
233
+ export class TrackedAnthropic extends Anthropic {
234
+ constructor(opts) {
235
+ super(opts);
236
+ // Replace messages with tracked version
237
+ this.messages = createTrackedMessages(this.messages);
238
+ }
239
+ }
240
+ /**
241
+ * Create a tracked Anthropic client
242
+ */
243
+ export function createAnthropic(opts) {
244
+ return new TrackedAnthropic(opts);
245
+ }
246
+ /**
247
+ * Wrap an existing Anthropic client to track costs
248
+ */
249
+ export function trackAnthropic(client) {
250
+ const trackedMessages = createTrackedMessages(client.messages);
251
+ client.messages = trackedMessages;
252
+ return client;
253
+ }
254
+ /**
255
+ * Default export - a function to create tracked clients
256
+ */
257
+ export default createAnthropic;
258
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/sdks/anthropic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * ElevenLabs SDK Wrapper for cost tracking
3
+ *
4
+ * ElevenLabs pricing is based on characters, not tokens.
5
+ * Different voice models have different per-character costs.
6
+ *
7
+ * Official SDK: https://github.com/elevenlabs/elevenlabs-js
8
+ *
9
+ * Models:
10
+ * - eleven_multilingual_v2: High quality, 29 languages
11
+ * - eleven_flash_v2_5: Ultra-low latency, 50% cheaper, 32 languages
12
+ * - eleven_turbo_v2_5: Balanced quality/latency, 32 languages
13
+ */
14
+ interface ElevenLabsClient {
15
+ textToSpeech: {
16
+ convert: (voiceId: string, options: TextToSpeechOptions) => Promise<Buffer | ArrayBuffer>;
17
+ stream: (voiceId: string, options: TextToSpeechOptions) => Promise<ReadableStream>;
18
+ };
19
+ generate?: (options: GenerateOptions) => Promise<Buffer | ArrayBuffer>;
20
+ }
21
+ interface TextToSpeechOptions {
22
+ text: string;
23
+ modelId?: string;
24
+ voiceSettings?: {
25
+ stability?: number;
26
+ similarityBoost?: number;
27
+ style?: number;
28
+ useSpeakerBoost?: boolean;
29
+ };
30
+ outputFormat?: string;
31
+ [key: string]: unknown;
32
+ }
33
+ interface GenerateOptions {
34
+ text: string;
35
+ voice?: string;
36
+ modelId?: string;
37
+ [key: string]: unknown;
38
+ }
39
+ /**
40
+ * Wrap an ElevenLabs client to track costs
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * import { ElevenLabsClient } from "elevenlabs";
45
+ * import { trackElevenLabs } from "tokenmeter/elevenlabs";
46
+ *
47
+ * const client = new ElevenLabsClient({ apiKey: "..." });
48
+ * const trackedClient = trackElevenLabs(client);
49
+ *
50
+ * // All calls are now tracked
51
+ * await trackedClient.textToSpeech.convert("voice_id", {
52
+ * text: "Hello world",
53
+ * modelId: "eleven_multilingual_v2"
54
+ * });
55
+ * ```
56
+ */
57
+ export declare function trackElevenLabs<T extends Partial<ElevenLabsClient>>(client: T): T;
58
+ export default trackElevenLabs;
59
+ //# sourceMappingURL=elevenlabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elevenlabs.d.ts","sourceRoot":"","sources":["../../src/sdks/elevenlabs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,UAAU,gBAAgB;IACxB,YAAY,EAAE;QACZ,OAAO,EAAE,CACP,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;QACnC,MAAM,EAAE,CACN,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,cAAc,CAAC,CAAC;KAC9B,CAAC;IACF,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;CACxE;AAED,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA+BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,CAAC,gBAAgB,CAAC,EACjE,MAAM,EAAE,CAAC,GACR,CAAC,CA6JH;AAED,eAAe,eAAe,CAAC"}