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,191 @@
1
+ import OpenAI from "openai";
2
+ import { recordEvent } from "../recorder.js";
3
+ import { getPricing, resolveModel } from "../config.js";
4
+ import { calculateCost } from "../pricing/index.js";
5
+ /**
6
+ * Create a tracked chat completions API
7
+ */
8
+ function createTrackedCompletions(completions) {
9
+ const originalCreate = completions.create.bind(completions);
10
+ function trackedCreate(body, options) {
11
+ const startTime = Date.now();
12
+ const model = resolveModel(body.model);
13
+ if (body.stream) {
14
+ // Streaming request
15
+ const promise = originalCreate(body, options);
16
+ // Wrap the promise to intercept the stream
17
+ return wrapStreamPromise(promise, model, startTime);
18
+ }
19
+ else {
20
+ // Non-streaming request
21
+ const promise = originalCreate(body, options);
22
+ return wrapCompletionPromise(promise, model, startTime);
23
+ }
24
+ }
25
+ // Copy other properties from original completions
26
+ const result = Object.create(completions);
27
+ result.create = trackedCreate;
28
+ return result;
29
+ }
30
+ /**
31
+ * Wrap a completion promise to track costs
32
+ */
33
+ function wrapCompletionPromise(promise, model, startTime) {
34
+ // Create a new promise that wraps the original
35
+ const wrappedPromise = promise.then((response) => {
36
+ const usage = response.usage;
37
+ if (usage) {
38
+ const pricing = getPricing();
39
+ const cost = calculateCost(model, usage.prompt_tokens, usage.completion_tokens, pricing);
40
+ recordEvent({
41
+ provider: "openai",
42
+ model,
43
+ operation: "chat",
44
+ inputTokens: usage.prompt_tokens,
45
+ outputTokens: usage.completion_tokens,
46
+ costUsd: cost,
47
+ status: "success",
48
+ metadata: {
49
+ durationMs: Date.now() - startTime,
50
+ },
51
+ });
52
+ }
53
+ return response;
54
+ }, (error) => {
55
+ recordEvent({
56
+ provider: "openai",
57
+ model,
58
+ operation: "chat",
59
+ status: "failed",
60
+ billable: false,
61
+ errorMessage: error instanceof Error ? error.message : String(error),
62
+ costUsd: 0,
63
+ metadata: {
64
+ durationMs: Date.now() - startTime,
65
+ },
66
+ });
67
+ throw error;
68
+ });
69
+ // Copy APIPromise methods to maintain compatibility
70
+ // We delegate to the original promise's methods rather than accessing internals
71
+ const apiPromise = Object.assign(wrappedPromise, {
72
+ asResponse: () => promise.asResponse(),
73
+ withResponse: () => promise.withResponse().then(({ data, response }) => ({
74
+ data,
75
+ response,
76
+ })),
77
+ });
78
+ return apiPromise;
79
+ }
80
+ /**
81
+ * Wrap a stream promise to track costs on completion
82
+ */
83
+ function wrapStreamPromise(promise, model, startTime) {
84
+ const wrappedPromise = promise.then((stream) => wrapStream(stream, model, startTime), (error) => {
85
+ recordEvent({
86
+ provider: "openai",
87
+ model,
88
+ operation: "chat",
89
+ status: "failed",
90
+ billable: false,
91
+ errorMessage: error instanceof Error ? error.message : String(error),
92
+ costUsd: 0,
93
+ metadata: {
94
+ durationMs: Date.now() - startTime,
95
+ },
96
+ });
97
+ throw error;
98
+ });
99
+ // Copy APIPromise methods - delegate to original promise
100
+ const apiPromise = Object.assign(wrappedPromise, {
101
+ asResponse: () => promise.asResponse(),
102
+ withResponse: () => promise.withResponse().then(async ({ data, response }) => ({
103
+ data: wrapStream(data, model, startTime),
104
+ response,
105
+ })),
106
+ });
107
+ return apiPromise;
108
+ }
109
+ /**
110
+ * Wrap a stream to track usage on completion
111
+ */
112
+ function wrapStream(stream, model, startTime) {
113
+ let inputTokens = 0;
114
+ let outputTokens = 0;
115
+ const originalIterator = stream[Symbol.asyncIterator].bind(stream);
116
+ const wrappedIterator = async function* () {
117
+ try {
118
+ for await (const chunk of { [Symbol.asyncIterator]: originalIterator }) {
119
+ // Track usage if available in chunk (with stream_options: { include_usage: true })
120
+ if (chunk.usage) {
121
+ inputTokens = chunk.usage.prompt_tokens;
122
+ outputTokens = chunk.usage.completion_tokens;
123
+ }
124
+ yield chunk;
125
+ }
126
+ // Stream completed successfully
127
+ const pricing = getPricing();
128
+ const cost = calculateCost(model, inputTokens, outputTokens, pricing);
129
+ recordEvent({
130
+ provider: "openai",
131
+ model,
132
+ operation: "chat",
133
+ inputTokens,
134
+ outputTokens,
135
+ costUsd: cost,
136
+ status: "success",
137
+ metadata: {
138
+ durationMs: Date.now() - startTime,
139
+ streamed: true,
140
+ },
141
+ });
142
+ }
143
+ catch (error) {
144
+ // Stream failed
145
+ recordEvent({
146
+ provider: "openai",
147
+ model,
148
+ operation: "chat",
149
+ inputTokens,
150
+ outputTokens,
151
+ status: "partial",
152
+ billable: inputTokens > 0 || outputTokens > 0,
153
+ errorMessage: error instanceof Error ? error.message : String(error),
154
+ costUsd: inputTokens > 0 || outputTokens > 0
155
+ ? calculateCost(model, inputTokens, outputTokens, getPricing())
156
+ : 0,
157
+ metadata: {
158
+ durationMs: Date.now() - startTime,
159
+ streamed: true,
160
+ },
161
+ });
162
+ throw error;
163
+ }
164
+ };
165
+ // Return a new stream with the wrapped iterator
166
+ const wrappedStream = Object.create(stream);
167
+ wrappedStream[Symbol.asyncIterator] = wrappedIterator;
168
+ return wrappedStream;
169
+ }
170
+ /**
171
+ * Wrapped OpenAI client that automatically tracks costs
172
+ */
173
+ export class TrackedOpenAI extends OpenAI {
174
+ constructor(opts) {
175
+ super(opts);
176
+ // Replace chat.completions with tracked version
177
+ this.chat.completions =
178
+ createTrackedCompletions(this.chat.completions);
179
+ }
180
+ }
181
+ /**
182
+ * Create a tracked OpenAI client
183
+ */
184
+ export function createOpenAI(opts) {
185
+ return new TrackedOpenAI(opts);
186
+ }
187
+ /**
188
+ * Default export - a function to create tracked clients
189
+ */
190
+ export default createOpenAI;
191
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/sdks/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { CostEvent, QueryParams, QueryResult, StorageAdapter } from "../types.js";
2
+ export type { StorageAdapter };
3
+ /**
4
+ * In-memory storage adapter for testing
5
+ */
6
+ export declare class InMemoryStorageAdapter implements StorageAdapter {
7
+ private events;
8
+ writeEvent(event: CostEvent): Promise<void>;
9
+ writeBatch(events: CostEvent[]): Promise<void>;
10
+ query(params: QueryParams): Promise<QueryResult>;
11
+ disconnect(): Promise<void>;
12
+ getEvents(): CostEvent[];
13
+ clear(): void;
14
+ }
15
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvF,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B;;GAEG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,MAAM,CAAmB;IAE3B,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IA0ChD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC,SAAS,IAAI,SAAS,EAAE;IAKxB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * In-memory storage adapter for testing
3
+ */
4
+ export class InMemoryStorageAdapter {
5
+ events = [];
6
+ async writeEvent(event) {
7
+ this.events.push(event);
8
+ }
9
+ async writeBatch(events) {
10
+ this.events.push(...events);
11
+ }
12
+ async query(params) {
13
+ let filtered = this.events;
14
+ if (params.identifier) {
15
+ filtered = filtered.filter((e) => e.identifier === params.identifier);
16
+ }
17
+ if (params.workflowId) {
18
+ filtered = filtered.filter((e) => e.workflowId === params.workflowId);
19
+ }
20
+ if (params.from) {
21
+ filtered = filtered.filter((e) => e.createdAt && e.createdAt >= params.from);
22
+ }
23
+ if (params.to) {
24
+ filtered = filtered.filter((e) => e.createdAt && e.createdAt <= params.to);
25
+ }
26
+ if (params.provider) {
27
+ filtered = filtered.filter((e) => e.provider === params.provider);
28
+ }
29
+ const totalCost = filtered.reduce((sum, e) => sum + e.costUsd, 0);
30
+ const byProvider = {};
31
+ for (const event of filtered) {
32
+ byProvider[event.provider] =
33
+ (byProvider[event.provider] || 0) + event.costUsd;
34
+ }
35
+ return {
36
+ totalCost,
37
+ events: filtered,
38
+ byProvider,
39
+ };
40
+ }
41
+ async disconnect() {
42
+ // No-op for in-memory
43
+ }
44
+ // Test helper
45
+ getEvents() {
46
+ return [...this.events];
47
+ }
48
+ // Test helper
49
+ clear() {
50
+ this.events = [];
51
+ }
52
+ }
53
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACzB,MAAM,GAAgB,EAAE,CAAC;IAEjC,KAAK,CAAC,UAAU,CAAC,KAAgB;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAmB;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAmB;QAC7B,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,IAAK,CAClD,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,QAAQ,GAAG,QAAQ,CAAC,MAAM,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,EAAG,CAChD,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAElE,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;gBACxB,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;QACtD,CAAC;QAED,OAAO;YACL,SAAS;YACT,MAAM,EAAE,QAAQ;YAChB,UAAU;SACX,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU;QACd,sBAAsB;IACxB,CAAC;IAED,cAAc;IACd,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,cAAc;IACd,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { CostEvent, QueryParams, QueryResult, StorageAdapter } from "../types.js";
2
+ /**
3
+ * Prisma storage adapter for PostgreSQL
4
+ */
5
+ export declare class PrismaStorageAdapter implements StorageAdapter {
6
+ private prisma;
7
+ private connected;
8
+ constructor(databaseUrl?: string);
9
+ private ensureConnected;
10
+ writeEvent(event: CostEvent): Promise<void>;
11
+ writeBatch(events: CostEvent[]): Promise<void>;
12
+ query(params: QueryParams): Promise<QueryResult>;
13
+ disconnect(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=prisma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/storage/prisma.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAS;gBAEd,WAAW,CAAC,EAAE,MAAM;YAYlB,eAAe;IAOvB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB3C,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B9C,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAoEhD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAMlC"}
@@ -0,0 +1,135 @@
1
+ import { PrismaClient, Prisma } from "@prisma/client";
2
+ /**
3
+ * Prisma storage adapter for PostgreSQL
4
+ */
5
+ export class PrismaStorageAdapter {
6
+ prisma;
7
+ connected = false;
8
+ constructor(databaseUrl) {
9
+ this.prisma = new PrismaClient({
10
+ datasources: databaseUrl
11
+ ? {
12
+ db: {
13
+ url: databaseUrl,
14
+ },
15
+ }
16
+ : undefined,
17
+ });
18
+ }
19
+ async ensureConnected() {
20
+ if (!this.connected) {
21
+ await this.prisma.$connect();
22
+ this.connected = true;
23
+ }
24
+ }
25
+ async writeEvent(event) {
26
+ await this.ensureConnected();
27
+ await this.prisma.tokenmeterEvent.create({
28
+ data: {
29
+ identifier: event.identifier,
30
+ secondaryIdentifier: event.secondaryIdentifier,
31
+ requestId: event.requestId,
32
+ workflowId: event.workflowId,
33
+ workflowType: event.workflowType,
34
+ provider: event.provider,
35
+ model: event.model,
36
+ operation: event.operation,
37
+ inputTokens: event.inputTokens,
38
+ outputTokens: event.outputTokens,
39
+ costUsd: event.costUsd,
40
+ status: event.status ?? "success",
41
+ billable: event.billable ?? true,
42
+ errorMessage: event.errorMessage,
43
+ metadata: event.metadata ?? Prisma.JsonNull,
44
+ },
45
+ });
46
+ }
47
+ async writeBatch(events) {
48
+ if (events.length === 0)
49
+ return;
50
+ await this.ensureConnected();
51
+ await this.prisma.tokenmeterEvent.createMany({
52
+ data: events.map((event) => ({
53
+ identifier: event.identifier,
54
+ secondaryIdentifier: event.secondaryIdentifier,
55
+ requestId: event.requestId,
56
+ workflowId: event.workflowId,
57
+ workflowType: event.workflowType,
58
+ provider: event.provider,
59
+ model: event.model,
60
+ operation: event.operation,
61
+ inputTokens: event.inputTokens,
62
+ outputTokens: event.outputTokens,
63
+ costUsd: event.costUsd,
64
+ status: event.status ?? "success",
65
+ billable: event.billable ?? true,
66
+ errorMessage: event.errorMessage,
67
+ metadata: event.metadata ?? Prisma.JsonNull,
68
+ })),
69
+ });
70
+ }
71
+ async query(params) {
72
+ await this.ensureConnected();
73
+ const where = {};
74
+ if (params.identifier) {
75
+ where.identifier = params.identifier;
76
+ }
77
+ if (params.workflowId) {
78
+ where.workflowId = params.workflowId;
79
+ }
80
+ if (params.provider) {
81
+ where.provider = params.provider;
82
+ }
83
+ if (params.from || params.to) {
84
+ where.createdAt = {};
85
+ if (params.from) {
86
+ where.createdAt.gte = params.from;
87
+ }
88
+ if (params.to) {
89
+ where.createdAt.lte = params.to;
90
+ }
91
+ }
92
+ const events = await this.prisma.tokenmeterEvent.findMany({
93
+ where,
94
+ orderBy: { createdAt: "desc" },
95
+ });
96
+ // Convert Prisma results to CostEvent
97
+ const costEvents = events.map((e) => ({
98
+ id: e.id,
99
+ identifier: e.identifier,
100
+ secondaryIdentifier: e.secondaryIdentifier ?? undefined,
101
+ requestId: e.requestId ?? undefined,
102
+ workflowId: e.workflowId ?? undefined,
103
+ workflowType: e.workflowType ?? undefined,
104
+ provider: e.provider,
105
+ model: e.model,
106
+ operation: e.operation ?? undefined,
107
+ inputTokens: e.inputTokens ?? undefined,
108
+ outputTokens: e.outputTokens ?? undefined,
109
+ costUsd: Number(e.costUsd),
110
+ status: e.status,
111
+ billable: e.billable,
112
+ errorMessage: e.errorMessage ?? undefined,
113
+ metadata: e.metadata,
114
+ createdAt: e.createdAt,
115
+ }));
116
+ const totalCost = costEvents.reduce((sum, e) => sum + e.costUsd, 0);
117
+ const byProvider = {};
118
+ for (const event of costEvents) {
119
+ byProvider[event.provider] =
120
+ (byProvider[event.provider] || 0) + event.costUsd;
121
+ }
122
+ return {
123
+ totalCost,
124
+ events: costEvents,
125
+ byProvider,
126
+ };
127
+ }
128
+ async disconnect() {
129
+ if (this.connected) {
130
+ await this.prisma.$disconnect();
131
+ this.connected = false;
132
+ }
133
+ }
134
+ }
135
+ //# sourceMappingURL=prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/storage/prisma.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * TokenMeter v5 - Core Types
3
+ *
4
+ * OpenTelemetry-native cost tracking for AI workflows.
5
+ */
6
+ import type { Attributes } from "@opentelemetry/api";
7
+ /**
8
+ * Pricing unit types
9
+ */
10
+ export type PricingUnit = "1m_tokens" | "1k_tokens" | "1k_characters" | "request" | "megapixel" | "second" | "minute" | "image";
11
+ /**
12
+ * Model pricing entry
13
+ */
14
+ export interface ModelPricing {
15
+ /** Cost per input unit */
16
+ input?: number;
17
+ /** Cost per output unit */
18
+ output?: number;
19
+ /** Flat cost per request (for request-based pricing) */
20
+ cost?: number;
21
+ /** The unit for pricing */
22
+ unit: PricingUnit;
23
+ /** Cost for cached input (prompt caching) */
24
+ cachedInput?: number;
25
+ /** Cost for cached output */
26
+ cachedOutput?: number;
27
+ /** Cost for cache write operations */
28
+ cacheWrite?: number;
29
+ /** Cost for cache read operations */
30
+ cacheRead?: number;
31
+ }
32
+ /**
33
+ * Provider pricing catalog
34
+ */
35
+ export interface ProviderPricing {
36
+ [modelId: string]: ModelPricing;
37
+ }
38
+ /**
39
+ * Complete pricing manifest
40
+ */
41
+ export interface PricingManifest {
42
+ version: string;
43
+ updatedAt: string;
44
+ providers: {
45
+ [providerId: string]: ProviderPricing;
46
+ };
47
+ }
48
+ /**
49
+ * Options for the monitor() function
50
+ */
51
+ export interface MonitorOptions {
52
+ /** Name for the instrumented client (used in span names) */
53
+ name?: string;
54
+ /** Override provider detection */
55
+ provider?: string;
56
+ /** Custom attributes to add to all spans from this client */
57
+ attributes?: Attributes;
58
+ }
59
+ /**
60
+ * Usage data extracted from API responses
61
+ */
62
+ export interface UsageData {
63
+ /** Provider name */
64
+ provider: string;
65
+ /** Model identifier */
66
+ model: string;
67
+ /** Input units (tokens, characters, etc.) */
68
+ inputUnits?: number;
69
+ /** Output units (tokens, characters, images, seconds, etc.) */
70
+ outputUnits?: number;
71
+ /** Cached input units */
72
+ cachedInputUnits?: number;
73
+ /** Raw cost if provided by the API */
74
+ rawCost?: number;
75
+ /** Additional metadata */
76
+ metadata?: Record<string, unknown>;
77
+ }
78
+ /**
79
+ * Extraction strategy for parsing API responses
80
+ */
81
+ export interface ExtractionStrategy {
82
+ /** Provider this strategy handles */
83
+ provider: string;
84
+ /** Check if this strategy can handle the given method/result */
85
+ canHandle(methodPath: string[], result: unknown): boolean;
86
+ /** Extract usage data from the result */
87
+ extract(methodPath: string[], result: unknown, args: unknown[]): UsageData | null;
88
+ }
89
+ /**
90
+ * Attributes that can be set via withAttributes()
91
+ */
92
+ export type TokenMeterAttributes = Record<string, string | number | boolean>;
93
+ /**
94
+ * Configuration for TokenMeterProcessor
95
+ */
96
+ export interface TokenMeterProcessorConfig {
97
+ /** Pricing manifest URL (for remote fetch) */
98
+ manifestUrl?: string;
99
+ /** Local fallback manifest path */
100
+ fallbackManifestPath?: string;
101
+ /** Custom pricing overrides */
102
+ pricingOverrides?: PricingManifest["providers"];
103
+ }
104
+ /**
105
+ * Configuration for PostgresExporter
106
+ */
107
+ export interface PostgresExporterConfig {
108
+ /** PostgreSQL connection string */
109
+ connectionString: string;
110
+ /** Table name (default: tokenmeter_costs) */
111
+ tableName?: string;
112
+ /** Batch size for inserts */
113
+ batchSize?: number;
114
+ /** Flush interval in milliseconds */
115
+ flushIntervalMs?: number;
116
+ }
117
+ /**
118
+ * A cost record for the database
119
+ */
120
+ export interface CostRecord {
121
+ id: string;
122
+ traceId: string;
123
+ spanId: string;
124
+ provider: string;
125
+ model: string;
126
+ organizationId?: string;
127
+ userId?: string;
128
+ costUsd: number;
129
+ inputUnits?: number;
130
+ outputUnits?: number;
131
+ attributes?: Record<string, unknown>;
132
+ createdAt: Date;
133
+ }
134
+ /**
135
+ * Query options for cost aggregation
136
+ */
137
+ export interface CostQueryOptions {
138
+ /** Group results by these attributes */
139
+ groupBy?: string[];
140
+ /** Filter by start date */
141
+ from?: Date | string;
142
+ /** Filter by end date */
143
+ to?: Date | string;
144
+ /** Filter by provider */
145
+ provider?: string;
146
+ /** Filter by model */
147
+ model?: string;
148
+ /** Filter by organization ID */
149
+ organizationId?: string;
150
+ /** Filter by user ID */
151
+ userId?: string;
152
+ /** Limit results */
153
+ limit?: number;
154
+ }
155
+ /**
156
+ * Aggregated cost result
157
+ */
158
+ export interface CostResult {
159
+ /** Total cost in USD */
160
+ totalCost: number;
161
+ /** Number of records */
162
+ count: number;
163
+ /** Grouped results (if groupBy specified) */
164
+ groups?: Array<{
165
+ key: Record<string, string>;
166
+ cost: number;
167
+ count: number;
168
+ }>;
169
+ }
170
+ /**
171
+ * TokenMeter-specific span attributes
172
+ */
173
+ export declare const TM_ATTRIBUTES: {
174
+ /** Calculated cost in USD */
175
+ readonly COST_USD: "tokenmeter.cost_usd";
176
+ /** Provider name */
177
+ readonly PROVIDER: "tokenmeter.provider";
178
+ /** Model name */
179
+ readonly MODEL: "tokenmeter.model";
180
+ /** Pricing unit used */
181
+ readonly UNIT: "tokenmeter.unit";
182
+ /** Input units consumed */
183
+ readonly INPUT_UNITS: "tokenmeter.input_units";
184
+ /** Output units consumed */
185
+ readonly OUTPUT_UNITS: "tokenmeter.output_units";
186
+ /** Organization ID (from withAttributes) */
187
+ readonly ORG_ID: "org.id";
188
+ /** User ID (from withAttributes) */
189
+ readonly USER_ID: "user.id";
190
+ /** Workflow ID (from withAttributes) */
191
+ readonly WORKFLOW_ID: "workflow.id";
192
+ };
193
+ /**
194
+ * Standard GenAI semantic conventions
195
+ */
196
+ export declare const GEN_AI_ATTRIBUTES: {
197
+ /** Input tokens */
198
+ readonly INPUT_TOKENS: "gen_ai.usage.input_tokens";
199
+ /** Output tokens */
200
+ readonly OUTPUT_TOKENS: "gen_ai.usage.output_tokens";
201
+ /** Model name */
202
+ readonly MODEL: "gen_ai.request.model";
203
+ /** System/provider */
204
+ readonly SYSTEM: "gen_ai.system";
205
+ };
206
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}