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.
Files changed (50) hide show
  1. package/README.md +19 -1
  2. package/dist/helpers.js +8 -4
  3. package/dist/helpers.js.map +1 -1
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +19 -6
  6. package/dist/index.js.map +1 -1
  7. package/dist/instrumentation/__tests__/anthropic-wrapper.test.d.ts +1 -0
  8. package/dist/instrumentation/__tests__/anthropic-wrapper.test.js +92 -0
  9. package/dist/instrumentation/__tests__/anthropic-wrapper.test.js.map +1 -0
  10. package/dist/instrumentation/__tests__/base-wrapper.test.d.ts +1 -0
  11. package/dist/instrumentation/__tests__/base-wrapper.test.js +175 -0
  12. package/dist/instrumentation/__tests__/base-wrapper.test.js.map +1 -0
  13. package/dist/instrumentation/__tests__/cohere-wrapper.test.d.ts +1 -0
  14. package/dist/instrumentation/__tests__/cohere-wrapper.test.js +131 -0
  15. package/dist/instrumentation/__tests__/cohere-wrapper.test.js.map +1 -0
  16. package/dist/instrumentation/__tests__/openai-wrapper.test.d.ts +1 -0
  17. package/dist/instrumentation/__tests__/openai-wrapper.test.js +181 -0
  18. package/dist/instrumentation/__tests__/openai-wrapper.test.js.map +1 -0
  19. package/dist/instrumentation/anthropic/wrapper.d.ts +7 -1
  20. package/dist/instrumentation/anthropic/wrapper.js +16 -1
  21. package/dist/instrumentation/anthropic/wrapper.js.map +1 -1
  22. package/dist/instrumentation/base-wrapper.d.ts +3 -2
  23. package/dist/instrumentation/base-wrapper.js +81 -1
  24. package/dist/instrumentation/base-wrapper.js.map +1 -1
  25. package/dist/instrumentation/cohere/wrapper.d.ts +7 -1
  26. package/dist/instrumentation/cohere/wrapper.js +19 -2
  27. package/dist/instrumentation/cohere/wrapper.js.map +1 -1
  28. package/dist/instrumentation/ollama/wrapper.d.ts +2 -1
  29. package/dist/instrumentation/ollama/wrapper.js +2 -2
  30. package/dist/instrumentation/ollama/wrapper.js.map +1 -1
  31. package/dist/instrumentation/openai/index.js +11 -0
  32. package/dist/instrumentation/openai/index.js.map +1 -1
  33. package/dist/instrumentation/openai/wrapper.d.ts +39 -3
  34. package/dist/instrumentation/openai/wrapper.js +537 -26
  35. package/dist/instrumentation/openai/wrapper.js.map +1 -1
  36. package/dist/otel/__tests__/metrics.test.d.ts +1 -0
  37. package/dist/otel/__tests__/metrics.test.js +51 -0
  38. package/dist/otel/__tests__/metrics.test.js.map +1 -0
  39. package/dist/otel/metrics.d.ts +22 -0
  40. package/dist/otel/metrics.js +132 -0
  41. package/dist/otel/metrics.js.map +1 -0
  42. package/dist/{tracing.d.ts → otel/tracing.d.ts} +1 -1
  43. package/dist/{tracing.js → otel/tracing.js} +17 -15
  44. package/dist/otel/tracing.js.map +1 -0
  45. package/dist/semantic-convention.d.ts +36 -0
  46. package/dist/semantic-convention.js +53 -11
  47. package/dist/semantic-convention.js.map +1 -1
  48. package/dist/types.d.ts +7 -0
  49. package/package.json +10 -11
  50. 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/connections/intro) to start using a pre-built dashboard we have created for these tools.
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
  ![](https://github.com/openlit/.github/blob/main/profile/assets/openlit-client-1.png?raw=true)
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
- return ((promptTokens / OpenLitHelper.PROMPT_TOKEN_FACTOR) * pricingInfo.chat[model].promptPrice +
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
- return (promptTokens / OpenLitHelper.PROMPT_TOKEN_FACTOR) * pricingInfo.embeddings[model];
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
- return pricingInfo.images[model][quality][size];
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
- return (prompt.length / OpenLitHelper.PROMPT_TOKEN_FACTOR) * pricingInfo.audio[model];
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}`);
@@ -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,OAAO,CACL,CAAC,YAAY,GAAG,aAAa,CAAC,mBAAmB,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW;gBACxF,CAAC,gBAAgB,GAAG,aAAa,CAAC,mBAAmB,CAAC;oBACpD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe,CAC1C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,KAAK,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,KAAa,EAAE,WAAgB,EAAE,YAAoB;QAC5E,IAAI,CAAC;YACH,OAAO,CAAC,YAAY,GAAG,aAAa,CAAC,mBAAmB,CAAC,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,KAAa,EAAE,WAAgB,EAAE,IAAY,EAAE,OAAe;QACrF,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,KAAa,EAAE,WAAgB,EAAE,MAAc;QACtE,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC,mBAAmB,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,WAAgB;QAC5C,IAAI,UAAU,GAAG,4EAA4E,CAAC;QAC9F,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC;gBACH,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,GAAG,KAAK,CAAC;YAChB,CAAC;YAED,IAAI,KAAK,EAAE,CAAC;gBACV,UAAU,GAAG,WAAW,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;wBACpC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;wBACrC,OAAO,IAAI,CAAC;oBACd,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;wBACrD,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;YACzC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,oDAAoD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0DAA0D,KAAK,EAAE,CAAC,CAAC;YACjF,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,IAAU,EAAE,KAAY;QAC7C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,oBAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAE,MAAW,EAAE,qBAA0B;QACrE,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;YACvB,GAAG,CAAE,MAAM,EAAE,IAAI,EAAE,QAAQ;gBACzB,IAAI,IAAI,KAAK,MAAM,CAAC,aAAa,EAAE,CAAC;oBAClC,OAAO,GAAG,EAAE,CAAC,qBAAqB,CAAA;gBACpC,CAAC;gBACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YAC5C,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;;AApHe,iCAAmB,GAAG,IAAI,CAAC;kBADxB,aAAa"}
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 { Resource } from '@opentelemetry/resources';
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: 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 || undefined;
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 = new resources_1.Resource({
56
- [semantic_conventions_1.SEMRESATTRS_SERVICE_NAME]: applicationName,
57
- [semantic_conventions_1.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment,
58
- [semantic_conventions_1.SEMRESATTRS_TELEMETRY_SDK_NAME]: constant_1.SDK_NAME,
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":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -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,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,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":";;;;;AAAA,4CAAiD;AACjD,gEAA8C;AAC9C,0DAAyC;AACzC,4DAA0C;AAC1C,mEAA0C;AAE1C,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AACjC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAClC,IAAI,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;AAEvD,MAAM,UAAU,GAAG,WAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;AAElD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,IAAU,CAAC;IAEf,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,GAAG,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;YAC/C,MAAM,YAAY,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;YAC1G,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;YAE5C,IAAI,CAAC,KAAK,CAAC,iBAAa,EAAE,mBAAmB,CAAC,CAAC,iBAAiB,CAAC;gBAC/D,aAAa,EAAE,iBAAiB;gBAChC,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YAEH,MAAM,iBAAa,CAAC,KAAK,CAAC;gBACxB,IAAI,EAAE,QAAQ;gBACd,aAAa,EAAE,iBAAiB;gBAChC,QAAQ,EAAE,YAAY;gBACtB,IAAI;aACL,CAAC,CAAC;YAEH,MAAM,CAAC,sBAAW,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE;gBAC3D,aAAa,EAAE,iBAAiB;gBAChC,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;YAC/C,MAAM,YAAY,GAAG,KAAK,SAAS,CAAC;gBAClC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC;gBAChE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;YACpI,CAAC,EAAE,CAAC;YACJ,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;YAE5C,IAAI,CAAC,KAAK,CAAC,iBAAa,EAAE,mBAAmB,CAAC,CAAC,iBAAiB,CAAC;gBAC/D,aAAa,EAAE,iBAAiB;gBAChC,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,iBAAa,CAAC,cAAc,CAAC;gBAC7C,IAAI,EAAE,QAAQ;gBACd,aAAa,EAAE,iBAAiB;gBAChC,QAAQ,EAAE,YAAY;gBACtB,IAAI;aACL,CAAC,CAAC;YACH,6DAA6D;YAC7D,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAChC,4CAA4C;YAC9C,CAAC;YAED,MAAM,CAAC,sBAAW,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE;gBAC3D,aAAa,EAAE,iBAAiB;gBAChC,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YAClF,MAAM,UAAU,GAAG;gBACjB,WAAW,EAAE,KAAK;gBAClB,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE;gBAC5D,IAAI,EAAE,eAAe;gBACrB,YAAY,EAAE,MAAM;aACrB,CAAC;YACF,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;YAE5C,IAAI,CAAC,KAAK,CAAC,gBAAa,EAAE,mBAAmB,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;YACrE,IAAI,CAAC,KAAK,CAAC,iBAAa,EAAE,kBAAkB,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAEnE,MAAM,YAAY,GAAG,MAAM,iBAAa,CAAC,iBAAiB,CAAC;gBACzD,IAAI,EAAE,QAAQ;gBACd,aAAa,EAAE,iBAAiB;gBAChC,MAAM,EAAE,UAAU;gBAClB,IAAI;gBACJ,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;YAEH,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;gBAC3B,aAAa,EAAE,iBAAiB;gBAChC,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAChD,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;gBAC3E,MAAM,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;gBAClF,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;gBAC5C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;gBAE1C,IAAI,CAAC,KAAK,CAAC,iBAAa,EAAE,mBAAmB,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAE5E,MAAM,MAAM,CACV,iBAAa,CAAC,iBAAiB,CAAC;oBAC9B,IAAI,EAAE,QAAQ;oBACd,aAAa,EAAE,iBAAiB;oBAChC,MAAM,EAAE,EAAE;oBACV,IAAI;oBACJ,MAAM,EAAE,KAAK;iBACd,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBAEhC,MAAM,CAAC,sBAAW,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAC3D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}