@paid-ai/paid-node 0.0.8-alpha1 → 0.0.8-alpha2

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 (44) hide show
  1. package/README.md +17 -16
  2. package/dist/cjs/Client.d.ts +4 -2
  3. package/dist/cjs/Client.js +21 -4
  4. package/dist/cjs/index.d.ts +3 -1
  5. package/dist/cjs/index.js +7 -4
  6. package/dist/cjs/tracing/signal.d.ts +1 -0
  7. package/dist/cjs/tracing/signal.js +49 -0
  8. package/dist/cjs/tracing/tracing.d.ts +8 -3
  9. package/dist/cjs/tracing/tracing.js +100 -28
  10. package/dist/cjs/tracing/wrappers/anthropicWrapper.d.ts +16 -0
  11. package/dist/cjs/tracing/wrappers/anthropicWrapper.js +88 -0
  12. package/dist/cjs/tracing/wrappers/langchainCallback.d.ts +21 -0
  13. package/dist/cjs/tracing/wrappers/langchainCallback.js +146 -0
  14. package/dist/cjs/tracing/wrappers/mistralWrapper.d.ts +17 -0
  15. package/dist/cjs/tracing/wrappers/mistralWrapper.js +85 -0
  16. package/dist/cjs/tracing/wrappers/openAiWrapper.js +48 -46
  17. package/dist/cjs/version.d.ts +1 -1
  18. package/dist/cjs/version.js +1 -1
  19. package/dist/cjs/wrapper/BatchUsage.d.ts +1 -1
  20. package/dist/cjs/wrapper/BatchUsage.js +2 -2
  21. package/dist/esm/Client.d.mts +4 -2
  22. package/dist/esm/Client.mjs +22 -5
  23. package/dist/esm/index.d.mts +3 -1
  24. package/dist/esm/index.mjs +3 -1
  25. package/dist/esm/tracing/signal.d.mts +1 -0
  26. package/dist/esm/tracing/signal.mjs +46 -0
  27. package/dist/esm/tracing/tracing.d.mts +8 -3
  28. package/dist/esm/tracing/tracing.mjs +94 -27
  29. package/dist/esm/tracing/wrappers/anthropicWrapper.d.mts +16 -0
  30. package/dist/esm/tracing/wrappers/anthropicWrapper.mjs +84 -0
  31. package/dist/esm/tracing/wrappers/langchainCallback.d.mts +21 -0
  32. package/dist/esm/tracing/wrappers/langchainCallback.mjs +142 -0
  33. package/dist/esm/tracing/wrappers/mistralWrapper.d.mts +17 -0
  34. package/dist/esm/tracing/wrappers/mistralWrapper.mjs +81 -0
  35. package/dist/esm/tracing/wrappers/openAiWrapper.mjs +44 -42
  36. package/dist/esm/version.d.mts +1 -1
  37. package/dist/esm/version.mjs +1 -1
  38. package/dist/esm/wrapper/BatchUsage.d.mts +1 -1
  39. package/dist/esm/wrapper/BatchUsage.mjs +1 -1
  40. package/package.json +7 -3
  41. package/dist/cjs/tracing/index.d.ts +0 -1
  42. package/dist/cjs/tracing/index.js +0 -17
  43. package/dist/esm/tracing/index.d.mts +0 -1
  44. package/dist/esm/tracing/index.mjs +0 -1
@@ -7,50 +7,117 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { NodeSDK } from '@opentelemetry/sdk-node';
11
- import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
10
+ import { NodeSDK } from "@opentelemetry/sdk-node";
11
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
12
+ import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
12
13
  import { trace, SpanStatusCode } from "@opentelemetry/api";
13
- import { AsyncLocalStorage } from 'async_hooks';
14
+ import { AsyncLocalStorage } from "async_hooks";
15
+ import winston from "winston";
16
+ export const logger = winston.createLogger({
17
+ level: "silent", // Default to 'silent' to avoid logging unless set via environment variable
18
+ format: winston.format.simple(),
19
+ transports: [new winston.transports.Console()],
20
+ });
21
+ const logLevel = process.env.PAID_LOG_LEVEL;
22
+ if (logLevel) {
23
+ logger.level = logLevel;
24
+ }
25
+ // storage for passing info to child spans
14
26
  const customerIdStorage = new AsyncLocalStorage();
27
+ const agentIdStorage = new AsyncLocalStorage();
15
28
  const tokenStorage = new AsyncLocalStorage();
16
- export const getCustomerId = () => customerIdStorage.getStore();
29
+ export const getCustomerIdStorage = () => customerIdStorage.getStore();
30
+ export const getAgentIdStorage = () => agentIdStorage.getStore();
17
31
  export const getTokenStorage = () => tokenStorage.getStore();
18
32
  let _token;
19
- const setToken = (token) => { _token = token; };
20
- const getToken = () => { return _token; };
21
- export function initializeTracing(apiKey) {
22
- setToken(apiKey);
33
+ const setToken = (token) => {
34
+ _token = token;
35
+ };
36
+ const getToken = () => {
37
+ return _token;
38
+ };
39
+ let _isShuttingDown = false;
40
+ function setupGracefulShutdown(shuttable) {
41
+ ["SIGINT", "SIGTERM", "beforeExit", "uncaughtException", "unhandledRejection"].forEach((signal) => {
42
+ process.on(signal, () => {
43
+ if (_isShuttingDown) {
44
+ return;
45
+ }
46
+ _isShuttingDown = true;
47
+ shuttable
48
+ .shutdown()
49
+ .then(() => logger.info(`Paid tracing SDK shut down from signal: ${signal}`))
50
+ .catch((error) => logger.error(`Error shutting down Paid tracing SDK ${error}`));
51
+ });
52
+ });
53
+ }
54
+ function isOTELInitialized() {
55
+ const provider = trace.getTracerProvider();
56
+ if (!provider) {
57
+ return false;
58
+ }
59
+ if (provider.constructor.name !== "ProxyTracerProvider" && provider.constructor.name !== "NodeTracerProvider") {
60
+ return true;
61
+ }
62
+ if (provider._delegate) {
63
+ return provider._delegate.constructor.name !== "NoopTracerProvider";
64
+ }
65
+ return false;
66
+ }
67
+ export function _initializeTracing(apiKey, collectorEndpoint) {
68
+ if (getToken()) {
69
+ throw new Error("Tracing SDK is already initialized.");
70
+ }
71
+ if (!apiKey) {
72
+ throw new Error("Cannot initialize tracing SDK - first initialize the PaidClient with an API key");
73
+ }
74
+ try {
75
+ new URL(collectorEndpoint);
76
+ }
77
+ catch (_a) {
78
+ throw new Error(`Collector endpoint [${collectorEndpoint}] must be a valid URL`);
79
+ }
80
+ if (isOTELInitialized()) {
81
+ throw new Error("OTEL SDK is already initialized with a different provider.\n" +
82
+ "If you're already using OTEL in your code - " +
83
+ "please use function Paid.getSpanProcessorAndInitialize() " +
84
+ "and add the span processor to your OTEL SDK initialization");
85
+ }
23
86
  const sdk = new NodeSDK({
24
87
  traceExporter: new OTLPTraceExporter({
25
- url: 'https://collector.agentpaid.io:4318/v1/traces',
26
- // url: 'http://localhost:4318/v1/traces',
88
+ url: collectorEndpoint,
27
89
  }),
28
90
  });
29
91
  sdk.start();
30
- // Graceful shutdown
31
- ['SIGINT', 'SIGTERM'].forEach(signal => {
32
- process.on(signal, () => {
33
- sdk.shutdown()
34
- .then(() => console.log('Paid tracing SDK shut down'))
35
- .catch(error => console.error('Error shutting down Paid tracing SDK', error));
36
- });
37
- });
92
+ setupGracefulShutdown(sdk);
93
+ setToken(apiKey);
94
+ logger.info(`Paid tracing SDK initialized with collector endpoint: ${collectorEndpoint}`);
95
+ }
96
+ export function _getSpanProcessorAndInitialize(apiKey, collectorEndpoint) {
97
+ setToken(apiKey);
98
+ const spanProcessor = new BatchSpanProcessor(new OTLPTraceExporter({ url: collectorEndpoint }));
99
+ setupGracefulShutdown(spanProcessor);
100
+ return spanProcessor;
38
101
  }
39
- export function capture(externalCustomerId, fn, ...args) {
102
+ export function _trace(externalCustomerId, fn, externalAgentId, ...args) {
40
103
  return __awaiter(this, void 0, void 0, function* () {
41
- const tracer = trace.getTracer('paid.node');
104
+ const tracer = trace.getTracer("paid.node");
42
105
  const token = getToken();
43
- if (!token) {
44
- console.warn('No token found - tracing will not be captured');
45
- return fn(...args);
106
+ if (!token || !externalCustomerId) {
107
+ throw new Error(`Token [${token}] or external customer ID [${externalCustomerId}] is missing`);
46
108
  }
47
109
  return tracer.startActiveSpan("paid.node", (span) => __awaiter(this, void 0, void 0, function* () {
48
- span.setAttribute('external_customer_id', externalCustomerId);
49
- span.setAttribute('token', token);
110
+ span.setAttribute("external_customer_id", externalCustomerId);
111
+ span.setAttribute("token", token);
112
+ if (externalAgentId) {
113
+ span.setAttribute("external_agent_id", externalAgentId);
114
+ }
50
115
  try {
51
116
  const result = yield customerIdStorage.run(externalCustomerId, () => __awaiter(this, void 0, void 0, function* () {
52
- return yield tokenStorage.run(token, () => __awaiter(this, void 0, void 0, function* () {
53
- return yield fn(...args);
117
+ return yield agentIdStorage.run(externalAgentId !== null && externalAgentId !== void 0 ? externalAgentId : null, () => __awaiter(this, void 0, void 0, function* () {
118
+ return yield tokenStorage.run(token, () => __awaiter(this, void 0, void 0, function* () {
119
+ return yield fn(...args);
120
+ }));
54
121
  }));
55
122
  }));
56
123
  span.setStatus({ code: SpanStatusCode.OK });
@@ -0,0 +1,16 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import { Tracer } from "@opentelemetry/api";
3
+ import { MessageCreateParams } from "@anthropic-ai/sdk/resources/messages";
4
+ export declare class PaidAnthropic {
5
+ private readonly anthropic;
6
+ private readonly tracer;
7
+ constructor(anthropicClient: Anthropic);
8
+ get messages(): MessagesWrapper;
9
+ }
10
+ declare class MessagesWrapper {
11
+ private anthropic;
12
+ private tracer;
13
+ constructor(anthropic: Anthropic, tracer: Tracer);
14
+ create(params: MessageCreateParams): Promise<any>;
15
+ }
16
+ export {};
@@ -0,0 +1,84 @@
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 { trace, SpanStatusCode, context } from "@opentelemetry/api";
11
+ import { getCustomerIdStorage, getAgentIdStorage, getTokenStorage } from "../tracing.mjs";
12
+ export class PaidAnthropic {
13
+ constructor(anthropicClient) {
14
+ this.anthropic = anthropicClient;
15
+ this.tracer = trace.getTracer("paid.node");
16
+ }
17
+ get messages() {
18
+ return new MessagesWrapper(this.anthropic, this.tracer);
19
+ }
20
+ }
21
+ class MessagesWrapper {
22
+ constructor(anthropic, tracer) {
23
+ this.anthropic = anthropic;
24
+ this.tracer = tracer;
25
+ }
26
+ create(params) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const currentSpan = trace.getSpan(context.active());
29
+ if (!currentSpan) {
30
+ throw new Error("No active span found, make sure to call this inside of a callback to paid.trace().");
31
+ }
32
+ const externalCustomerId = getCustomerIdStorage();
33
+ const externalAgentId = getAgentIdStorage();
34
+ const token = getTokenStorage();
35
+ if (!token || !externalCustomerId) {
36
+ throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
37
+ }
38
+ return this.tracer.startActiveSpan("trace.anthropic.messages", (span) => __awaiter(this, void 0, void 0, function* () {
39
+ const attributes = {
40
+ "gen_ai.system": "anthropic",
41
+ "gen_ai.operation.name": "messages",
42
+ external_customer_id: externalCustomerId,
43
+ token: token,
44
+ };
45
+ if (externalAgentId) {
46
+ attributes["external_agent_id"] = externalAgentId;
47
+ }
48
+ // Set request model from params
49
+ if (params.model) {
50
+ attributes["gen_ai.request.model"] = params.model;
51
+ }
52
+ span.setAttributes(attributes);
53
+ try {
54
+ const response = (yield this.anthropic.messages.create(params));
55
+ // Add usage information from response
56
+ if (response.usage) {
57
+ span.setAttributes({
58
+ "gen_ai.usage.input_tokens": response.usage.input_tokens,
59
+ "gen_ai.usage.output_tokens": response.usage.output_tokens,
60
+ "gen_ai.response.model": response.model,
61
+ });
62
+ // Add Anthropic-specific cache usage if available
63
+ if ("cache_creation_input_tokens" in response.usage && response.usage.cache_creation_input_tokens) {
64
+ span.setAttribute("gen_ai.usage.cache_creation_input_tokens", response.usage.cache_creation_input_tokens);
65
+ }
66
+ if ("cache_read_input_tokens" in response.usage && response.usage.cache_read_input_tokens) {
67
+ span.setAttribute("gen_ai.usage.cache_read_input_tokens", response.usage.cache_read_input_tokens);
68
+ }
69
+ }
70
+ span.setStatus({ code: SpanStatusCode.OK });
71
+ return response;
72
+ }
73
+ catch (error) {
74
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
75
+ span.recordException(error);
76
+ throw error;
77
+ }
78
+ finally {
79
+ span.end();
80
+ }
81
+ }));
82
+ });
83
+ }
84
+ }
@@ -0,0 +1,21 @@
1
+ import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
2
+ interface SerializedData {
3
+ id?: string[];
4
+ [key: string]: any;
5
+ }
6
+ interface Metadata {
7
+ ls_model_type?: string;
8
+ ls_model_name?: string;
9
+ [key: string]: any;
10
+ }
11
+ export declare class PaidLangChainCallback extends BaseCallbackHandler {
12
+ name: string;
13
+ private tracer;
14
+ private spans;
15
+ constructor();
16
+ private extractProvider;
17
+ handleLLMStart(llm: SerializedData, prompts: string[], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Metadata): Promise<void>;
18
+ handleLLMEnd(output: any, runId: string, parentRunId?: string): Promise<void>;
19
+ handleLLMError(err: Error, runId: string, parentRunId?: string): Promise<void>;
20
+ }
21
+ export {};
@@ -0,0 +1,142 @@
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 { BaseCallbackHandler } from "@langchain/core/callbacks/base";
11
+ import { trace, SpanStatusCode, context } from "@opentelemetry/api";
12
+ import { getCustomerIdStorage, getAgentIdStorage, getTokenStorage } from "../tracing.mjs";
13
+ export class PaidLangChainCallback extends BaseCallbackHandler {
14
+ constructor() {
15
+ super();
16
+ this.name = "PaidLangChainCallback";
17
+ this.spans = new Map();
18
+ this.tracer = trace.getTracer("paid.node");
19
+ }
20
+ extractProvider(serialized) {
21
+ if (!(serialized === null || serialized === void 0 ? void 0 : serialized.id))
22
+ return "unknown";
23
+ const idStr = serialized.id.join(" ").toLowerCase();
24
+ if (idStr.includes("openai"))
25
+ return "openai";
26
+ if (idStr.includes("anthropic"))
27
+ return "anthropic";
28
+ if (idStr.includes("mistral"))
29
+ return "mistral";
30
+ if (idStr.includes("cohere"))
31
+ return "cohere";
32
+ if (idStr.includes("huggingface"))
33
+ return "huggingface";
34
+ if (idStr.includes("azure"))
35
+ return "azure";
36
+ return "unknown";
37
+ }
38
+ handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ const currentSpan = trace.getSpan(context.active());
41
+ if (!currentSpan) {
42
+ throw new Error("No active span found, make sure to call this inside of a callback to paid.trace().");
43
+ }
44
+ const externalCustomerId = getCustomerIdStorage();
45
+ const externalAgentId = getAgentIdStorage();
46
+ const token = getTokenStorage();
47
+ if (!token || !externalCustomerId) {
48
+ throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
49
+ }
50
+ const modelType = (metadata === null || metadata === void 0 ? void 0 : metadata.ls_model_type) || "unknown";
51
+ const modelName = (metadata === null || metadata === void 0 ? void 0 : metadata.ls_model_name) || "unknown";
52
+ const spanName = `trace.langchain.${modelType}`;
53
+ const span = this.tracer.startSpan(spanName);
54
+ const attributes = {
55
+ "gen_ai.system": this.extractProvider(llm),
56
+ "gen_ai.operation.name": modelType,
57
+ "gen_ai.request.model": modelName,
58
+ external_customer_id: externalCustomerId,
59
+ token: token,
60
+ };
61
+ if (externalAgentId) {
62
+ attributes["external_agent_id"] = externalAgentId;
63
+ }
64
+ span.setAttributes(attributes);
65
+ this.spans.set(runId, span);
66
+ });
67
+ }
68
+ handleLLMEnd(output, runId, parentRunId) {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
71
+ const span = this.spans.get(runId);
72
+ if (!span)
73
+ return;
74
+ try {
75
+ const attributes = {};
76
+ // Extract token usage information
77
+ if ((_a = output.llmOutput) === null || _a === void 0 ? void 0 : _a.tokenUsage) {
78
+ const usage = output.llmOutput.tokenUsage;
79
+ if (usage.promptTokens !== undefined) {
80
+ attributes["gen_ai.usage.input_tokens"] = usage.promptTokens;
81
+ }
82
+ if (usage.completionTokens !== undefined) {
83
+ attributes["gen_ai.usage.output_tokens"] = usage.completionTokens;
84
+ }
85
+ if (usage.cachedInputTokens !== undefined) {
86
+ attributes["gen_ai.usage.cached_input_tokens"] = usage.cachedInputTokens;
87
+ }
88
+ if (usage.reasoningOutputTokens !== undefined) {
89
+ attributes["gen_ai.usage.reasoning_output_tokens"] = usage.reasoningOutputTokens;
90
+ }
91
+ }
92
+ // Alternative token usage format (some providers use different field names)
93
+ if ((_b = output.llmOutput) === null || _b === void 0 ? void 0 : _b.token_usage) {
94
+ const usage = output.llmOutput.token_usage;
95
+ if (usage.prompt_tokens !== undefined) {
96
+ attributes["gen_ai.usage.input_tokens"] = usage.prompt_tokens;
97
+ }
98
+ if (usage.completion_tokens !== undefined) {
99
+ attributes["gen_ai.usage.output_tokens"] = usage.completion_tokens;
100
+ }
101
+ if (usage.cached_input_tokens !== undefined) {
102
+ attributes["gen_ai.usage.cached_input_tokens"] = usage.cached_input_tokens;
103
+ }
104
+ if (usage.reasoning_output_tokens !== undefined) {
105
+ attributes["gen_ai.usage.reasoning_output_tokens"] = usage.reasoning_output_tokens;
106
+ }
107
+ }
108
+ // Add model from response if available
109
+ if ((_c = output.llmOutput) === null || _c === void 0 ? void 0 : _c.modelName) {
110
+ attributes["gen_ai.response.model"] = output.llmOutput.modelName;
111
+ }
112
+ else if ((_d = output.llmOutput) === null || _d === void 0 ? void 0 : _d.model_name) {
113
+ attributes["gen_ai.response.model"] = output.llmOutput.model_name;
114
+ }
115
+ else if ((_j = (_h = (_g = (_f = (_e = output.generations) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) === null || _h === void 0 ? void 0 : _h["response_metadata"]) === null || _j === void 0 ? void 0 : _j.model_name) {
116
+ attributes["gen_ai.response.model"] = output.generations[0][0].message["response_metadata"].model_name;
117
+ }
118
+ span.setAttributes(attributes);
119
+ span.setStatus({ code: SpanStatusCode.OK });
120
+ }
121
+ finally {
122
+ span.end();
123
+ this.spans.delete(runId);
124
+ }
125
+ });
126
+ }
127
+ handleLLMError(err, runId, parentRunId) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ const span = this.spans.get(runId);
130
+ if (!span)
131
+ return;
132
+ try {
133
+ span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
134
+ span.recordException(err);
135
+ }
136
+ finally {
137
+ span.end();
138
+ this.spans.delete(runId);
139
+ }
140
+ });
141
+ }
142
+ }
@@ -0,0 +1,17 @@
1
+ import { Mistral } from "@mistralai/mistralai";
2
+ import { Tracer } from "@opentelemetry/api";
3
+ import { OCRRequest, OCRResponse } from "@mistralai/mistralai/models/components";
4
+ import { RequestOptions } from "@mistralai/mistralai/lib/sdks";
5
+ export declare class PaidMistral {
6
+ private readonly mistral;
7
+ private readonly tracer;
8
+ constructor(mistralClient: Mistral);
9
+ get ocr(): OCRWrapper;
10
+ }
11
+ declare class OCRWrapper {
12
+ private mistral;
13
+ private tracer;
14
+ constructor(mistral: Mistral, tracer: Tracer);
15
+ process(request: OCRRequest, options?: RequestOptions): Promise<OCRResponse>;
16
+ }
17
+ export {};
@@ -0,0 +1,81 @@
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 { trace, SpanStatusCode, context } from "@opentelemetry/api";
11
+ import { getCustomerIdStorage, getAgentIdStorage, getTokenStorage } from "../tracing.mjs";
12
+ export class PaidMistral {
13
+ constructor(mistralClient) {
14
+ this.mistral = mistralClient;
15
+ this.tracer = trace.getTracer("paid.node");
16
+ }
17
+ get ocr() {
18
+ return new OCRWrapper(this.mistral, this.tracer);
19
+ }
20
+ }
21
+ class OCRWrapper {
22
+ constructor(mistral, tracer) {
23
+ this.mistral = mistral;
24
+ this.tracer = tracer;
25
+ }
26
+ process(request, options) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const currentSpan = trace.getSpan(context.active());
29
+ if (!currentSpan) {
30
+ throw new Error("No active span found, make sure to call this inside of a callback to paid.trace().");
31
+ }
32
+ const externalCustomerId = getCustomerIdStorage();
33
+ const externalAgentId = getAgentIdStorage();
34
+ const token = getTokenStorage();
35
+ if (!token || !externalCustomerId) {
36
+ throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
37
+ }
38
+ return this.tracer.startActiveSpan("trace.mistral.ocr", (span) => __awaiter(this, void 0, void 0, function* () {
39
+ var _a;
40
+ const attributes = {
41
+ "gen_ai.system": "mistral",
42
+ "gen_ai.operation.name": "ocr",
43
+ external_customer_id: externalCustomerId,
44
+ token: token,
45
+ };
46
+ if (externalAgentId) {
47
+ attributes["external_agent_id"] = externalAgentId;
48
+ }
49
+ // Check if annotations are requested
50
+ if (request.bboxAnnotationFormat || request.documentAnnotationFormat) {
51
+ attributes["gen_ai.ocr.annotated"] = "true";
52
+ }
53
+ // Set request model
54
+ if (request.model) {
55
+ attributes["gen_ai.request.model"] = request.model;
56
+ }
57
+ span.setAttributes(attributes);
58
+ try {
59
+ const response = yield this.mistral.ocr.process(request, options);
60
+ // Add usage information from response
61
+ if (((_a = response.usageInfo) === null || _a === void 0 ? void 0 : _a.pagesProcessed) !== undefined) {
62
+ span.setAttribute("gen_ai.ocr.pages_processed", response.usageInfo.pagesProcessed);
63
+ }
64
+ if (response.model) {
65
+ span.setAttribute("gen_ai.response.model", response.model);
66
+ }
67
+ span.setStatus({ code: SpanStatusCode.OK });
68
+ return response;
69
+ }
70
+ catch (error) {
71
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
72
+ span.recordException(error);
73
+ throw error;
74
+ }
75
+ finally {
76
+ span.end();
77
+ }
78
+ }));
79
+ });
80
+ }
81
+ }