openlit 1.6.0 → 1.7.1
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 +19 -1
- package/dist/helpers.js +8 -4
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +19 -6
- package/dist/index.js.map +1 -1
- package/dist/instrumentation/__tests__/anthropic-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/anthropic-wrapper.test.js +92 -0
- package/dist/instrumentation/__tests__/anthropic-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/base-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/base-wrapper.test.js +175 -0
- package/dist/instrumentation/__tests__/base-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/cohere-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/cohere-wrapper.test.js +131 -0
- package/dist/instrumentation/__tests__/cohere-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/openai-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/openai-wrapper.test.js +181 -0
- package/dist/instrumentation/__tests__/openai-wrapper.test.js.map +1 -0
- package/dist/instrumentation/anthropic/wrapper.d.ts +7 -1
- package/dist/instrumentation/anthropic/wrapper.js +16 -1
- package/dist/instrumentation/anthropic/wrapper.js.map +1 -1
- package/dist/instrumentation/base-wrapper.d.ts +3 -2
- package/dist/instrumentation/base-wrapper.js +81 -1
- package/dist/instrumentation/base-wrapper.js.map +1 -1
- package/dist/instrumentation/cohere/wrapper.d.ts +7 -1
- package/dist/instrumentation/cohere/wrapper.js +19 -2
- package/dist/instrumentation/cohere/wrapper.js.map +1 -1
- package/dist/instrumentation/ollama/wrapper.d.ts +2 -1
- package/dist/instrumentation/ollama/wrapper.js +2 -2
- package/dist/instrumentation/ollama/wrapper.js.map +1 -1
- package/dist/instrumentation/openai/index.js +11 -0
- package/dist/instrumentation/openai/index.js.map +1 -1
- package/dist/instrumentation/openai/wrapper.d.ts +39 -3
- package/dist/instrumentation/openai/wrapper.js +537 -26
- package/dist/instrumentation/openai/wrapper.js.map +1 -1
- package/dist/otel/__tests__/metrics.test.d.ts +1 -0
- package/dist/otel/__tests__/metrics.test.js +51 -0
- package/dist/otel/__tests__/metrics.test.js.map +1 -0
- package/dist/otel/metrics.d.ts +22 -0
- package/dist/otel/metrics.js +132 -0
- package/dist/otel/metrics.js.map +1 -0
- package/dist/{tracing.d.ts → otel/tracing.d.ts} +1 -1
- package/dist/{tracing.js → otel/tracing.js} +17 -15
- package/dist/otel/tracing.js.map +1 -0
- package/dist/semantic-convention.d.ts +36 -0
- package/dist/semantic-convention.js +53 -11
- package/dist/semantic-convention.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/package.json +10 -11
- package/dist/tracing.js.map +0 -1
package/README.md
CHANGED
|
@@ -54,6 +54,24 @@ This project proudly follows and maintains the [Semantic Conventions](https://gi
|
|
|
54
54
|
- [✅ OpenObserve](https://docs.openlit.io/latest/connections/openobserve)
|
|
55
55
|
- [✅ Highlight.io](https://docs.openlit.io/latest/connections/highlight)
|
|
56
56
|
|
|
57
|
+
## Supported Metrics
|
|
58
|
+
|
|
59
|
+
> **Note:** Metrics tracking in the TypeScript SDK is only available for Anthropic, Cohere, Ollama, and OpenAI integrations.
|
|
60
|
+
|
|
61
|
+
The following metrics are supported:
|
|
62
|
+
|
|
63
|
+
- **genaiClientUsageTokens**: Histogram for total input/output tokens used.
|
|
64
|
+
- **genaiClientOperationDuration**: Histogram for GenAI operation duration.
|
|
65
|
+
- **genaiServerTbt**: Histogram for time per output token after the first token.
|
|
66
|
+
- **genaiServerTtft**: Histogram for time to first token for successful responses.
|
|
67
|
+
- **genaiRequests**: Counter for number of GenAI requests.
|
|
68
|
+
- **genaiPromptTokens**: Counter for number of prompt tokens processed.
|
|
69
|
+
- **genaiCompletionTokens**: Counter for number of completion tokens processed.
|
|
70
|
+
- **genaiReasoningTokens**: Counter for number of reasoning thought tokens processed.
|
|
71
|
+
- **genaiCost**: Histogram for distribution of GenAI request costs (USD).
|
|
72
|
+
|
|
73
|
+
These metrics allow you to monitor usage, performance, and cost for supported GenAI operations.
|
|
74
|
+
|
|
57
75
|
## 💿 Installation
|
|
58
76
|
|
|
59
77
|
```bash
|
|
@@ -143,7 +161,7 @@ Now that your LLM observability data is being collected and sent to configured O
|
|
|
143
161
|
|
|
144
162
|
If you want to use OpenLIT's Observability Dashboard to monitor LLM usage—like cost, tokens, and user interactions—please check out our [Quickstart Guide](https://docs.openlit.io/latest/quickstart).
|
|
145
163
|
|
|
146
|
-
If you're sending metrics and traces to other observability tools, take a look at our [Connections Guide](https://docs.openlit.io/latest/
|
|
164
|
+
If you're sending metrics and traces to other observability tools, take a look at our [Connections Guide](https://docs.openlit.io/latest/destinations/intro) to start using a pre-built dashboard we have created for these tools.
|
|
147
165
|
|
|
148
166
|

|
|
149
167
|
|
package/dist/helpers.js
CHANGED
|
@@ -19,9 +19,10 @@ class OpenLitHelper {
|
|
|
19
19
|
}
|
|
20
20
|
static getChatModelCost(model, pricingInfo, promptTokens, completionTokens) {
|
|
21
21
|
try {
|
|
22
|
-
|
|
22
|
+
const cost = ((promptTokens / OpenLitHelper.PROMPT_TOKEN_FACTOR) * pricingInfo.chat[model].promptPrice +
|
|
23
23
|
(completionTokens / OpenLitHelper.PROMPT_TOKEN_FACTOR) *
|
|
24
24
|
pricingInfo.chat[model].completionPrice);
|
|
25
|
+
return isNaN(cost) ? 0 : cost;
|
|
25
26
|
}
|
|
26
27
|
catch (error) {
|
|
27
28
|
console.error(`Error in getChatModelCost: ${error}`);
|
|
@@ -30,7 +31,8 @@ class OpenLitHelper {
|
|
|
30
31
|
}
|
|
31
32
|
static getEmbedModelCost(model, pricingInfo, promptTokens) {
|
|
32
33
|
try {
|
|
33
|
-
|
|
34
|
+
const cost = (promptTokens / OpenLitHelper.PROMPT_TOKEN_FACTOR) * pricingInfo.embeddings[model];
|
|
35
|
+
return isNaN(cost) ? 0 : cost;
|
|
34
36
|
}
|
|
35
37
|
catch (error) {
|
|
36
38
|
console.error(`Error in getEmbedModelCost: ${error}`);
|
|
@@ -39,7 +41,8 @@ class OpenLitHelper {
|
|
|
39
41
|
}
|
|
40
42
|
static getImageModelCost(model, pricingInfo, size, quality) {
|
|
41
43
|
try {
|
|
42
|
-
|
|
44
|
+
const cost = pricingInfo.images[model][quality][size];
|
|
45
|
+
return isNaN(cost) ? 0 : cost;
|
|
43
46
|
}
|
|
44
47
|
catch (error) {
|
|
45
48
|
console.error(`Error in getImageModelCost: ${error}`);
|
|
@@ -48,7 +51,8 @@ class OpenLitHelper {
|
|
|
48
51
|
}
|
|
49
52
|
static getAudioModelCost(model, pricingInfo, prompt) {
|
|
50
53
|
try {
|
|
51
|
-
|
|
54
|
+
const cost = (prompt.length / OpenLitHelper.PROMPT_TOKEN_FACTOR) * pricingInfo.audio[model];
|
|
55
|
+
return isNaN(cost) ? 0 : cost;
|
|
52
56
|
}
|
|
53
57
|
catch (error) {
|
|
54
58
|
console.error(`Error in getAudioModelCost: ${error}`);
|
package/dist/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;AAAA,6CAA8D;AAC9D,4CAA0D;AAE1D,MAAqB,aAAa;IAGhC,MAAM,CAAC,YAAY,CAAC,IAAY,EAAE,KAAa;QAC7C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAA,8BAAgB,EAAC,KAAsB,CAAC,CAAC;YAC1D,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,IAAY;QAC/B,MAAM,QAAQ,GAAG,IAAA,8BAAgB,EAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,gBAAgB,CACrB,KAAa,EACb,WAAgB,EAChB,YAAoB,EACpB,gBAAwB;QAExB,IAAI,CAAC;YACH,
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
2
2
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
3
3
|
import { OpenlitOptions } from './types';
|
|
4
4
|
import BaseOpenlit from './features/base';
|
|
@@ -20,7 +20,7 @@ declare const guard: {
|
|
|
20
20
|
All: (options: ConstructorParameters<typeof GuardAll>[0]) => GuardAll;
|
|
21
21
|
};
|
|
22
22
|
declare class Openlit extends BaseOpenlit {
|
|
23
|
-
static resource:
|
|
23
|
+
static resource: ReturnType<typeof resourceFromAttributes>;
|
|
24
24
|
static options: OpenlitOptions;
|
|
25
25
|
static _sdk: NodeSDK;
|
|
26
26
|
static evals: {
|
package/dist/index.js
CHANGED
|
@@ -7,10 +7,12 @@ exports.Openlit = void 0;
|
|
|
7
7
|
const resources_1 = require("@opentelemetry/resources");
|
|
8
8
|
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
9
9
|
const sdk_node_1 = require("@opentelemetry/sdk-node");
|
|
10
|
-
const tracing_1 = __importDefault(require("./tracing"));
|
|
10
|
+
const tracing_1 = __importDefault(require("./otel/tracing"));
|
|
11
11
|
const constant_1 = require("./constant");
|
|
12
12
|
const base_1 = __importDefault(require("./features/base"));
|
|
13
13
|
const evals_1 = require("./evals");
|
|
14
|
+
const metrics_1 = __importDefault(require("./otel/metrics"));
|
|
15
|
+
const semantic_convention_1 = __importDefault(require("./semantic-convention"));
|
|
14
16
|
const prompt_injection_1 = require("./guard/prompt-injection");
|
|
15
17
|
const sensitive_topic_1 = require("./guard/sensitive-topic");
|
|
16
18
|
const topic_restriction_1 = require("./guard/topic-restriction");
|
|
@@ -33,7 +35,7 @@ class Openlit extends base_1.default {
|
|
|
33
35
|
static init(options) {
|
|
34
36
|
try {
|
|
35
37
|
const { environment = constant_1.DEFAULT_ENVIRONMENT, applicationName = constant_1.DEFAULT_APPLICATION_NAME } = options || {};
|
|
36
|
-
const otlpEndpoint = options?.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT ||
|
|
38
|
+
const otlpEndpoint = (options?.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318").replace(/\/v1\/traces$/, '');
|
|
37
39
|
let otlpHeaders = options?.otlpHeaders;
|
|
38
40
|
if (!otlpHeaders) {
|
|
39
41
|
if (process.env.OTEL_EXPORTER_OTLP_HEADERS) {
|
|
@@ -52,10 +54,10 @@ class Openlit extends base_1.default {
|
|
|
52
54
|
this.options.otlpHeaders = otlpHeaders;
|
|
53
55
|
this.options.disableBatch =
|
|
54
56
|
options?.disableBatch === undefined ? true : !!options.disableBatch;
|
|
55
|
-
this.resource =
|
|
56
|
-
[semantic_conventions_1.
|
|
57
|
-
[
|
|
58
|
-
[semantic_conventions_1.
|
|
57
|
+
this.resource = (0, resources_1.resourceFromAttributes)({
|
|
58
|
+
[semantic_conventions_1.ATTR_SERVICE_NAME]: applicationName,
|
|
59
|
+
[semantic_convention_1.default.ATTR_DEPLOYMENT_ENVIRONMENT]: environment,
|
|
60
|
+
[semantic_conventions_1.ATTR_TELEMETRY_SDK_NAME]: constant_1.SDK_NAME,
|
|
59
61
|
});
|
|
60
62
|
tracing_1.default.setup({
|
|
61
63
|
...this.options,
|
|
@@ -65,9 +67,20 @@ class Openlit extends base_1.default {
|
|
|
65
67
|
otlpHeaders,
|
|
66
68
|
resource: this.resource,
|
|
67
69
|
});
|
|
70
|
+
const exportIntervalMillis = Number(process.env.OTEL_EXPORTER_OTLP_METRICS_EXPORT_INTERVAL ?? 60000) || 60000;
|
|
71
|
+
metrics_1.default.setup({
|
|
72
|
+
...options,
|
|
73
|
+
environment,
|
|
74
|
+
applicationName,
|
|
75
|
+
otlpEndpoint,
|
|
76
|
+
otlpHeaders,
|
|
77
|
+
resource: this.resource,
|
|
78
|
+
exportIntervalMillis: exportIntervalMillis,
|
|
79
|
+
});
|
|
68
80
|
this._sdk = new sdk_node_1.NodeSDK({
|
|
69
81
|
resource: this.resource,
|
|
70
82
|
traceExporter: tracing_1.default.traceExporter,
|
|
83
|
+
metricReader: metrics_1.default.metricReaders[0],
|
|
71
84
|
});
|
|
72
85
|
// This was causing the traceProvider initilization with multiple instances.
|
|
73
86
|
// this._sdk.start();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const api_1 = require("@opentelemetry/api");
|
|
7
|
+
const wrapper_1 = __importDefault(require("../anthropic/wrapper"));
|
|
8
|
+
const config_1 = __importDefault(require("../../config"));
|
|
9
|
+
const helpers_1 = __importDefault(require("../../helpers"));
|
|
10
|
+
const base_wrapper_1 = __importDefault(require("../base-wrapper"));
|
|
11
|
+
const semantic_convention_1 = __importDefault(require("../../semantic-convention"));
|
|
12
|
+
jest.mock('../../../src/config');
|
|
13
|
+
jest.mock('../../../src/helpers');
|
|
14
|
+
jest.mock('../../../src/instrumentation/base-wrapper');
|
|
15
|
+
const mockTracer = api_1.trace.getTracer('test-tracer');
|
|
16
|
+
describe('AnthropicWrapper', () => {
|
|
17
|
+
let span;
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
span = mockTracer.startSpan('test-span');
|
|
20
|
+
span.setAttribute = jest.fn();
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
span.end();
|
|
25
|
+
});
|
|
26
|
+
describe('_messageCreate', () => {
|
|
27
|
+
it('should call recordMetrics after span ends', async () => {
|
|
28
|
+
const mockArgs = [{ message: 'test message' }];
|
|
29
|
+
const mockResponse = { response_id: '123', meta: { billedUnits: { inputTokens: 10, outputTokens: 20 } } };
|
|
30
|
+
jest.spyOn(base_wrapper_1.default, 'recordMetrics').mockImplementation(() => { });
|
|
31
|
+
jest.spyOn(wrapper_1.default, '_messageCreateCommonSetter').mockImplementationOnce(async ({ genAIEndpoint, span }) => {
|
|
32
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_OPERATION, semantic_convention_1.default.GEN_AI_OPERATION_TYPE_CHAT);
|
|
33
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_RESPONSE_ID, '123');
|
|
34
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_REQUEST_MAX_TOKENS, 100);
|
|
35
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_REQUEST_TEMPERATURE, 0.7);
|
|
36
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_USAGE_INPUT_TOKENS, 10);
|
|
37
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_USAGE_OUTPUT_TOKENS, 20);
|
|
38
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_USAGE_TOTAL_TOKENS, 30);
|
|
39
|
+
span.setAttribute(semantic_convention_1.default.GEN_AI_RESPONSE_FINISH_REASON, 'stop');
|
|
40
|
+
return {
|
|
41
|
+
genAIEndpoint,
|
|
42
|
+
model: 'test-model',
|
|
43
|
+
user: 'test-user',
|
|
44
|
+
cost: 0.5,
|
|
45
|
+
aiSystem: 'anthropic',
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
await wrapper_1.default._messageCreate({
|
|
49
|
+
args: mockArgs,
|
|
50
|
+
genAIEndpoint: 'anthropic.endpoint',
|
|
51
|
+
response: mockResponse,
|
|
52
|
+
span,
|
|
53
|
+
});
|
|
54
|
+
expect(base_wrapper_1.default.recordMetrics).toHaveBeenCalledWith(span, {
|
|
55
|
+
model: 'test-model',
|
|
56
|
+
user: 'test-user',
|
|
57
|
+
cost: 0.5,
|
|
58
|
+
aiSystem: 'anthropic',
|
|
59
|
+
genAIEndpoint: 'anthropic.endpoint',
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('_messageCommonSetter', () => {
|
|
64
|
+
it('should set span attributes and return metric parameters', async () => {
|
|
65
|
+
const mockArgs = [{ message: 'test message', max_tokens: 100, temperature: 0.7 }];
|
|
66
|
+
const mockResult = {
|
|
67
|
+
id: '123',
|
|
68
|
+
usage: { input_tokens: 10, output_tokens: 20 },
|
|
69
|
+
model: 'claude-3-sonnet-20240229',
|
|
70
|
+
stop_reason: 'stop',
|
|
71
|
+
};
|
|
72
|
+
jest.spyOn(config_1.default, 'updatePricingJson').mockResolvedValue({});
|
|
73
|
+
jest.spyOn(helpers_1.default, 'getChatModelCost').mockReturnValue(0.5);
|
|
74
|
+
const setAttributeSpy = jest.spyOn(span, 'setAttribute');
|
|
75
|
+
await wrapper_1.default._messageCreateCommonSetter({
|
|
76
|
+
args: mockArgs,
|
|
77
|
+
genAIEndpoint: 'anthropic.endpoint',
|
|
78
|
+
result: mockResult,
|
|
79
|
+
span,
|
|
80
|
+
});
|
|
81
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_OPERATION, semantic_convention_1.default.GEN_AI_OPERATION_TYPE_CHAT);
|
|
82
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_RESPONSE_ID, '123');
|
|
83
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_REQUEST_MAX_TOKENS, 100);
|
|
84
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_REQUEST_TEMPERATURE, 0.7);
|
|
85
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_USAGE_INPUT_TOKENS, 10);
|
|
86
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_USAGE_OUTPUT_TOKENS, 20);
|
|
87
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_USAGE_TOTAL_TOKENS, 30);
|
|
88
|
+
expect(setAttributeSpy).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_RESPONSE_FINISH_REASON, 'stop');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=anthropic-wrapper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-wrapper.test.js","sourceRoot":"","sources":["../../../src/instrumentation/__tests__/anthropic-wrapper.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const resources_1 = require("@opentelemetry/resources");
|
|
7
|
+
const semantic_convention_1 = __importDefault(require("../../semantic-convention"));
|
|
8
|
+
const metrics_1 = __importDefault(require("../../otel/metrics"));
|
|
9
|
+
const base_wrapper_1 = __importDefault(require("../base-wrapper"));
|
|
10
|
+
const index_1 = __importDefault(require("../../index"));
|
|
11
|
+
describe('BaseWrapper.setBaseSpanAttributes', () => {
|
|
12
|
+
let span;
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
|
+
let addSpy;
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
|
+
let recordSpy;
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
index_1.default.init({
|
|
19
|
+
applicationName: 'TestApp',
|
|
20
|
+
environment: 'TestEnv',
|
|
21
|
+
otlpEndpoint: 'http://localhost:4318',
|
|
22
|
+
});
|
|
23
|
+
metrics_1.default.setup({ resource: (0, resources_1.defaultResource)(), otlpEndpoint: 'http://localhost:4318' }); // Ensure metrics are initialized with a valid endpoint
|
|
24
|
+
addSpy = jest.spyOn(metrics_1.default.genaiRequests, 'add').mockImplementation(() => { });
|
|
25
|
+
jest.spyOn(metrics_1.default.genaiPromptTokens, 'add').mockImplementation(() => { });
|
|
26
|
+
jest.spyOn(metrics_1.default.genaiCompletionTokens, 'add').mockImplementation(() => { });
|
|
27
|
+
jest.spyOn(metrics_1.default.genaiClientOperationDuration, 'record').mockImplementation(() => { });
|
|
28
|
+
jest.spyOn(metrics_1.default.genaiCost, 'record').mockImplementation(() => { });
|
|
29
|
+
span = {
|
|
30
|
+
setAttribute: jest.fn(),
|
|
31
|
+
setStatus: jest.fn(),
|
|
32
|
+
attributes: {
|
|
33
|
+
[semantic_convention_1.default.GEN_AI_USAGE_INPUT_TOKENS]: 10,
|
|
34
|
+
[semantic_convention_1.default.GEN_AI_USAGE_OUTPUT_TOKENS]: 20,
|
|
35
|
+
duration: 1.5,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(span, 'setAttributes', {
|
|
39
|
+
value: jest.fn(),
|
|
40
|
+
writable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
enumerable: true,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
jest.restoreAllMocks();
|
|
47
|
+
});
|
|
48
|
+
it('should increment all metrics and set span attributes', () => {
|
|
49
|
+
const baseAttributes = {
|
|
50
|
+
model: 'gpt-4',
|
|
51
|
+
user: 'user1',
|
|
52
|
+
cost: 0.99,
|
|
53
|
+
aiSystem: 'openai',
|
|
54
|
+
genAIEndpoint: 'endpoint',
|
|
55
|
+
};
|
|
56
|
+
// @ts-expect-error: test mock span needs attributes property for metrics extraction
|
|
57
|
+
base_wrapper_1.default.setBaseSpanAttributes(span, baseAttributes);
|
|
58
|
+
base_wrapper_1.default.recordMetrics(span, baseAttributes);
|
|
59
|
+
expect(span.setAttribute).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_REQUEST_USER, 'user1');
|
|
60
|
+
expect(span.setAttribute).toHaveBeenCalledWith(semantic_convention_1.default.GEN_AI_USAGE_COST, 0.99);
|
|
61
|
+
expect(span.setStatus).toHaveBeenCalled();
|
|
62
|
+
expect(metrics_1.default.genaiRequests.add).toHaveBeenCalledWith(1, expect.objectContaining({
|
|
63
|
+
[semantic_convention_1.default.GEN_AI_SYSTEM]: 'openai',
|
|
64
|
+
[semantic_convention_1.default.GEN_AI_REQUEST_USER]: 'user1',
|
|
65
|
+
[semantic_convention_1.default.GEN_AI_REQUEST_MODEL]: 'gpt-4',
|
|
66
|
+
}));
|
|
67
|
+
expect(metrics_1.default.genaiPromptTokens.add).toHaveBeenCalledWith(10, expect.any(Object));
|
|
68
|
+
expect(metrics_1.default.genaiCompletionTokens.add).toHaveBeenCalledWith(20, expect.any(Object));
|
|
69
|
+
expect(metrics_1.default.genaiClientOperationDuration.record).toHaveBeenCalledWith(1.5e-9, expect.any(Object));
|
|
70
|
+
expect(metrics_1.default.genaiCost.record).toHaveBeenCalledWith(0.99, expect.any(Object));
|
|
71
|
+
});
|
|
72
|
+
it('should handle missing tokens and duration gracefully', () => {
|
|
73
|
+
Object.defineProperty(span, 'attributes', {
|
|
74
|
+
value: {},
|
|
75
|
+
writable: true,
|
|
76
|
+
configurable: true,
|
|
77
|
+
enumerable: true,
|
|
78
|
+
});
|
|
79
|
+
const baseAttributes = {
|
|
80
|
+
genAIEndpoint: 'endpoint',
|
|
81
|
+
model: 'gpt-4',
|
|
82
|
+
user: 'user2',
|
|
83
|
+
cost: undefined,
|
|
84
|
+
aiSystem: 'openai',
|
|
85
|
+
};
|
|
86
|
+
base_wrapper_1.default.setBaseSpanAttributes(span, baseAttributes);
|
|
87
|
+
base_wrapper_1.default.recordMetrics(span, baseAttributes);
|
|
88
|
+
expect(metrics_1.default.genaiPromptTokens.add).not.toHaveBeenCalled();
|
|
89
|
+
expect(metrics_1.default.genaiCompletionTokens.add).not.toHaveBeenCalled();
|
|
90
|
+
expect(metrics_1.default.genaiClientOperationDuration.record).not.toHaveBeenCalled();
|
|
91
|
+
expect(metrics_1.default.genaiCost.record).not.toHaveBeenCalled();
|
|
92
|
+
});
|
|
93
|
+
describe('metrics logic for inputTokens, outputTokens, duration, cost', () => {
|
|
94
|
+
beforeEach(() => {
|
|
95
|
+
metrics_1.default.setup({ resource: (0, resources_1.defaultResource)(), otlpEndpoint: 'http://localhost:4318' });
|
|
96
|
+
jest.spyOn(metrics_1.default.genaiPromptTokens, 'add').mockImplementation(() => { });
|
|
97
|
+
jest.spyOn(metrics_1.default.genaiCompletionTokens, 'add').mockImplementation(() => { });
|
|
98
|
+
jest.spyOn(metrics_1.default.genaiClientOperationDuration, 'record').mockImplementation(() => { });
|
|
99
|
+
jest.spyOn(metrics_1.default.genaiCost, 'record').mockImplementation(() => { });
|
|
100
|
+
});
|
|
101
|
+
it('should not call metrics for NaN, undefined, or non-number values', () => {
|
|
102
|
+
const span = {
|
|
103
|
+
setAttribute: jest.fn(),
|
|
104
|
+
setStatus: jest.fn(),
|
|
105
|
+
setAttributes: jest.fn(),
|
|
106
|
+
attributes: {
|
|
107
|
+
[semantic_convention_1.default.GEN_AI_USAGE_INPUT_TOKENS]: NaN,
|
|
108
|
+
[semantic_convention_1.default.GEN_AI_USAGE_OUTPUT_TOKENS]: undefined,
|
|
109
|
+
duration: 'not-a-number',
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const baseAttributes = {
|
|
113
|
+
model: 'gpt-4',
|
|
114
|
+
user: 'user1',
|
|
115
|
+
cost: 'not-a-number',
|
|
116
|
+
aiSystem: 'openai',
|
|
117
|
+
genAIEndpoint: 'endpoint',
|
|
118
|
+
};
|
|
119
|
+
base_wrapper_1.default.setBaseSpanAttributes(span, baseAttributes);
|
|
120
|
+
base_wrapper_1.default.recordMetrics(span, baseAttributes);
|
|
121
|
+
expect(metrics_1.default.genaiPromptTokens.add).not.toHaveBeenCalled();
|
|
122
|
+
expect(metrics_1.default.genaiCompletionTokens.add).not.toHaveBeenCalled();
|
|
123
|
+
expect(metrics_1.default.genaiClientOperationDuration.record).not.toHaveBeenCalled();
|
|
124
|
+
expect(metrics_1.default.genaiCost.record).not.toHaveBeenCalled();
|
|
125
|
+
});
|
|
126
|
+
it('should call metrics for zero and negative values', () => {
|
|
127
|
+
const span = {
|
|
128
|
+
setAttribute: jest.fn(),
|
|
129
|
+
setStatus: jest.fn(),
|
|
130
|
+
setAttributes: jest.fn(),
|
|
131
|
+
attributes: {
|
|
132
|
+
[semantic_convention_1.default.GEN_AI_USAGE_INPUT_TOKENS]: 0,
|
|
133
|
+
[semantic_convention_1.default.GEN_AI_USAGE_OUTPUT_TOKENS]: -5,
|
|
134
|
+
duration: -1.5,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
const baseAttributes = {
|
|
138
|
+
model: 'gpt-4',
|
|
139
|
+
user: 'user1',
|
|
140
|
+
cost: 0,
|
|
141
|
+
aiSystem: 'openai',
|
|
142
|
+
genAIEndpoint: 'endpoint',
|
|
143
|
+
};
|
|
144
|
+
base_wrapper_1.default.setBaseSpanAttributes(span, baseAttributes);
|
|
145
|
+
base_wrapper_1.default.recordMetrics(span, baseAttributes);
|
|
146
|
+
expect(metrics_1.default.genaiPromptTokens.add).toHaveBeenCalledWith(0, expect.any(Object));
|
|
147
|
+
expect(metrics_1.default.genaiCompletionTokens.add).toHaveBeenCalledWith(-5, expect.any(Object));
|
|
148
|
+
expect(metrics_1.default.genaiClientOperationDuration.record).toHaveBeenCalledWith(-1.5e-9, expect.any(Object));
|
|
149
|
+
expect(metrics_1.default.genaiCost.record).toHaveBeenCalledWith(0, expect.any(Object));
|
|
150
|
+
});
|
|
151
|
+
it('should convert string cost to number if possible', () => {
|
|
152
|
+
const span = {
|
|
153
|
+
setAttribute: jest.fn(),
|
|
154
|
+
setStatus: jest.fn(),
|
|
155
|
+
setAttributes: jest.fn(),
|
|
156
|
+
attributes: {
|
|
157
|
+
[semantic_convention_1.default.GEN_AI_USAGE_INPUT_TOKENS]: 1,
|
|
158
|
+
[semantic_convention_1.default.GEN_AI_USAGE_OUTPUT_TOKENS]: 2,
|
|
159
|
+
duration: 3,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
const baseAttributes = {
|
|
163
|
+
model: 'gpt-4',
|
|
164
|
+
user: 'user1',
|
|
165
|
+
cost: '1.23',
|
|
166
|
+
aiSystem: 'openai',
|
|
167
|
+
genAIEndpoint: 'endpoint',
|
|
168
|
+
};
|
|
169
|
+
base_wrapper_1.default.setBaseSpanAttributes(span, baseAttributes);
|
|
170
|
+
base_wrapper_1.default.recordMetrics(span, baseAttributes);
|
|
171
|
+
expect(metrics_1.default.genaiCost.record).toHaveBeenCalledWith(1.23, expect.any(Object));
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
//# sourceMappingURL=base-wrapper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-wrapper.test.js","sourceRoot":"","sources":["../../../src/instrumentation/__tests__/base-wrapper.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const api_1 = require("@opentelemetry/api");
|
|
7
|
+
const wrapper_1 = __importDefault(require("../cohere/wrapper"));
|
|
8
|
+
const config_1 = __importDefault(require("../../config"));
|
|
9
|
+
const helpers_1 = __importDefault(require("../../helpers"));
|
|
10
|
+
const base_wrapper_1 = __importDefault(require("../base-wrapper"));
|
|
11
|
+
jest.mock('../../../src/config');
|
|
12
|
+
jest.mock('../../../src/helpers');
|
|
13
|
+
jest.mock('../../../src/instrumentation/base-wrapper');
|
|
14
|
+
const mockTracer = api_1.trace.getTracer('test-tracer');
|
|
15
|
+
describe('CohereWrapper', () => {
|
|
16
|
+
let span;
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
span = mockTracer.startSpan('test-span');
|
|
19
|
+
span.setAttribute = jest.fn();
|
|
20
|
+
jest.clearAllMocks();
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
span.end();
|
|
24
|
+
});
|
|
25
|
+
describe('_chat', () => {
|
|
26
|
+
it('should call recordMetrics after span ends', async () => {
|
|
27
|
+
const mockArgs = [{ message: 'test message' }];
|
|
28
|
+
const mockResponse = { response_id: '123', meta: { billedUnits: { inputTokens: 10, outputTokens: 20 } } };
|
|
29
|
+
const mockGenAIEndpoint = 'cohere.endpoint';
|
|
30
|
+
jest.spyOn(wrapper_1.default, '_chatCommonSetter').mockResolvedValue({
|
|
31
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
32
|
+
model: 'test-model',
|
|
33
|
+
user: 'test-user',
|
|
34
|
+
cost: 0.5,
|
|
35
|
+
aiSystem: 'cohere',
|
|
36
|
+
});
|
|
37
|
+
await wrapper_1.default._chat({
|
|
38
|
+
args: mockArgs,
|
|
39
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
40
|
+
response: mockResponse,
|
|
41
|
+
span,
|
|
42
|
+
});
|
|
43
|
+
expect(base_wrapper_1.default.recordMetrics).toHaveBeenCalledWith(span, {
|
|
44
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
45
|
+
model: 'test-model',
|
|
46
|
+
user: 'test-user',
|
|
47
|
+
cost: 0.5,
|
|
48
|
+
aiSystem: 'cohere',
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe('_chatGenerator', () => {
|
|
53
|
+
it('should call recordMetrics after span ends in generator', async () => {
|
|
54
|
+
const mockArgs = [{ message: 'test message' }];
|
|
55
|
+
const mockResponse = async function* () {
|
|
56
|
+
yield { eventType: 'stream', response: { response_id: '123' } };
|
|
57
|
+
yield { eventType: 'stream-end', response: { response_id: '123', meta: { billedUnits: { inputTokens: 10, outputTokens: 20 } } } };
|
|
58
|
+
}();
|
|
59
|
+
const mockGenAIEndpoint = 'cohere.endpoint';
|
|
60
|
+
jest.spyOn(wrapper_1.default, '_chatCommonSetter').mockResolvedValue({
|
|
61
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
62
|
+
model: 'test-model',
|
|
63
|
+
user: 'test-user',
|
|
64
|
+
cost: 0.5,
|
|
65
|
+
aiSystem: 'cohere',
|
|
66
|
+
});
|
|
67
|
+
const generator = wrapper_1.default._chatGenerator({
|
|
68
|
+
args: mockArgs,
|
|
69
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
70
|
+
response: mockResponse,
|
|
71
|
+
span,
|
|
72
|
+
});
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
74
|
+
for await (const _ of generator) {
|
|
75
|
+
// Consume generator without using the value
|
|
76
|
+
}
|
|
77
|
+
expect(base_wrapper_1.default.recordMetrics).toHaveBeenCalledWith(span, {
|
|
78
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
79
|
+
model: 'test-model',
|
|
80
|
+
user: 'test-user',
|
|
81
|
+
cost: 0.5,
|
|
82
|
+
aiSystem: 'cohere',
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe('_chatCommonSetter', () => {
|
|
87
|
+
it('should set span attributes and return metric parameters', async () => {
|
|
88
|
+
const mockArgs = [{ message: 'test message', max_tokens: 100, temperature: 0.7 }];
|
|
89
|
+
const mockResult = {
|
|
90
|
+
response_id: '123',
|
|
91
|
+
meta: { billedUnits: { inputTokens: 10, outputTokens: 20 } },
|
|
92
|
+
text: 'response text',
|
|
93
|
+
finishReason: 'stop',
|
|
94
|
+
};
|
|
95
|
+
const mockGenAIEndpoint = 'cohere.endpoint';
|
|
96
|
+
jest.spyOn(config_1.default, 'updatePricingJson').mockResolvedValue({});
|
|
97
|
+
jest.spyOn(helpers_1.default, 'getChatModelCost').mockReturnValue(0.5);
|
|
98
|
+
const metricParams = await wrapper_1.default._chatCommonSetter({
|
|
99
|
+
args: mockArgs,
|
|
100
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
101
|
+
result: mockResult,
|
|
102
|
+
span,
|
|
103
|
+
stream: false,
|
|
104
|
+
});
|
|
105
|
+
expect(metricParams).toEqual({
|
|
106
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
107
|
+
model: 'test-model',
|
|
108
|
+
user: "test-user",
|
|
109
|
+
cost: 0.5,
|
|
110
|
+
aiSystem: 'cohere',
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('_chatCommonSetter error handling', () => {
|
|
114
|
+
it('should not call recordMetrics and handle the error properly', async () => {
|
|
115
|
+
const mockArgs = [{ message: 'test message', max_tokens: 100, temperature: 0.7 }];
|
|
116
|
+
const mockGenAIEndpoint = 'cohere.endpoint';
|
|
117
|
+
const mockError = new Error('Test error');
|
|
118
|
+
jest.spyOn(wrapper_1.default, '_chatCommonSetter').mockRejectedValue(mockError);
|
|
119
|
+
await expect(wrapper_1.default._chatCommonSetter({
|
|
120
|
+
args: mockArgs,
|
|
121
|
+
genAIEndpoint: mockGenAIEndpoint,
|
|
122
|
+
result: {},
|
|
123
|
+
span,
|
|
124
|
+
stream: false,
|
|
125
|
+
})).rejects.toThrow('Test error');
|
|
126
|
+
expect(base_wrapper_1.default.recordMetrics).not.toHaveBeenCalled();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=cohere-wrapper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohere-wrapper.test.js","sourceRoot":"","sources":["../../../src/instrumentation/__tests__/cohere-wrapper.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|