@paid-ai/paid-node 0.0.8-alpha3 → 0.0.8-alpha5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -136,16 +136,42 @@ const additionalData = {
136
136
  }
137
137
  }
138
138
  };
139
- await client.usage.recordUsage({
140
- agent_id: "<your_agent_id>",
141
- event_name: "<your_signal_name>",
142
- customer_id: "<your_customer_id>",
143
- data: additionalData,
139
+ await client.usage.recordBulk({
140
+ signals: [{
141
+ agent_id: "<your_agent_id>",
142
+ event_name: "<your_signal_name>",
143
+ customer_id: "<your_customer_id>",
144
+ data: additionalData,
145
+ }]
144
146
  })
145
147
 
146
148
  await client.usage.flush(); // need to flush to send usage immediately
147
149
  ```
148
150
 
151
+ ## Send signals over OTLP
152
+
153
+ Besides sending signals over REST, it's also possible to send signals as part or tracing
154
+ context, just like with cost tracking.
155
+
156
+ Example usage:
157
+
158
+ ```typescript
159
+ import { PaidClient } from "@paid-ai/paid-node";
160
+
161
+ async function main() {
162
+ const client = new PaidClient({ token: "<your_paid_api_key>" });
163
+
164
+ // initialize cost tracking
165
+ await client.initializeTracing()
166
+
167
+ // trace the call
168
+ await client.trace("<your_external_customer_id>", async () => {
169
+ // ... your app logic, cost tracking LLM wrapper calls
170
+ client.signal("signal_name", { "data": { // ... additional data, e.g. costs } });
171
+ }, "<optional_external_agent_id>");
172
+ }
173
+ ```
174
+
149
175
  ## Advanced
150
176
 
151
177
  ### Additional Headers
@@ -43,5 +43,24 @@ export declare class PaidClient {
43
43
  get usage(): Usage;
44
44
  initializeTracing(collectorEndpoint?: string): Promise<void>;
45
45
  trace<T extends (...args: any[]) => any>(externalCustomerId: string, fn: T, externalAgentId?: string, ...args: Parameters<T>): Promise<ReturnType<T>>;
46
- signal(eventName: string, data?: Record<string, any>): void;
46
+ /**
47
+ * Sends Paid signal. Needs to be called as part of callback to Paid.trace().
48
+ * When enableCostTracing flag is on, signal is associated
49
+ * with cost traces from the same Paid.trace() context.
50
+ *
51
+ * @param eventName - The name of the signal.
52
+ * @param enableCostTracing - Whether to associate this signal with cost traces
53
+ * from the current Paid.trace() context (default: false)
54
+ * @param data - Optional additional data to include with the signal
55
+ *
56
+ * @remarks
57
+ * When enableCostTracing is on, the signal will be associated with cost
58
+ * traces within the same Paid.trace() context.
59
+ * It is advised to only make one call to this function
60
+ * with enableCostTracing per Paid.trace() context.
61
+ * Otherwise, there will be multiple signals that refer to the same costs.
62
+ */
63
+ signal(eventName: string): void;
64
+ signal(eventName: string, data: Record<string, any>): void;
65
+ signal(eventName: string, enableCostTracing: boolean, data?: Record<string, any>): void;
47
66
  }
@@ -95,16 +95,28 @@ class PaidClient {
95
95
  (0, tracing_js_1._initializeTracing)(resolvedToken, collectorEndpoint);
96
96
  });
97
97
  }
98
- // Use this method to track actions like LLM usage and sending signals.
98
+ // Use this method to track actions like LLM costs and sending signals.
99
99
  // The callback to this function is the work that you want to trace.
100
100
  trace(externalCustomerId, fn, externalAgentId, ...args) {
101
101
  return __awaiter(this, void 0, void 0, function* () {
102
102
  return yield (0, tracing_js_1._trace)(externalCustomerId, fn, externalAgentId, ...args);
103
103
  });
104
104
  }
105
- // sends Paid signal. This needs to called as part of callback to Paid.trace()
106
- signal(eventName, data) {
107
- return (0, signal_js_1._signal)(eventName, data);
105
+ signal(eventName, enableCostTracingOrData, data) {
106
+ let enableCostTracing = false;
107
+ let finalData;
108
+ if (typeof enableCostTracingOrData === 'boolean') {
109
+ // Case: signal(eventName, boolean, data?)
110
+ enableCostTracing = enableCostTracingOrData;
111
+ finalData = data;
112
+ }
113
+ else if (typeof enableCostTracingOrData === 'object') {
114
+ // Case: signal(eventName, data)
115
+ enableCostTracing = false;
116
+ finalData = enableCostTracingOrData;
117
+ }
118
+ // Case: signal(eventName) - both remain default/undefined
119
+ return (0, signal_js_1._signal)(eventName, enableCostTracing, finalData);
108
120
  }
109
121
  }
110
122
  exports.PaidClient = PaidClient;
@@ -1 +1 @@
1
- export declare function _signal(eventName: string, data?: Record<string, any>): void;
1
+ export declare function _signal(eventName: string, enableCostTracing: boolean, data?: Record<string, any>): void;
@@ -4,7 +4,7 @@ exports._signal = _signal;
4
4
  const api_1 = require("@opentelemetry/api");
5
5
  const tracing_js_1 = require("./tracing.js");
6
6
  const tracing_js_2 = require("./tracing.js");
7
- function _signal(eventName, data) {
7
+ function _signal(eventName, enableCostTracing, data) {
8
8
  if (!eventName) {
9
9
  throw new Error("Event name is required for signal.");
10
10
  }
@@ -14,8 +14,7 @@ function _signal(eventName, data) {
14
14
  if (!externalCustomerId || !externalAgentId || !token) {
15
15
  throw new Error(`Missing some of: external_customer_id: ${externalCustomerId}, external_agent_id: ${externalAgentId}, or token. Make sure to call signal() within trace()`);
16
16
  }
17
- const tracer = tracing_js_2.paidTracer;
18
- tracer.startActiveSpan("trace.signal", (span) => {
17
+ tracing_js_2.paidTracer.startActiveSpan("trace.signal", (span) => {
19
18
  try {
20
19
  const attributes = {
21
20
  external_customer_id: externalCustomerId,
@@ -23,6 +22,16 @@ function _signal(eventName, data) {
23
22
  event_name: eventName,
24
23
  token: token,
25
24
  };
25
+ if (enableCostTracing) {
26
+ // let the app know to associate this signal with cost traces
27
+ attributes["enable_cost_tracing"] = true;
28
+ if (data === undefined) {
29
+ data = { paid: { enable_cost_tracing: true } };
30
+ }
31
+ else {
32
+ data["paid"] = { enable_cost_tracing: true };
33
+ }
34
+ }
26
35
  // Optional data (ex. manual cost tracking)
27
36
  if (data) {
28
37
  attributes["data"] = JSON.stringify(data);
@@ -35,6 +35,7 @@ const COLLECTOR_ENDPOINT = process.env.PAID_COLLECTOR_ENDPOINT || "https://colle
35
35
  let paidExporter = new exporter_trace_otlp_http_1.OTLPTraceExporter({ url: COLLECTOR_ENDPOINT });
36
36
  let spanProcessor = new sdk_trace_base_1.BatchSpanProcessor(paidExporter);
37
37
  let paidTracerProvider = new sdk_trace_node_1.NodeTracerProvider({ spanProcessors: [spanProcessor] });
38
+ paidTracerProvider.register();
38
39
  exports.paidTracer = paidTracerProvider.getTracer("paid.node");
39
40
  // storage for passing info to child spans
40
41
  const customerIdStorage = new async_hooks_1.AsyncLocalStorage();
@@ -79,6 +80,7 @@ function _initializeTracing(apiKey, collectorEndpoint) {
79
80
  paidExporter = new exporter_trace_otlp_http_1.OTLPTraceExporter({ url: collectorEndpoint });
80
81
  spanProcessor = new sdk_trace_base_1.BatchSpanProcessor(paidExporter);
81
82
  paidTracerProvider = new sdk_trace_node_1.NodeTracerProvider({ spanProcessors: [spanProcessor] });
83
+ paidTracerProvider.register();
82
84
  exports.paidTracer = paidTracerProvider.getTracer("paid.node");
83
85
  }
84
86
  setupGracefulShutdown(spanProcessor);
@@ -88,12 +90,11 @@ function _initializeTracing(apiKey, collectorEndpoint) {
88
90
  }
89
91
  function _trace(externalCustomerId, fn, externalAgentId, ...args) {
90
92
  return __awaiter(this, void 0, void 0, function* () {
91
- const tracer = exports.paidTracer;
92
93
  const token = getToken();
93
94
  if (!token || !externalCustomerId) {
94
95
  throw new Error(`Paid tracing is not initialized. Make sure to call initializeTracing() first.`);
95
96
  }
96
- return tracer.startActiveSpan("paid.node", (span) => __awaiter(this, void 0, void 0, function* () {
97
+ return exports.paidTracer.startActiveSpan("paid.node", (span) => __awaiter(this, void 0, void 0, function* () {
97
98
  span.setAttribute("external_customer_id", externalCustomerId);
98
99
  span.setAttribute("token", token);
99
100
  if (externalAgentId) {
@@ -197,16 +197,15 @@ class ImagesWrapper {
197
197
  }
198
198
  generate(params) {
199
199
  return __awaiter(this, void 0, void 0, function* () {
200
- var _a;
201
200
  const externalCustomerId = (0, tracing_js_1.getCustomerIdStorage)();
202
201
  const externalAgentId = (0, tracing_js_1.getAgentIdStorage)();
203
202
  const token = (0, tracing_js_1.getTokenStorage)();
204
- const model = (_a = params.model) !== null && _a !== void 0 ? _a : "dall-e-3";
203
+ const model = params.model || "";
205
204
  if (!token || !externalCustomerId) {
206
205
  throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
207
206
  }
208
207
  return this.tracer.startActiveSpan("trace.openai.images", (span) => __awaiter(this, void 0, void 0, function* () {
209
- var _a, _b, _c;
208
+ var _a;
210
209
  const attributes = {
211
210
  "gen_ai.request.model": model,
212
211
  "gen_ai.system": "openai",
@@ -222,8 +221,8 @@ class ImagesWrapper {
222
221
  const response = yield this.openai.images.generate(params);
223
222
  span.setAttributes({
224
223
  "gen_ai.image.count": (_a = params.n) !== null && _a !== void 0 ? _a : 1,
225
- "gen_ai.image.size": (_b = params.size) !== null && _b !== void 0 ? _b : "1024x1024",
226
- "gen_ai.image.quality": (_c = params.quality) !== null && _c !== void 0 ? _c : "standard",
224
+ "gen_ai.image.size": params.size || "",
225
+ "gen_ai.image.quality": params.quality || "",
227
226
  });
228
227
  span.setStatus({ code: api_1.SpanStatusCode.OK });
229
228
  return response;
@@ -0,0 +1,22 @@
1
+ import { generateText as originalGenerateText, streamText as originalStreamText, generateObject as originalGenerateObject, streamObject as originalStreamObject, embed as originalEmbed, embedMany as originalEmbedMany } from "ai";
2
+ type GenerateTextParams = Parameters<typeof originalGenerateText>[0];
3
+ type StreamTextParams = Parameters<typeof originalStreamText>[0];
4
+ type GenerateObjectParams = Parameters<typeof originalGenerateObject>[0];
5
+ type StreamObjectParams = Parameters<typeof originalStreamObject>[0];
6
+ type EmbedParams = Parameters<typeof originalEmbed>[0];
7
+ type EmbedManyParams = Parameters<typeof originalEmbedMany>[0];
8
+ export declare function generateText(params: GenerateTextParams): Promise<ReturnType<typeof originalGenerateText>>;
9
+ export declare function streamText(params: StreamTextParams): Promise<ReturnType<typeof originalStreamText>>;
10
+ export declare function generateObject(params: GenerateObjectParams): Promise<ReturnType<typeof originalGenerateObject>>;
11
+ export declare function streamObject(params: StreamObjectParams): Promise<ReturnType<typeof originalStreamObject>>;
12
+ export declare function embed(params: EmbedParams): Promise<ReturnType<typeof originalEmbed>>;
13
+ export declare function embedMany(params: EmbedManyParams): Promise<ReturnType<typeof originalEmbedMany>>;
14
+ declare const _default: {
15
+ generateText: typeof generateText;
16
+ streamText: typeof streamText;
17
+ generateObject: typeof generateObject;
18
+ streamObject: typeof streamObject;
19
+ embed: typeof embed;
20
+ embedMany: typeof embedMany;
21
+ };
22
+ export default _default;
@@ -0,0 +1,327 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.generateText = generateText;
13
+ exports.streamText = streamText;
14
+ exports.generateObject = generateObject;
15
+ exports.streamObject = streamObject;
16
+ exports.embed = embed;
17
+ exports.embedMany = embedMany;
18
+ const api_1 = require("@opentelemetry/api");
19
+ const tracing_js_1 = require("../tracing.js");
20
+ const ai_1 = require("ai");
21
+ function getModelInfo(model) {
22
+ if (model === null || model === void 0 ? void 0 : model.modelId) {
23
+ const modelId = model.modelId;
24
+ if (modelId.startsWith('gpt-') || modelId.startsWith('text-embedding-') || modelId.startsWith('dall-e-')) {
25
+ return { system: 'openai', modelName: modelId };
26
+ }
27
+ if (modelId.startsWith('claude-')) {
28
+ return { system: 'anthropic', modelName: modelId };
29
+ }
30
+ if (modelId.startsWith('mistral-') || modelId.startsWith('codestral-')) {
31
+ return { system: 'mistral', modelName: modelId };
32
+ }
33
+ if (modelId.includes('gemini')) {
34
+ return { system: 'google', modelName: modelId };
35
+ }
36
+ }
37
+ if (model === null || model === void 0 ? void 0 : model.provider) {
38
+ return { system: model.provider, modelName: model.modelId };
39
+ }
40
+ return { system: 'unknown' };
41
+ }
42
+ function extractUsageMetrics(usage) {
43
+ const usageAttrs = {};
44
+ const inputTokens = usage.promptTokens || usage.prompt_tokens || usage.inputTokens;
45
+ const outputTokens = usage.completionTokens || usage.completion_tokens || usage.outputTokens;
46
+ const cachedTokens = usage.cachedPromptTokens || usage.cached_prompt_tokens || usage.cachedInputTokens;
47
+ if (inputTokens !== undefined) {
48
+ usageAttrs["gen_ai.usage.input_tokens"] = inputTokens;
49
+ }
50
+ if (outputTokens !== undefined) {
51
+ usageAttrs["gen_ai.usage.output_tokens"] = outputTokens;
52
+ }
53
+ if (cachedTokens !== undefined) {
54
+ usageAttrs["gen_ai.usage.cached_input_tokens"] = cachedTokens;
55
+ }
56
+ if (usage.tokens !== undefined && inputTokens === undefined) {
57
+ usageAttrs["gen_ai.usage.input_tokens"] = usage.tokens;
58
+ }
59
+ return usageAttrs;
60
+ }
61
+ function validateContext() {
62
+ const externalCustomerId = (0, tracing_js_1.getCustomerIdStorage)();
63
+ const token = (0, tracing_js_1.getTokenStorage)();
64
+ if (!token || !externalCustomerId) {
65
+ throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
66
+ }
67
+ return {
68
+ externalCustomerId,
69
+ externalAgentId: (0, tracing_js_1.getAgentIdStorage)(),
70
+ token,
71
+ };
72
+ }
73
+ function generateText(params) {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ const context = validateContext();
76
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
77
+ return tracing_js_1.paidTracer.startActiveSpan("trace.ai-sdk.generateText", (span) => __awaiter(this, void 0, void 0, function* () {
78
+ var _a;
79
+ const attributes = {
80
+ "gen_ai.system": aiSystem,
81
+ "gen_ai.operation.name": "chat",
82
+ "external_customer_id": context.externalCustomerId,
83
+ "token": context.token,
84
+ };
85
+ if (context.externalAgentId) {
86
+ attributes["external_agent_id"] = context.externalAgentId;
87
+ }
88
+ if (modelName) {
89
+ attributes["gen_ai.request.model"] = modelName;
90
+ }
91
+ span.setAttributes(attributes);
92
+ try {
93
+ const result = yield (0, ai_1.generateText)(params);
94
+ if (result.usage) {
95
+ const usageAttrs = extractUsageMetrics(result.usage);
96
+ span.setAttributes(usageAttrs);
97
+ }
98
+ if ((_a = result.response) === null || _a === void 0 ? void 0 : _a.modelId) {
99
+ span.setAttribute("gen_ai.response.model", result.response.modelId);
100
+ }
101
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
102
+ return result;
103
+ }
104
+ catch (error) {
105
+ span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
106
+ span.recordException(error);
107
+ throw error;
108
+ }
109
+ finally {
110
+ span.end();
111
+ }
112
+ }));
113
+ });
114
+ }
115
+ function streamText(params) {
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ const context = validateContext();
118
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
119
+ return tracing_js_1.paidTracer.startActiveSpan("trace.ai-sdk.streamText", (span) => __awaiter(this, void 0, void 0, function* () {
120
+ const attributes = {
121
+ "gen_ai.system": aiSystem,
122
+ "gen_ai.operation.name": "chat",
123
+ "external_customer_id": context.externalCustomerId,
124
+ "token": context.token,
125
+ };
126
+ if (context.externalAgentId) {
127
+ attributes["external_agent_id"] = context.externalAgentId;
128
+ }
129
+ if (modelName) {
130
+ attributes["gen_ai.request.model"] = modelName;
131
+ }
132
+ span.setAttributes(attributes);
133
+ try {
134
+ const originalOnFinish = params.onFinish;
135
+ const wrappedParams = Object.assign(Object.assign({}, params), { onFinish: (result) => {
136
+ if (result.usage) {
137
+ const usageAttrs = extractUsageMetrics(result.usage);
138
+ span.setAttributes(usageAttrs);
139
+ }
140
+ if (originalOnFinish) {
141
+ originalOnFinish(result);
142
+ }
143
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
144
+ span.end();
145
+ } });
146
+ const result = (0, ai_1.streamText)(wrappedParams);
147
+ return result;
148
+ }
149
+ catch (error) {
150
+ span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
151
+ span.recordException(error);
152
+ throw error;
153
+ }
154
+ finally {
155
+ span.end();
156
+ }
157
+ }));
158
+ });
159
+ }
160
+ function generateObject(params) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ const context = validateContext();
163
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
164
+ return tracing_js_1.paidTracer.startActiveSpan("trace.ai-sdk.generateObject", (span) => __awaiter(this, void 0, void 0, function* () {
165
+ var _a;
166
+ const attributes = {
167
+ "gen_ai.system": aiSystem,
168
+ "gen_ai.operation.name": "chat",
169
+ "external_customer_id": context.externalCustomerId,
170
+ "token": context.token,
171
+ };
172
+ if (context.externalAgentId) {
173
+ attributes["external_agent_id"] = context.externalAgentId;
174
+ }
175
+ if (modelName) {
176
+ attributes["gen_ai.request.model"] = modelName;
177
+ }
178
+ span.setAttributes(attributes);
179
+ try {
180
+ const result = yield (0, ai_1.generateObject)(params);
181
+ if (result.usage) {
182
+ const usageAttrs = extractUsageMetrics(result.usage);
183
+ span.setAttributes(usageAttrs);
184
+ }
185
+ if ((_a = result.response) === null || _a === void 0 ? void 0 : _a.modelId) {
186
+ span.setAttribute("gen_ai.response.model", result.response.modelId);
187
+ }
188
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
189
+ return result;
190
+ }
191
+ catch (error) {
192
+ span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
193
+ span.recordException(error);
194
+ throw error;
195
+ }
196
+ finally {
197
+ span.end();
198
+ }
199
+ }));
200
+ });
201
+ }
202
+ function streamObject(params) {
203
+ return __awaiter(this, void 0, void 0, function* () {
204
+ const context = validateContext();
205
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
206
+ return tracing_js_1.paidTracer.startActiveSpan("trace.ai-sdk.streamObject", (span) => __awaiter(this, void 0, void 0, function* () {
207
+ const attributes = {
208
+ "gen_ai.system": aiSystem,
209
+ "gen_ai.operation.name": "chat",
210
+ "external_customer_id": context.externalCustomerId,
211
+ "token": context.token,
212
+ };
213
+ if (context.externalAgentId) {
214
+ attributes["external_agent_id"] = context.externalAgentId;
215
+ }
216
+ if (modelName) {
217
+ attributes["gen_ai.request.model"] = modelName;
218
+ }
219
+ span.setAttributes(attributes);
220
+ try {
221
+ const originalOnFinish = params.onFinish;
222
+ const wrappedParams = Object.assign(Object.assign({}, params), { onFinish: (result) => {
223
+ if (result.usage) {
224
+ const usageAttrs = extractUsageMetrics(result.usage);
225
+ span.setAttributes(usageAttrs);
226
+ }
227
+ if (originalOnFinish) {
228
+ originalOnFinish(result);
229
+ }
230
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
231
+ span.end();
232
+ } });
233
+ const result = (0, ai_1.streamObject)(wrappedParams);
234
+ return result;
235
+ }
236
+ catch (error) {
237
+ span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
238
+ span.recordException(error);
239
+ throw error;
240
+ }
241
+ }));
242
+ });
243
+ }
244
+ function embed(params) {
245
+ return __awaiter(this, void 0, void 0, function* () {
246
+ const context = validateContext();
247
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
248
+ return tracing_js_1.paidTracer.startActiveSpan("trace.ai-sdk.embed", (span) => __awaiter(this, void 0, void 0, function* () {
249
+ const attributes = {
250
+ "gen_ai.system": aiSystem,
251
+ "gen_ai.operation.name": "embeddings",
252
+ "external_customer_id": context.externalCustomerId,
253
+ "token": context.token,
254
+ };
255
+ if (context.externalAgentId) {
256
+ attributes["external_agent_id"] = context.externalAgentId;
257
+ }
258
+ if (modelName) {
259
+ attributes["gen_ai.request.model"] = modelName;
260
+ }
261
+ span.setAttributes(attributes);
262
+ try {
263
+ const result = yield (0, ai_1.embed)(params);
264
+ if (result.usage) {
265
+ const usageAttrs = extractUsageMetrics(result.usage);
266
+ span.setAttributes(usageAttrs);
267
+ }
268
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
269
+ return result;
270
+ }
271
+ catch (error) {
272
+ span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
273
+ span.recordException(error);
274
+ throw error;
275
+ }
276
+ finally {
277
+ span.end();
278
+ }
279
+ }));
280
+ });
281
+ }
282
+ function embedMany(params) {
283
+ return __awaiter(this, void 0, void 0, function* () {
284
+ const context = validateContext();
285
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
286
+ return tracing_js_1.paidTracer.startActiveSpan("trace.ai-sdk.embedMany", (span) => __awaiter(this, void 0, void 0, function* () {
287
+ const attributes = {
288
+ "gen_ai.system": aiSystem,
289
+ "gen_ai.operation.name": "embeddings",
290
+ "external_customer_id": context.externalCustomerId,
291
+ "token": context.token,
292
+ };
293
+ if (context.externalAgentId) {
294
+ attributes["external_agent_id"] = context.externalAgentId;
295
+ }
296
+ if (modelName) {
297
+ attributes["gen_ai.request.model"] = modelName;
298
+ }
299
+ span.setAttributes(attributes);
300
+ try {
301
+ const result = yield (0, ai_1.embedMany)(params);
302
+ if (result.usage) {
303
+ const usageAttrs = extractUsageMetrics(result.usage);
304
+ span.setAttributes(usageAttrs);
305
+ }
306
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
307
+ return result;
308
+ }
309
+ catch (error) {
310
+ span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
311
+ span.recordException(error);
312
+ throw error;
313
+ }
314
+ finally {
315
+ span.end();
316
+ }
317
+ }));
318
+ });
319
+ }
320
+ exports.default = {
321
+ generateText,
322
+ streamText,
323
+ generateObject,
324
+ streamObject,
325
+ embed,
326
+ embedMany,
327
+ };
@@ -0,0 +1 @@
1
+ export { generateText as paidGenerateText, streamText as paidStreamText, generateObject as paidGenerateObject, streamObject as paidStreamObject, embed as paidEmbed, embedMany as paidEmbedMany, } from "../tracing/wrappers/vercelAIWrapper.js";
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.paidEmbedMany = exports.paidEmbed = exports.paidStreamObject = exports.paidGenerateObject = exports.paidStreamText = exports.paidGenerateText = void 0;
4
+ var vercelAIWrapper_js_1 = require("../tracing/wrappers/vercelAIWrapper.js");
5
+ Object.defineProperty(exports, "paidGenerateText", { enumerable: true, get: function () { return vercelAIWrapper_js_1.generateText; } });
6
+ Object.defineProperty(exports, "paidStreamText", { enumerable: true, get: function () { return vercelAIWrapper_js_1.streamText; } });
7
+ Object.defineProperty(exports, "paidGenerateObject", { enumerable: true, get: function () { return vercelAIWrapper_js_1.generateObject; } });
8
+ Object.defineProperty(exports, "paidStreamObject", { enumerable: true, get: function () { return vercelAIWrapper_js_1.streamObject; } });
9
+ Object.defineProperty(exports, "paidEmbed", { enumerable: true, get: function () { return vercelAIWrapper_js_1.embed; } });
10
+ Object.defineProperty(exports, "paidEmbedMany", { enumerable: true, get: function () { return vercelAIWrapper_js_1.embedMany; } });
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.0.8-alpha3";
1
+ export declare const SDK_VERSION = "0.0.8-alpha5";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = "0.0.8-alpha3";
4
+ exports.SDK_VERSION = "0.0.8-alpha5";
@@ -43,5 +43,24 @@ export declare class PaidClient {
43
43
  get usage(): Usage;
44
44
  initializeTracing(collectorEndpoint?: string): Promise<void>;
45
45
  trace<T extends (...args: any[]) => any>(externalCustomerId: string, fn: T, externalAgentId?: string, ...args: Parameters<T>): Promise<ReturnType<T>>;
46
- signal(eventName: string, data?: Record<string, any>): void;
46
+ /**
47
+ * Sends Paid signal. Needs to be called as part of callback to Paid.trace().
48
+ * When enableCostTracing flag is on, signal is associated
49
+ * with cost traces from the same Paid.trace() context.
50
+ *
51
+ * @param eventName - The name of the signal.
52
+ * @param enableCostTracing - Whether to associate this signal with cost traces
53
+ * from the current Paid.trace() context (default: false)
54
+ * @param data - Optional additional data to include with the signal
55
+ *
56
+ * @remarks
57
+ * When enableCostTracing is on, the signal will be associated with cost
58
+ * traces within the same Paid.trace() context.
59
+ * It is advised to only make one call to this function
60
+ * with enableCostTracing per Paid.trace() context.
61
+ * Otherwise, there will be multiple signals that refer to the same costs.
62
+ */
63
+ signal(eventName: string): void;
64
+ signal(eventName: string, data: Record<string, any>): void;
65
+ signal(eventName: string, enableCostTracing: boolean, data?: Record<string, any>): void;
47
66
  }
@@ -59,15 +59,27 @@ export class PaidClient {
59
59
  _initializeTracing(resolvedToken, collectorEndpoint);
60
60
  });
61
61
  }
62
- // Use this method to track actions like LLM usage and sending signals.
62
+ // Use this method to track actions like LLM costs and sending signals.
63
63
  // The callback to this function is the work that you want to trace.
64
64
  trace(externalCustomerId, fn, externalAgentId, ...args) {
65
65
  return __awaiter(this, void 0, void 0, function* () {
66
66
  return yield _trace(externalCustomerId, fn, externalAgentId, ...args);
67
67
  });
68
68
  }
69
- // sends Paid signal. This needs to called as part of callback to Paid.trace()
70
- signal(eventName, data) {
71
- return _signal(eventName, data);
69
+ signal(eventName, enableCostTracingOrData, data) {
70
+ let enableCostTracing = false;
71
+ let finalData;
72
+ if (typeof enableCostTracingOrData === 'boolean') {
73
+ // Case: signal(eventName, boolean, data?)
74
+ enableCostTracing = enableCostTracingOrData;
75
+ finalData = data;
76
+ }
77
+ else if (typeof enableCostTracingOrData === 'object') {
78
+ // Case: signal(eventName, data)
79
+ enableCostTracing = false;
80
+ finalData = enableCostTracingOrData;
81
+ }
82
+ // Case: signal(eventName) - both remain default/undefined
83
+ return _signal(eventName, enableCostTracing, finalData);
72
84
  }
73
85
  }
@@ -1 +1 @@
1
- export declare function _signal(eventName: string, data?: Record<string, any>): void;
1
+ export declare function _signal(eventName: string, enableCostTracing: boolean, data?: Record<string, any>): void;
@@ -1,7 +1,7 @@
1
1
  import { SpanStatusCode } from "@opentelemetry/api";
2
2
  import { getCustomerIdStorage, getAgentIdStorage, getTokenStorage } from "./tracing.mjs";
3
3
  import { paidTracer } from "./tracing.mjs";
4
- export function _signal(eventName, data) {
4
+ export function _signal(eventName, enableCostTracing, data) {
5
5
  if (!eventName) {
6
6
  throw new Error("Event name is required for signal.");
7
7
  }
@@ -11,8 +11,7 @@ export function _signal(eventName, data) {
11
11
  if (!externalCustomerId || !externalAgentId || !token) {
12
12
  throw new Error(`Missing some of: external_customer_id: ${externalCustomerId}, external_agent_id: ${externalAgentId}, or token. Make sure to call signal() within trace()`);
13
13
  }
14
- const tracer = paidTracer;
15
- tracer.startActiveSpan("trace.signal", (span) => {
14
+ paidTracer.startActiveSpan("trace.signal", (span) => {
16
15
  try {
17
16
  const attributes = {
18
17
  external_customer_id: externalCustomerId,
@@ -20,6 +19,16 @@ export function _signal(eventName, data) {
20
19
  event_name: eventName,
21
20
  token: token,
22
21
  };
22
+ if (enableCostTracing) {
23
+ // let the app know to associate this signal with cost traces
24
+ attributes["enable_cost_tracing"] = true;
25
+ if (data === undefined) {
26
+ data = { paid: { enable_cost_tracing: true } };
27
+ }
28
+ else {
29
+ data["paid"] = { enable_cost_tracing: true };
30
+ }
31
+ }
23
32
  // Optional data (ex. manual cost tracking)
24
33
  if (data) {
25
34
  attributes["data"] = JSON.stringify(data);
@@ -27,6 +27,7 @@ const COLLECTOR_ENDPOINT = process.env.PAID_COLLECTOR_ENDPOINT || "https://colle
27
27
  let paidExporter = new OTLPTraceExporter({ url: COLLECTOR_ENDPOINT });
28
28
  let spanProcessor = new BatchSpanProcessor(paidExporter);
29
29
  let paidTracerProvider = new NodeTracerProvider({ spanProcessors: [spanProcessor] });
30
+ paidTracerProvider.register();
30
31
  export let paidTracer = paidTracerProvider.getTracer("paid.node");
31
32
  // storage for passing info to child spans
32
33
  const customerIdStorage = new AsyncLocalStorage();
@@ -68,6 +69,7 @@ export function _initializeTracing(apiKey, collectorEndpoint) {
68
69
  paidExporter = new OTLPTraceExporter({ url: collectorEndpoint });
69
70
  spanProcessor = new BatchSpanProcessor(paidExporter);
70
71
  paidTracerProvider = new NodeTracerProvider({ spanProcessors: [spanProcessor] });
72
+ paidTracerProvider.register();
71
73
  paidTracer = paidTracerProvider.getTracer("paid.node");
72
74
  }
73
75
  setupGracefulShutdown(spanProcessor);
@@ -77,12 +79,11 @@ export function _initializeTracing(apiKey, collectorEndpoint) {
77
79
  }
78
80
  export function _trace(externalCustomerId, fn, externalAgentId, ...args) {
79
81
  return __awaiter(this, void 0, void 0, function* () {
80
- const tracer = paidTracer;
81
82
  const token = getToken();
82
83
  if (!token || !externalCustomerId) {
83
84
  throw new Error(`Paid tracing is not initialized. Make sure to call initializeTracing() first.`);
84
85
  }
85
- return tracer.startActiveSpan("paid.node", (span) => __awaiter(this, void 0, void 0, function* () {
86
+ return paidTracer.startActiveSpan("paid.node", (span) => __awaiter(this, void 0, void 0, function* () {
86
87
  span.setAttribute("external_customer_id", externalCustomerId);
87
88
  span.setAttribute("token", token);
88
89
  if (externalAgentId) {
@@ -193,16 +193,15 @@ class ImagesWrapper {
193
193
  }
194
194
  generate(params) {
195
195
  return __awaiter(this, void 0, void 0, function* () {
196
- var _a;
197
196
  const externalCustomerId = getCustomerIdStorage();
198
197
  const externalAgentId = getAgentIdStorage();
199
198
  const token = getTokenStorage();
200
- const model = (_a = params.model) !== null && _a !== void 0 ? _a : "dall-e-3";
199
+ const model = params.model || "";
201
200
  if (!token || !externalCustomerId) {
202
201
  throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
203
202
  }
204
203
  return this.tracer.startActiveSpan("trace.openai.images", (span) => __awaiter(this, void 0, void 0, function* () {
205
- var _a, _b, _c;
204
+ var _a;
206
205
  const attributes = {
207
206
  "gen_ai.request.model": model,
208
207
  "gen_ai.system": "openai",
@@ -218,8 +217,8 @@ class ImagesWrapper {
218
217
  const response = yield this.openai.images.generate(params);
219
218
  span.setAttributes({
220
219
  "gen_ai.image.count": (_a = params.n) !== null && _a !== void 0 ? _a : 1,
221
- "gen_ai.image.size": (_b = params.size) !== null && _b !== void 0 ? _b : "1024x1024",
222
- "gen_ai.image.quality": (_c = params.quality) !== null && _c !== void 0 ? _c : "standard",
220
+ "gen_ai.image.size": params.size || "",
221
+ "gen_ai.image.quality": params.quality || "",
223
222
  });
224
223
  span.setStatus({ code: SpanStatusCode.OK });
225
224
  return response;
@@ -0,0 +1,22 @@
1
+ import { generateText as originalGenerateText, streamText as originalStreamText, generateObject as originalGenerateObject, streamObject as originalStreamObject, embed as originalEmbed, embedMany as originalEmbedMany } from "ai";
2
+ type GenerateTextParams = Parameters<typeof originalGenerateText>[0];
3
+ type StreamTextParams = Parameters<typeof originalStreamText>[0];
4
+ type GenerateObjectParams = Parameters<typeof originalGenerateObject>[0];
5
+ type StreamObjectParams = Parameters<typeof originalStreamObject>[0];
6
+ type EmbedParams = Parameters<typeof originalEmbed>[0];
7
+ type EmbedManyParams = Parameters<typeof originalEmbedMany>[0];
8
+ export declare function generateText(params: GenerateTextParams): Promise<ReturnType<typeof originalGenerateText>>;
9
+ export declare function streamText(params: StreamTextParams): Promise<ReturnType<typeof originalStreamText>>;
10
+ export declare function generateObject(params: GenerateObjectParams): Promise<ReturnType<typeof originalGenerateObject>>;
11
+ export declare function streamObject(params: StreamObjectParams): Promise<ReturnType<typeof originalStreamObject>>;
12
+ export declare function embed(params: EmbedParams): Promise<ReturnType<typeof originalEmbed>>;
13
+ export declare function embedMany(params: EmbedManyParams): Promise<ReturnType<typeof originalEmbedMany>>;
14
+ declare const _default: {
15
+ generateText: typeof generateText;
16
+ streamText: typeof streamText;
17
+ generateObject: typeof generateObject;
18
+ streamObject: typeof streamObject;
19
+ embed: typeof embed;
20
+ embedMany: typeof embedMany;
21
+ };
22
+ export default _default;
@@ -0,0 +1,319 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { SpanStatusCode } from "@opentelemetry/api";
11
+ import { getCustomerIdStorage, getAgentIdStorage, getTokenStorage, paidTracer } from "../tracing.mjs";
12
+ import { generateText as originalGenerateText, streamText as originalStreamText, generateObject as originalGenerateObject, streamObject as originalStreamObject, embed as originalEmbed, embedMany as originalEmbedMany, } from "ai";
13
+ function getModelInfo(model) {
14
+ if (model === null || model === void 0 ? void 0 : model.modelId) {
15
+ const modelId = model.modelId;
16
+ if (modelId.startsWith('gpt-') || modelId.startsWith('text-embedding-') || modelId.startsWith('dall-e-')) {
17
+ return { system: 'openai', modelName: modelId };
18
+ }
19
+ if (modelId.startsWith('claude-')) {
20
+ return { system: 'anthropic', modelName: modelId };
21
+ }
22
+ if (modelId.startsWith('mistral-') || modelId.startsWith('codestral-')) {
23
+ return { system: 'mistral', modelName: modelId };
24
+ }
25
+ if (modelId.includes('gemini')) {
26
+ return { system: 'google', modelName: modelId };
27
+ }
28
+ }
29
+ if (model === null || model === void 0 ? void 0 : model.provider) {
30
+ return { system: model.provider, modelName: model.modelId };
31
+ }
32
+ return { system: 'unknown' };
33
+ }
34
+ function extractUsageMetrics(usage) {
35
+ const usageAttrs = {};
36
+ const inputTokens = usage.promptTokens || usage.prompt_tokens || usage.inputTokens;
37
+ const outputTokens = usage.completionTokens || usage.completion_tokens || usage.outputTokens;
38
+ const cachedTokens = usage.cachedPromptTokens || usage.cached_prompt_tokens || usage.cachedInputTokens;
39
+ if (inputTokens !== undefined) {
40
+ usageAttrs["gen_ai.usage.input_tokens"] = inputTokens;
41
+ }
42
+ if (outputTokens !== undefined) {
43
+ usageAttrs["gen_ai.usage.output_tokens"] = outputTokens;
44
+ }
45
+ if (cachedTokens !== undefined) {
46
+ usageAttrs["gen_ai.usage.cached_input_tokens"] = cachedTokens;
47
+ }
48
+ if (usage.tokens !== undefined && inputTokens === undefined) {
49
+ usageAttrs["gen_ai.usage.input_tokens"] = usage.tokens;
50
+ }
51
+ return usageAttrs;
52
+ }
53
+ function validateContext() {
54
+ const externalCustomerId = getCustomerIdStorage();
55
+ const token = getTokenStorage();
56
+ if (!token || !externalCustomerId) {
57
+ throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
58
+ }
59
+ return {
60
+ externalCustomerId,
61
+ externalAgentId: getAgentIdStorage(),
62
+ token,
63
+ };
64
+ }
65
+ export function generateText(params) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ const context = validateContext();
68
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
69
+ return paidTracer.startActiveSpan("trace.ai-sdk.generateText", (span) => __awaiter(this, void 0, void 0, function* () {
70
+ var _a;
71
+ const attributes = {
72
+ "gen_ai.system": aiSystem,
73
+ "gen_ai.operation.name": "chat",
74
+ "external_customer_id": context.externalCustomerId,
75
+ "token": context.token,
76
+ };
77
+ if (context.externalAgentId) {
78
+ attributes["external_agent_id"] = context.externalAgentId;
79
+ }
80
+ if (modelName) {
81
+ attributes["gen_ai.request.model"] = modelName;
82
+ }
83
+ span.setAttributes(attributes);
84
+ try {
85
+ const result = yield originalGenerateText(params);
86
+ if (result.usage) {
87
+ const usageAttrs = extractUsageMetrics(result.usage);
88
+ span.setAttributes(usageAttrs);
89
+ }
90
+ if ((_a = result.response) === null || _a === void 0 ? void 0 : _a.modelId) {
91
+ span.setAttribute("gen_ai.response.model", result.response.modelId);
92
+ }
93
+ span.setStatus({ code: SpanStatusCode.OK });
94
+ return result;
95
+ }
96
+ catch (error) {
97
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
98
+ span.recordException(error);
99
+ throw error;
100
+ }
101
+ finally {
102
+ span.end();
103
+ }
104
+ }));
105
+ });
106
+ }
107
+ export function streamText(params) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ const context = validateContext();
110
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
111
+ return paidTracer.startActiveSpan("trace.ai-sdk.streamText", (span) => __awaiter(this, void 0, void 0, function* () {
112
+ const attributes = {
113
+ "gen_ai.system": aiSystem,
114
+ "gen_ai.operation.name": "chat",
115
+ "external_customer_id": context.externalCustomerId,
116
+ "token": context.token,
117
+ };
118
+ if (context.externalAgentId) {
119
+ attributes["external_agent_id"] = context.externalAgentId;
120
+ }
121
+ if (modelName) {
122
+ attributes["gen_ai.request.model"] = modelName;
123
+ }
124
+ span.setAttributes(attributes);
125
+ try {
126
+ const originalOnFinish = params.onFinish;
127
+ const wrappedParams = Object.assign(Object.assign({}, params), { onFinish: (result) => {
128
+ if (result.usage) {
129
+ const usageAttrs = extractUsageMetrics(result.usage);
130
+ span.setAttributes(usageAttrs);
131
+ }
132
+ if (originalOnFinish) {
133
+ originalOnFinish(result);
134
+ }
135
+ span.setStatus({ code: SpanStatusCode.OK });
136
+ span.end();
137
+ } });
138
+ const result = originalStreamText(wrappedParams);
139
+ return result;
140
+ }
141
+ catch (error) {
142
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
143
+ span.recordException(error);
144
+ throw error;
145
+ }
146
+ finally {
147
+ span.end();
148
+ }
149
+ }));
150
+ });
151
+ }
152
+ export function generateObject(params) {
153
+ return __awaiter(this, void 0, void 0, function* () {
154
+ const context = validateContext();
155
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
156
+ return paidTracer.startActiveSpan("trace.ai-sdk.generateObject", (span) => __awaiter(this, void 0, void 0, function* () {
157
+ var _a;
158
+ const attributes = {
159
+ "gen_ai.system": aiSystem,
160
+ "gen_ai.operation.name": "chat",
161
+ "external_customer_id": context.externalCustomerId,
162
+ "token": context.token,
163
+ };
164
+ if (context.externalAgentId) {
165
+ attributes["external_agent_id"] = context.externalAgentId;
166
+ }
167
+ if (modelName) {
168
+ attributes["gen_ai.request.model"] = modelName;
169
+ }
170
+ span.setAttributes(attributes);
171
+ try {
172
+ const result = yield originalGenerateObject(params);
173
+ if (result.usage) {
174
+ const usageAttrs = extractUsageMetrics(result.usage);
175
+ span.setAttributes(usageAttrs);
176
+ }
177
+ if ((_a = result.response) === null || _a === void 0 ? void 0 : _a.modelId) {
178
+ span.setAttribute("gen_ai.response.model", result.response.modelId);
179
+ }
180
+ span.setStatus({ code: SpanStatusCode.OK });
181
+ return result;
182
+ }
183
+ catch (error) {
184
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
185
+ span.recordException(error);
186
+ throw error;
187
+ }
188
+ finally {
189
+ span.end();
190
+ }
191
+ }));
192
+ });
193
+ }
194
+ export function streamObject(params) {
195
+ return __awaiter(this, void 0, void 0, function* () {
196
+ const context = validateContext();
197
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
198
+ return paidTracer.startActiveSpan("trace.ai-sdk.streamObject", (span) => __awaiter(this, void 0, void 0, function* () {
199
+ const attributes = {
200
+ "gen_ai.system": aiSystem,
201
+ "gen_ai.operation.name": "chat",
202
+ "external_customer_id": context.externalCustomerId,
203
+ "token": context.token,
204
+ };
205
+ if (context.externalAgentId) {
206
+ attributes["external_agent_id"] = context.externalAgentId;
207
+ }
208
+ if (modelName) {
209
+ attributes["gen_ai.request.model"] = modelName;
210
+ }
211
+ span.setAttributes(attributes);
212
+ try {
213
+ const originalOnFinish = params.onFinish;
214
+ const wrappedParams = Object.assign(Object.assign({}, params), { onFinish: (result) => {
215
+ if (result.usage) {
216
+ const usageAttrs = extractUsageMetrics(result.usage);
217
+ span.setAttributes(usageAttrs);
218
+ }
219
+ if (originalOnFinish) {
220
+ originalOnFinish(result);
221
+ }
222
+ span.setStatus({ code: SpanStatusCode.OK });
223
+ span.end();
224
+ } });
225
+ const result = originalStreamObject(wrappedParams);
226
+ return result;
227
+ }
228
+ catch (error) {
229
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
230
+ span.recordException(error);
231
+ throw error;
232
+ }
233
+ }));
234
+ });
235
+ }
236
+ export function embed(params) {
237
+ return __awaiter(this, void 0, void 0, function* () {
238
+ const context = validateContext();
239
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
240
+ return paidTracer.startActiveSpan("trace.ai-sdk.embed", (span) => __awaiter(this, void 0, void 0, function* () {
241
+ const attributes = {
242
+ "gen_ai.system": aiSystem,
243
+ "gen_ai.operation.name": "embeddings",
244
+ "external_customer_id": context.externalCustomerId,
245
+ "token": context.token,
246
+ };
247
+ if (context.externalAgentId) {
248
+ attributes["external_agent_id"] = context.externalAgentId;
249
+ }
250
+ if (modelName) {
251
+ attributes["gen_ai.request.model"] = modelName;
252
+ }
253
+ span.setAttributes(attributes);
254
+ try {
255
+ const result = yield originalEmbed(params);
256
+ if (result.usage) {
257
+ const usageAttrs = extractUsageMetrics(result.usage);
258
+ span.setAttributes(usageAttrs);
259
+ }
260
+ span.setStatus({ code: SpanStatusCode.OK });
261
+ return result;
262
+ }
263
+ catch (error) {
264
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
265
+ span.recordException(error);
266
+ throw error;
267
+ }
268
+ finally {
269
+ span.end();
270
+ }
271
+ }));
272
+ });
273
+ }
274
+ export function embedMany(params) {
275
+ return __awaiter(this, void 0, void 0, function* () {
276
+ const context = validateContext();
277
+ const { system: aiSystem, modelName } = getModelInfo(params.model);
278
+ return paidTracer.startActiveSpan("trace.ai-sdk.embedMany", (span) => __awaiter(this, void 0, void 0, function* () {
279
+ const attributes = {
280
+ "gen_ai.system": aiSystem,
281
+ "gen_ai.operation.name": "embeddings",
282
+ "external_customer_id": context.externalCustomerId,
283
+ "token": context.token,
284
+ };
285
+ if (context.externalAgentId) {
286
+ attributes["external_agent_id"] = context.externalAgentId;
287
+ }
288
+ if (modelName) {
289
+ attributes["gen_ai.request.model"] = modelName;
290
+ }
291
+ span.setAttributes(attributes);
292
+ try {
293
+ const result = yield originalEmbedMany(params);
294
+ if (result.usage) {
295
+ const usageAttrs = extractUsageMetrics(result.usage);
296
+ span.setAttributes(usageAttrs);
297
+ }
298
+ span.setStatus({ code: SpanStatusCode.OK });
299
+ return result;
300
+ }
301
+ catch (error) {
302
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
303
+ span.recordException(error);
304
+ throw error;
305
+ }
306
+ finally {
307
+ span.end();
308
+ }
309
+ }));
310
+ });
311
+ }
312
+ export default {
313
+ generateText,
314
+ streamText,
315
+ generateObject,
316
+ streamObject,
317
+ embed,
318
+ embedMany,
319
+ };
@@ -0,0 +1 @@
1
+ export { generateText as paidGenerateText, streamText as paidStreamText, generateObject as paidGenerateObject, streamObject as paidStreamObject, embed as paidEmbed, embedMany as paidEmbedMany, } from "../tracing/wrappers/vercelAIWrapper.mjs";
@@ -0,0 +1 @@
1
+ export { generateText as paidGenerateText, streamText as paidStreamText, generateObject as paidGenerateObject, streamObject as paidStreamObject, embed as paidEmbed, embedMany as paidEmbedMany, } from "../tracing/wrappers/vercelAIWrapper.mjs";
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.0.8-alpha3";
1
+ export declare const SDK_VERSION = "0.0.8-alpha5";
@@ -1 +1 @@
1
- export const SDK_VERSION = "0.0.8-alpha3";
1
+ export const SDK_VERSION = "0.0.8-alpha5";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paid-ai/paid-node",
3
- "version": "0.0.8-alpha3",
3
+ "version": "0.0.8-alpha5",
4
4
  "private": false,
5
5
  "repository": "https://github.com/AgentPaid/paid-node",
6
6
  "type": "commonjs",
@@ -20,6 +20,18 @@
20
20
  },
21
21
  "default": "./dist/cjs/index.js"
22
22
  },
23
+ "./vercel": {
24
+ "types": "./dist/cjs/vercel/index.d.ts",
25
+ "import": {
26
+ "types": "./dist/esm/vercel/index.d.mts",
27
+ "default": "./dist/esm/vercel/index.mjs"
28
+ },
29
+ "require": {
30
+ "types": "./dist/cjs/vercel/index.d.ts",
31
+ "default": "./dist/cjs/vercel/index.js"
32
+ },
33
+ "default": "./dist/cjs/vercel/index.js"
34
+ },
23
35
  "./package.json": "./package.json"
24
36
  },
25
37
  "files": [
@@ -36,12 +48,14 @@
36
48
  "wire:test": "yarn test:wire"
37
49
  },
38
50
  "dependencies": {
51
+ "@ai-sdk/openai": "^1.3.23",
39
52
  "@anthropic-ai/sdk": "^0.56.0",
40
53
  "@langchain/core": "^0.3.64",
41
54
  "@mistralai/mistralai": "^1.7.4",
42
55
  "@opentelemetry/api": "^1.9.0",
43
56
  "@opentelemetry/exporter-trace-otlp-http": "^0.202.0",
44
57
  "@opentelemetry/sdk-node": "^0.202.0",
58
+ "ai": "^5.0.2",
45
59
  "form-data": "^4.0.0",
46
60
  "formdata-node": "^6.0.3",
47
61
  "js-base64": "3.7.7",