@paid-ai/paid-node 0.0.8-alpha1 → 0.0.8-alpha3
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 +17 -16
- package/dist/cjs/Client.d.ts +3 -2
- package/dist/cjs/Client.js +12 -4
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +7 -4
- package/dist/cjs/tracing/signal.d.ts +1 -0
- package/dist/cjs/tracing/signal.js +45 -0
- package/dist/cjs/tracing/tracing.d.ts +7 -3
- package/dist/cjs/tracing/tracing.js +78 -31
- package/dist/cjs/tracing/wrappers/anthropicWrapper.d.ts +16 -0
- package/dist/cjs/tracing/wrappers/anthropicWrapper.js +84 -0
- package/dist/cjs/tracing/wrappers/langchainCallback.d.ts +21 -0
- package/dist/cjs/tracing/wrappers/langchainCallback.js +142 -0
- package/dist/cjs/tracing/wrappers/mistralWrapper.d.ts +17 -0
- package/dist/cjs/tracing/wrappers/mistralWrapper.js +81 -0
- package/dist/cjs/tracing/wrappers/openAiWrapper.js +42 -56
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wrapper/BatchUsage.d.ts +1 -1
- package/dist/cjs/wrapper/BatchUsage.js +2 -2
- package/dist/esm/Client.d.mts +3 -2
- package/dist/esm/Client.mjs +13 -5
- package/dist/esm/index.d.mts +3 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/tracing/signal.d.mts +1 -0
- package/dist/esm/tracing/signal.mjs +42 -0
- package/dist/esm/tracing/tracing.d.mts +7 -3
- package/dist/esm/tracing/tracing.mjs +73 -30
- package/dist/esm/tracing/wrappers/anthropicWrapper.d.mts +16 -0
- package/dist/esm/tracing/wrappers/anthropicWrapper.mjs +80 -0
- package/dist/esm/tracing/wrappers/langchainCallback.d.mts +21 -0
- package/dist/esm/tracing/wrappers/langchainCallback.mjs +138 -0
- package/dist/esm/tracing/wrappers/mistralWrapper.d.mts +17 -0
- package/dist/esm/tracing/wrappers/mistralWrapper.mjs +77 -0
- package/dist/esm/tracing/wrappers/openAiWrapper.mjs +42 -56
- package/dist/esm/version.d.mts +1 -1
- package/dist/esm/version.mjs +1 -1
- package/dist/esm/wrapper/BatchUsage.d.mts +1 -1
- package/dist/esm/wrapper/BatchUsage.mjs +1 -1
- package/package.json +7 -3
- package/dist/cjs/tracing/index.d.ts +0 -1
- package/dist/cjs/tracing/index.js +0 -17
- package/dist/esm/tracing/index.d.mts +0 -1
- package/dist/esm/tracing/index.mjs +0 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</picture>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
#
|
|
11
11
|
|
|
12
12
|
<div align="center">
|
|
13
13
|
<a href="https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2FAgentPaid%2Fpaid-node">
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
</a>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
|
-
Paid is the all-in-one, drop-in Business Engine for AI Agents that handles your pricing, subscriptions, margins, billing, and renewals with just 5 lines of code.
|
|
22
|
-
The Paid TypeScript library provides convenient access to the Paid API from TypeScript.
|
|
21
|
+
Paid is the all-in-one, drop-in Business Engine for AI Agents that handles your pricing, subscriptions, margins, billing, and renewals with just 5 lines of code.
|
|
22
|
+
The Paid TypeScript library provides convenient access to the Paid API from TypeScript.
|
|
23
23
|
|
|
24
24
|
## Documentation
|
|
25
25
|
|
|
@@ -33,7 +33,7 @@ npm install -s @paid-ai/paid-node
|
|
|
33
33
|
|
|
34
34
|
## Usage
|
|
35
35
|
|
|
36
|
-
The client needs to be configured with your account's API key, which is available in the [Paid dashboard](https://app.paid.ai/agent-integration/api-keys).
|
|
36
|
+
The client needs to be configured with your account's API key, which is available in the [Paid dashboard](https://app.paid.ai/agent-integration/api-keys).
|
|
37
37
|
|
|
38
38
|
```typescript
|
|
39
39
|
import { PaidClient } from "@paid-ai/paid-node";
|
|
@@ -78,17 +78,18 @@ try {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
## Logging
|
|
82
|
+
Logs are silent by default.
|
|
83
|
+
|
|
84
|
+
To enable logs, set the `PAID_LOG_LEVEL` environment variable. Available levels include:
|
|
85
|
+
`error`, `warn`, `info`, `http`, `verbose`, `debug`, and `silly`.
|
|
86
|
+
|
|
87
|
+
Example: `PAID_LOG_LEVEL=debug node your-app.js`
|
|
88
|
+
|
|
81
89
|
## Cost Tracking
|
|
82
90
|
|
|
83
91
|
It's possible to track usage costs by using Paid wrappers around you AI provider API.
|
|
84
|
-
As of now, the following
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
chat.completions.create()
|
|
88
|
-
responses.create()
|
|
89
|
-
images.generate()
|
|
90
|
-
embeddings.create()
|
|
91
|
-
```
|
|
92
|
+
As of now, the following AI providers are supported: `OpenAI`, `Anthropic`, `Mistral` (OCR), and `Langchain`.
|
|
92
93
|
|
|
93
94
|
Example usage:
|
|
94
95
|
|
|
@@ -98,16 +99,16 @@ import OpenAI from "openai";
|
|
|
98
99
|
|
|
99
100
|
async function main() {
|
|
100
101
|
const client = new PaidClient({ token: "<your_paid_api_key>" });
|
|
101
|
-
const openaiClient = new OpenAI({ apiKey: "<your_openai_api_key" });
|
|
102
102
|
|
|
103
103
|
// initialize cost tracking
|
|
104
104
|
await client.initializeTracing()
|
|
105
105
|
|
|
106
106
|
// wrap openai in paid wrapper
|
|
107
|
+
const openaiClient = new OpenAI({ apiKey: "<your_openai_api_key" });
|
|
107
108
|
const paidOpenAiWrapper = new PaidOpenAI(openaiClient);
|
|
108
109
|
|
|
109
|
-
//
|
|
110
|
-
await client.
|
|
110
|
+
// trace the call
|
|
111
|
+
await client.trace("<your_external_customer_id>", async () => {
|
|
111
112
|
const response = await paidOpenAiWrapper.images.generate({
|
|
112
113
|
prompt: "A beautiful sunset over the mountains",
|
|
113
114
|
n: 1,
|
|
@@ -116,7 +117,7 @@ async function main() {
|
|
|
116
117
|
if (response.data) {
|
|
117
118
|
console.log("Image generation:", response.data[0].url);
|
|
118
119
|
}
|
|
119
|
-
});
|
|
120
|
+
}, "<optional_external_agent_id>");
|
|
120
121
|
}
|
|
121
122
|
```
|
|
122
123
|
|
package/dist/cjs/Client.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare class PaidClient {
|
|
|
41
41
|
get contacts(): Contacts;
|
|
42
42
|
get orders(): Orders;
|
|
43
43
|
get usage(): Usage;
|
|
44
|
-
initializeTracing(): Promise<void>;
|
|
45
|
-
|
|
44
|
+
initializeTracing(collectorEndpoint?: string): Promise<void>;
|
|
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
|
}
|
package/dist/cjs/Client.js
CHANGED
|
@@ -54,6 +54,7 @@ const Client_js_3 = require("./api/resources/contacts/client/Client.js");
|
|
|
54
54
|
const Client_js_4 = require("./api/resources/orders/client/Client.js");
|
|
55
55
|
const BatchUsage_js_1 = require("./wrapper/BatchUsage.js");
|
|
56
56
|
const tracing_js_1 = require("./tracing/tracing.js");
|
|
57
|
+
const signal_js_1 = require("./tracing/signal.js");
|
|
57
58
|
class PaidClient {
|
|
58
59
|
constructor(_options) {
|
|
59
60
|
this._options = Object.assign(Object.assign({}, _options), { headers: (0, headers_js_1.mergeHeaders)({
|
|
@@ -85,18 +86,25 @@ class PaidClient {
|
|
|
85
86
|
var _a;
|
|
86
87
|
return ((_a = this._usage) !== null && _a !== void 0 ? _a : (this._usage = new BatchUsage_js_1.Usage(this._options)));
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
+
// Need to call this method before using tracing or creating wrappers.
|
|
90
|
+
initializeTracing(collectorEndpoint) {
|
|
89
91
|
return __awaiter(this, void 0, void 0, function* () {
|
|
90
92
|
const tokenSupplier = this._options.token;
|
|
91
93
|
const token = typeof tokenSupplier === "function" ? yield tokenSupplier() : tokenSupplier;
|
|
92
94
|
const resolvedToken = yield Promise.resolve(token);
|
|
93
|
-
(0, tracing_js_1.
|
|
95
|
+
(0, tracing_js_1._initializeTracing)(resolvedToken, collectorEndpoint);
|
|
94
96
|
});
|
|
95
97
|
}
|
|
96
|
-
|
|
98
|
+
// Use this method to track actions like LLM usage and sending signals.
|
|
99
|
+
// The callback to this function is the work that you want to trace.
|
|
100
|
+
trace(externalCustomerId, fn, externalAgentId, ...args) {
|
|
97
101
|
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
-
return yield (0, tracing_js_1.
|
|
102
|
+
return yield (0, tracing_js_1._trace)(externalCustomerId, fn, externalAgentId, ...args);
|
|
99
103
|
});
|
|
100
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);
|
|
108
|
+
}
|
|
101
109
|
}
|
|
102
110
|
exports.PaidClient = PaidClient;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -3,4 +3,6 @@ export { PaidClient } from "./Client.js";
|
|
|
3
3
|
export { PaidError, PaidTimeoutError } from "./errors/index.js";
|
|
4
4
|
export { PaidEnvironment } from "./environments.js";
|
|
5
5
|
export { PaidOpenAI } from "./tracing/wrappers/openAiWrapper.js";
|
|
6
|
-
export {
|
|
6
|
+
export { PaidAnthropic } from "./tracing/wrappers/anthropicWrapper.js";
|
|
7
|
+
export { PaidMistral } from "./tracing/wrappers/mistralWrapper.js";
|
|
8
|
+
export { PaidLangChainCallback } from "./tracing/wrappers/langchainCallback.js";
|
package/dist/cjs/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.PaidLangChainCallback = exports.PaidMistral = exports.PaidAnthropic = exports.PaidOpenAI = exports.PaidEnvironment = exports.PaidTimeoutError = exports.PaidError = exports.PaidClient = exports.Paid = void 0;
|
|
37
37
|
exports.Paid = __importStar(require("./api/index.js"));
|
|
38
38
|
var Client_js_1 = require("./Client.js");
|
|
39
39
|
Object.defineProperty(exports, "PaidClient", { enumerable: true, get: function () { return Client_js_1.PaidClient; } });
|
|
@@ -44,6 +44,9 @@ var environments_js_1 = require("./environments.js");
|
|
|
44
44
|
Object.defineProperty(exports, "PaidEnvironment", { enumerable: true, get: function () { return environments_js_1.PaidEnvironment; } });
|
|
45
45
|
var openAiWrapper_js_1 = require("./tracing/wrappers/openAiWrapper.js");
|
|
46
46
|
Object.defineProperty(exports, "PaidOpenAI", { enumerable: true, get: function () { return openAiWrapper_js_1.PaidOpenAI; } });
|
|
47
|
-
var
|
|
48
|
-
Object.defineProperty(exports, "
|
|
49
|
-
|
|
47
|
+
var anthropicWrapper_js_1 = require("./tracing/wrappers/anthropicWrapper.js");
|
|
48
|
+
Object.defineProperty(exports, "PaidAnthropic", { enumerable: true, get: function () { return anthropicWrapper_js_1.PaidAnthropic; } });
|
|
49
|
+
var mistralWrapper_js_1 = require("./tracing/wrappers/mistralWrapper.js");
|
|
50
|
+
Object.defineProperty(exports, "PaidMistral", { enumerable: true, get: function () { return mistralWrapper_js_1.PaidMistral; } });
|
|
51
|
+
var langchainCallback_js_1 = require("./tracing/wrappers/langchainCallback.js");
|
|
52
|
+
Object.defineProperty(exports, "PaidLangChainCallback", { enumerable: true, get: function () { return langchainCallback_js_1.PaidLangChainCallback; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function _signal(eventName: string, data?: Record<string, any>): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._signal = _signal;
|
|
4
|
+
const api_1 = require("@opentelemetry/api");
|
|
5
|
+
const tracing_js_1 = require("./tracing.js");
|
|
6
|
+
const tracing_js_2 = require("./tracing.js");
|
|
7
|
+
function _signal(eventName, data) {
|
|
8
|
+
if (!eventName) {
|
|
9
|
+
throw new Error("Event name is required for signal.");
|
|
10
|
+
}
|
|
11
|
+
const externalCustomerId = (0, tracing_js_1.getCustomerIdStorage)();
|
|
12
|
+
const externalAgentId = (0, tracing_js_1.getAgentIdStorage)();
|
|
13
|
+
const token = (0, tracing_js_1.getTokenStorage)();
|
|
14
|
+
if (!externalCustomerId || !externalAgentId || !token) {
|
|
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
|
+
}
|
|
17
|
+
const tracer = tracing_js_2.paidTracer;
|
|
18
|
+
tracer.startActiveSpan("trace.signal", (span) => {
|
|
19
|
+
try {
|
|
20
|
+
const attributes = {
|
|
21
|
+
external_customer_id: externalCustomerId,
|
|
22
|
+
external_agent_id: externalAgentId,
|
|
23
|
+
event_name: eventName,
|
|
24
|
+
token: token,
|
|
25
|
+
};
|
|
26
|
+
// Optional data (ex. manual cost tracking)
|
|
27
|
+
if (data) {
|
|
28
|
+
attributes["data"] = JSON.stringify(data);
|
|
29
|
+
}
|
|
30
|
+
span.setAttributes(attributes);
|
|
31
|
+
// Mark span as successful
|
|
32
|
+
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
span.setStatus({
|
|
36
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
37
|
+
message: error.message,
|
|
38
|
+
});
|
|
39
|
+
span.recordException(error);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
span.end();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import winston from "winston";
|
|
2
|
+
export declare const logger: winston.Logger;
|
|
3
|
+
export declare let paidTracer: import("@opentelemetry/api").Tracer;
|
|
4
|
+
export declare const getCustomerIdStorage: () => string | null | undefined;
|
|
5
|
+
export declare const getAgentIdStorage: () => string | null | undefined;
|
|
2
6
|
export declare const getTokenStorage: () => string | null | undefined;
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
7
|
+
export declare function _initializeTracing(apiKey: string, collectorEndpoint?: string): void;
|
|
8
|
+
export declare function _trace<T extends (...args: any[]) => any>(externalCustomerId: string, fn: T, externalAgentId: string | undefined, ...args: Parameters<T>): Promise<ReturnType<T>>;
|
|
@@ -8,56 +8,103 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.getTokenStorage = exports.
|
|
13
|
-
exports.
|
|
14
|
-
exports.
|
|
15
|
-
const
|
|
15
|
+
exports.getTokenStorage = exports.getAgentIdStorage = exports.getCustomerIdStorage = exports.paidTracer = exports.logger = void 0;
|
|
16
|
+
exports._initializeTracing = _initializeTracing;
|
|
17
|
+
exports._trace = _trace;
|
|
18
|
+
const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
|
|
16
19
|
const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
|
|
20
|
+
const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
17
21
|
const api_1 = require("@opentelemetry/api");
|
|
18
22
|
const async_hooks_1 = require("async_hooks");
|
|
23
|
+
const winston_1 = __importDefault(require("winston"));
|
|
24
|
+
exports.logger = winston_1.default.createLogger({
|
|
25
|
+
level: "silent", // Default to 'silent' to avoid logging unless set via environment variable
|
|
26
|
+
format: winston_1.default.format.simple(),
|
|
27
|
+
transports: [new winston_1.default.transports.Console()],
|
|
28
|
+
});
|
|
29
|
+
const logLevel = process.env.PAID_LOG_LEVEL;
|
|
30
|
+
if (logLevel) {
|
|
31
|
+
exports.logger.level = logLevel;
|
|
32
|
+
}
|
|
33
|
+
const COLLECTOR_ENDPOINT = process.env.PAID_COLLECTOR_ENDPOINT || "https://collector.agentpaid.io:4318/v1/traces";
|
|
34
|
+
// set up default tracing provider
|
|
35
|
+
let paidExporter = new exporter_trace_otlp_http_1.OTLPTraceExporter({ url: COLLECTOR_ENDPOINT });
|
|
36
|
+
let spanProcessor = new sdk_trace_base_1.BatchSpanProcessor(paidExporter);
|
|
37
|
+
let paidTracerProvider = new sdk_trace_node_1.NodeTracerProvider({ spanProcessors: [spanProcessor] });
|
|
38
|
+
exports.paidTracer = paidTracerProvider.getTracer("paid.node");
|
|
39
|
+
// storage for passing info to child spans
|
|
19
40
|
const customerIdStorage = new async_hooks_1.AsyncLocalStorage();
|
|
41
|
+
const agentIdStorage = new async_hooks_1.AsyncLocalStorage();
|
|
20
42
|
const tokenStorage = new async_hooks_1.AsyncLocalStorage();
|
|
21
|
-
const
|
|
22
|
-
exports.
|
|
43
|
+
const getCustomerIdStorage = () => customerIdStorage.getStore();
|
|
44
|
+
exports.getCustomerIdStorage = getCustomerIdStorage;
|
|
45
|
+
const getAgentIdStorage = () => agentIdStorage.getStore();
|
|
46
|
+
exports.getAgentIdStorage = getAgentIdStorage;
|
|
23
47
|
const getTokenStorage = () => tokenStorage.getStore();
|
|
24
48
|
exports.getTokenStorage = getTokenStorage;
|
|
25
49
|
let _token;
|
|
26
|
-
const setToken = (token) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
sdk.start();
|
|
37
|
-
// Graceful shutdown
|
|
38
|
-
['SIGINT', 'SIGTERM'].forEach(signal => {
|
|
50
|
+
const setToken = (token) => {
|
|
51
|
+
_token = token;
|
|
52
|
+
};
|
|
53
|
+
const getToken = () => {
|
|
54
|
+
return _token;
|
|
55
|
+
};
|
|
56
|
+
let _isShuttingDown = false;
|
|
57
|
+
function setupGracefulShutdown(shuttable) {
|
|
58
|
+
["SIGINT", "SIGTERM", "beforeExit", "uncaughtException", "unhandledRejection"].forEach((signal) => {
|
|
39
59
|
process.on(signal, () => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
if (_isShuttingDown) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
_isShuttingDown = true;
|
|
64
|
+
shuttable
|
|
65
|
+
.shutdown()
|
|
66
|
+
.then(() => exports.logger.info(`Paid tracing SDK shut down from signal: ${signal}`))
|
|
67
|
+
.catch((error) => exports.logger.error(`Error shutting down Paid tracing SDK ${error}`));
|
|
43
68
|
});
|
|
44
69
|
});
|
|
45
70
|
}
|
|
46
|
-
function
|
|
71
|
+
function _initializeTracing(apiKey, collectorEndpoint) {
|
|
72
|
+
if (getToken()) {
|
|
73
|
+
throw new Error("Tracing SDK is already initialized.");
|
|
74
|
+
}
|
|
75
|
+
if (!apiKey) {
|
|
76
|
+
throw new Error("Cannot initialize tracing SDK - first initialize the PaidClient with an API key");
|
|
77
|
+
}
|
|
78
|
+
if (collectorEndpoint) {
|
|
79
|
+
paidExporter = new exporter_trace_otlp_http_1.OTLPTraceExporter({ url: collectorEndpoint });
|
|
80
|
+
spanProcessor = new sdk_trace_base_1.BatchSpanProcessor(paidExporter);
|
|
81
|
+
paidTracerProvider = new sdk_trace_node_1.NodeTracerProvider({ spanProcessors: [spanProcessor] });
|
|
82
|
+
exports.paidTracer = paidTracerProvider.getTracer("paid.node");
|
|
83
|
+
}
|
|
84
|
+
setupGracefulShutdown(spanProcessor);
|
|
85
|
+
setToken(apiKey);
|
|
86
|
+
const collectorAddress = collectorEndpoint || COLLECTOR_ENDPOINT;
|
|
87
|
+
exports.logger.info(`Paid tracing SDK initialized with collector endpoint: ${collectorAddress}`);
|
|
88
|
+
}
|
|
89
|
+
function _trace(externalCustomerId, fn, externalAgentId, ...args) {
|
|
47
90
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const tracer =
|
|
91
|
+
const tracer = exports.paidTracer;
|
|
49
92
|
const token = getToken();
|
|
50
|
-
if (!token) {
|
|
51
|
-
|
|
52
|
-
return fn(...args);
|
|
93
|
+
if (!token || !externalCustomerId) {
|
|
94
|
+
throw new Error(`Paid tracing is not initialized. Make sure to call initializeTracing() first.`);
|
|
53
95
|
}
|
|
54
96
|
return tracer.startActiveSpan("paid.node", (span) => __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
span.setAttribute(
|
|
56
|
-
span.setAttribute(
|
|
97
|
+
span.setAttribute("external_customer_id", externalCustomerId);
|
|
98
|
+
span.setAttribute("token", token);
|
|
99
|
+
if (externalAgentId) {
|
|
100
|
+
span.setAttribute("external_agent_id", externalAgentId);
|
|
101
|
+
}
|
|
57
102
|
try {
|
|
58
103
|
const result = yield customerIdStorage.run(externalCustomerId, () => __awaiter(this, void 0, void 0, function* () {
|
|
59
|
-
return yield
|
|
60
|
-
return yield
|
|
104
|
+
return yield agentIdStorage.run(externalAgentId !== null && externalAgentId !== void 0 ? externalAgentId : null, () => __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
return yield tokenStorage.run(token, () => __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
return yield fn(...args);
|
|
107
|
+
}));
|
|
61
108
|
}));
|
|
62
109
|
}));
|
|
63
110
|
span.setStatus({ code: api_1.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
|
+
"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.PaidAnthropic = void 0;
|
|
13
|
+
const api_1 = require("@opentelemetry/api");
|
|
14
|
+
const tracing_js_1 = require("../tracing.js");
|
|
15
|
+
class PaidAnthropic {
|
|
16
|
+
constructor(anthropicClient) {
|
|
17
|
+
this.anthropic = anthropicClient;
|
|
18
|
+
this.tracer = tracing_js_1.paidTracer;
|
|
19
|
+
}
|
|
20
|
+
get messages() {
|
|
21
|
+
return new MessagesWrapper(this.anthropic, this.tracer);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.PaidAnthropic = PaidAnthropic;
|
|
25
|
+
class MessagesWrapper {
|
|
26
|
+
constructor(anthropic, tracer) {
|
|
27
|
+
this.anthropic = anthropic;
|
|
28
|
+
this.tracer = tracer;
|
|
29
|
+
}
|
|
30
|
+
create(params) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const externalCustomerId = (0, tracing_js_1.getCustomerIdStorage)();
|
|
33
|
+
const externalAgentId = (0, tracing_js_1.getAgentIdStorage)();
|
|
34
|
+
const token = (0, tracing_js_1.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: api_1.SpanStatusCode.OK });
|
|
71
|
+
return response;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
span.setStatus({ code: api_1.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
|
+
"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.PaidLangChainCallback = void 0;
|
|
13
|
+
const base_1 = require("@langchain/core/callbacks/base");
|
|
14
|
+
const api_1 = require("@opentelemetry/api");
|
|
15
|
+
const tracing_js_1 = require("../tracing.js");
|
|
16
|
+
class PaidLangChainCallback extends base_1.BaseCallbackHandler {
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.name = "PaidLangChainCallback";
|
|
20
|
+
this.spans = new Map();
|
|
21
|
+
this.tracer = tracing_js_1.paidTracer;
|
|
22
|
+
}
|
|
23
|
+
extractProvider(serialized) {
|
|
24
|
+
if (!(serialized === null || serialized === void 0 ? void 0 : serialized.id))
|
|
25
|
+
return "unknown";
|
|
26
|
+
const idStr = serialized.id.join(" ").toLowerCase();
|
|
27
|
+
if (idStr.includes("openai"))
|
|
28
|
+
return "openai";
|
|
29
|
+
if (idStr.includes("anthropic"))
|
|
30
|
+
return "anthropic";
|
|
31
|
+
if (idStr.includes("mistral"))
|
|
32
|
+
return "mistral";
|
|
33
|
+
if (idStr.includes("cohere"))
|
|
34
|
+
return "cohere";
|
|
35
|
+
if (idStr.includes("huggingface"))
|
|
36
|
+
return "huggingface";
|
|
37
|
+
if (idStr.includes("azure"))
|
|
38
|
+
return "azure";
|
|
39
|
+
return "unknown";
|
|
40
|
+
}
|
|
41
|
+
handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
const externalCustomerId = (0, tracing_js_1.getCustomerIdStorage)();
|
|
44
|
+
const externalAgentId = (0, tracing_js_1.getAgentIdStorage)();
|
|
45
|
+
const token = (0, tracing_js_1.getTokenStorage)();
|
|
46
|
+
if (!token || !externalCustomerId) {
|
|
47
|
+
throw new Error("No token or externalCustomerId: This wrapper should be used inside a callback to paid.trace().");
|
|
48
|
+
}
|
|
49
|
+
const modelType = (metadata === null || metadata === void 0 ? void 0 : metadata.ls_model_type) || "unknown";
|
|
50
|
+
const modelName = (metadata === null || metadata === void 0 ? void 0 : metadata.ls_model_name) || "unknown";
|
|
51
|
+
const spanName = `trace.langchain.${modelType}`;
|
|
52
|
+
const span = this.tracer.startSpan(spanName);
|
|
53
|
+
const attributes = {
|
|
54
|
+
"gen_ai.system": this.extractProvider(llm),
|
|
55
|
+
"gen_ai.operation.name": modelType,
|
|
56
|
+
"gen_ai.request.model": modelName,
|
|
57
|
+
external_customer_id: externalCustomerId,
|
|
58
|
+
token: token,
|
|
59
|
+
};
|
|
60
|
+
if (externalAgentId) {
|
|
61
|
+
attributes["external_agent_id"] = externalAgentId;
|
|
62
|
+
}
|
|
63
|
+
span.setAttributes(attributes);
|
|
64
|
+
this.spans.set(runId, span);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
handleLLMEnd(output, runId, parentRunId) {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
70
|
+
const span = this.spans.get(runId);
|
|
71
|
+
if (!span)
|
|
72
|
+
return;
|
|
73
|
+
try {
|
|
74
|
+
const attributes = {};
|
|
75
|
+
// Extract token usage information
|
|
76
|
+
if ((_a = output.llmOutput) === null || _a === void 0 ? void 0 : _a.tokenUsage) {
|
|
77
|
+
const usage = output.llmOutput.tokenUsage;
|
|
78
|
+
if (usage.promptTokens !== undefined) {
|
|
79
|
+
attributes["gen_ai.usage.input_tokens"] = usage.promptTokens;
|
|
80
|
+
}
|
|
81
|
+
if (usage.completionTokens !== undefined) {
|
|
82
|
+
attributes["gen_ai.usage.output_tokens"] = usage.completionTokens;
|
|
83
|
+
}
|
|
84
|
+
if (usage.cachedInputTokens !== undefined) {
|
|
85
|
+
attributes["gen_ai.usage.cached_input_tokens"] = usage.cachedInputTokens;
|
|
86
|
+
}
|
|
87
|
+
if (usage.reasoningOutputTokens !== undefined) {
|
|
88
|
+
attributes["gen_ai.usage.reasoning_output_tokens"] = usage.reasoningOutputTokens;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Alternative token usage format (some providers use different field names)
|
|
92
|
+
if ((_b = output.llmOutput) === null || _b === void 0 ? void 0 : _b.token_usage) {
|
|
93
|
+
const usage = output.llmOutput.token_usage;
|
|
94
|
+
if (usage.prompt_tokens !== undefined) {
|
|
95
|
+
attributes["gen_ai.usage.input_tokens"] = usage.prompt_tokens;
|
|
96
|
+
}
|
|
97
|
+
if (usage.completion_tokens !== undefined) {
|
|
98
|
+
attributes["gen_ai.usage.output_tokens"] = usage.completion_tokens;
|
|
99
|
+
}
|
|
100
|
+
if (usage.cached_input_tokens !== undefined) {
|
|
101
|
+
attributes["gen_ai.usage.cached_input_tokens"] = usage.cached_input_tokens;
|
|
102
|
+
}
|
|
103
|
+
if (usage.reasoning_output_tokens !== undefined) {
|
|
104
|
+
attributes["gen_ai.usage.reasoning_output_tokens"] = usage.reasoning_output_tokens;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Add model from response if available
|
|
108
|
+
if ((_c = output.llmOutput) === null || _c === void 0 ? void 0 : _c.modelName) {
|
|
109
|
+
attributes["gen_ai.response.model"] = output.llmOutput.modelName;
|
|
110
|
+
}
|
|
111
|
+
else if ((_d = output.llmOutput) === null || _d === void 0 ? void 0 : _d.model_name) {
|
|
112
|
+
attributes["gen_ai.response.model"] = output.llmOutput.model_name;
|
|
113
|
+
}
|
|
114
|
+
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) {
|
|
115
|
+
attributes["gen_ai.response.model"] = output.generations[0][0].message["response_metadata"].model_name;
|
|
116
|
+
}
|
|
117
|
+
span.setAttributes(attributes);
|
|
118
|
+
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
span.end();
|
|
122
|
+
this.spans.delete(runId);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
handleLLMError(err, runId, parentRunId) {
|
|
127
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
const span = this.spans.get(runId);
|
|
129
|
+
if (!span)
|
|
130
|
+
return;
|
|
131
|
+
try {
|
|
132
|
+
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: err.message });
|
|
133
|
+
span.recordException(err);
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
span.end();
|
|
137
|
+
this.spans.delete(runId);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.PaidLangChainCallback = PaidLangChainCallback;
|
|
@@ -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 {};
|