weflayr 0.24.0 → 0.26.0
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 +2 -2
- package/dist/{api → src/api}/generated/facade.gen.d.ts +86 -12
- package/dist/{api → src/api}/generated/facade.gen.js +4 -2
- package/dist/src/api/generated/index.d.ts +2 -0
- package/dist/{api → src/api}/generated/index.js +3 -1
- package/dist/{api → src/api}/generated/sdk.gen.d.ts +11 -3
- package/dist/{api → src/api}/generated/sdk.gen.js +34 -4
- package/{src/api/generated/types.gen.ts → dist/src/api/generated/types.gen.d.ts} +436 -153
- package/dist/{api → src/api}/makeEndpoint.js +1 -3
- package/dist/src/auto-instrument.d.ts +42 -0
- package/dist/src/auto-instrument.js +156 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +49 -0
- package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.d.ts +20 -0
- package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +114 -0
- package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.d.ts +28 -0
- package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.js +92 -0
- package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.d.ts +25 -0
- package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.js +141 -0
- package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.d.ts +9 -0
- package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.js +17 -0
- package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.d.ts +15 -0
- package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +50 -0
- package/dist/src/instrumentation/anthropic/set_telemetry_attributes.d.ts +15 -0
- package/dist/src/instrumentation/anthropic/set_telemetry_attributes.js +39 -0
- package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.d.ts +22 -0
- package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.js +97 -0
- package/dist/src/instrumentation/bedrock/get_cache_telemetry.d.ts +22 -0
- package/dist/src/instrumentation/bedrock/get_cache_telemetry.js +102 -0
- package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.d.ts +15 -0
- package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.js +91 -0
- package/dist/src/instrumentation/bedrock/get_model_id_telemetry.d.ts +21 -0
- package/dist/src/instrumentation/bedrock/get_model_id_telemetry.js +54 -0
- package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.d.ts +19 -0
- package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.js +81 -0
- package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.d.ts +27 -0
- package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +126 -0
- package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.d.ts +17 -0
- package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.js +85 -0
- package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.d.ts +15 -0
- package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.js +68 -0
- package/dist/src/instrumentation/bedrock/set_telemetry_attributes.d.ts +18 -0
- package/dist/src/instrumentation/bedrock/set_telemetry_attributes.js +47 -0
- package/dist/src/instrumentation/cohere/get_chat_telemetry.d.ts +23 -0
- package/dist/src/instrumentation/cohere/get_chat_telemetry.js +77 -0
- package/dist/src/instrumentation/cohere/get_embeddings_telemetry.d.ts +18 -0
- package/dist/src/instrumentation/cohere/get_embeddings_telemetry.js +88 -0
- package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.js +18 -0
- package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.d.ts +31 -0
- package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.js +106 -0
- package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.d.ts +27 -0
- package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.js +75 -0
- package/dist/src/instrumentation/cohere/set_telemetry_attributes.d.ts +17 -0
- package/dist/src/instrumentation/cohere/set_telemetry_attributes.js +44 -0
- package/dist/src/instrumentation/elevenlabs/full_instrumentation.d.ts +28 -0
- package/dist/src/instrumentation/elevenlabs/full_instrumentation.js +209 -0
- package/dist/src/instrumentation/google/get_audio_telemetry.d.ts +9 -0
- package/dist/src/instrumentation/google/get_audio_telemetry.js +28 -0
- package/dist/src/instrumentation/google/get_cache_operations_telemetry.d.ts +23 -0
- package/dist/src/instrumentation/google/get_cache_operations_telemetry.js +154 -0
- package/dist/src/instrumentation/google/get_cache_telemetry.d.ts +16 -0
- package/{src → dist/src}/instrumentation/google/get_cache_telemetry.js +18 -19
- package/dist/src/instrumentation/google/get_embeddings_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/google/get_embeddings_telemetry.js +85 -0
- package/dist/src/instrumentation/google/get_provider_name.d.ts +11 -0
- package/{src → dist/src}/instrumentation/google/get_provider_name.js +11 -12
- package/{src/instrumentation/google/get_reasoning_telemetry.js → dist/src/instrumentation/google/get_reasoning_telemetry.d.ts} +1 -11
- package/dist/src/instrumentation/google/get_reasoning_telemetry.js +21 -0
- package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.js +19 -0
- package/dist/src/instrumentation/google/set_telemetry_attributes.d.ts +18 -0
- package/dist/src/instrumentation/google/set_telemetry_attributes.js +98 -0
- package/dist/src/instrumentation/openai/get_audio_telemetry.d.ts +25 -0
- package/dist/src/instrumentation/openai/get_audio_telemetry.js +123 -0
- package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.d.ts +35 -0
- package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.js +148 -0
- package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.d.ts +27 -0
- package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +72 -0
- package/dist/src/instrumentation/openai/get_cache_config_telemetry.d.ts +28 -0
- package/dist/src/instrumentation/openai/get_cache_config_telemetry.js +91 -0
- package/dist/src/instrumentation/openai/get_embeddings_telemetry.d.ts +18 -0
- package/dist/src/instrumentation/openai/get_embeddings_telemetry.js +86 -0
- package/dist/src/instrumentation/openai/get_streaming_usage.d.ts +21 -0
- package/dist/src/instrumentation/openai/get_streaming_usage.js +74 -0
- package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.js +20 -0
- package/dist/src/instrumentation/openai/set_telemetry_attributes.d.ts +17 -0
- package/dist/src/instrumentation/openai/set_telemetry_attributes.js +47 -0
- package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.d.ts +35 -0
- package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.js +76 -0
- package/dist/src/instrumentation/vercel/full_instrumentation.d.ts +3 -0
- package/dist/src/instrumentation/vercel/full_instrumentation.js +54 -0
- package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.d.ts +22 -0
- package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.js +66 -0
- package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.d.ts +24 -0
- package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.js +84 -0
- package/dist/src/logger.d.ts +1 -0
- package/dist/src/logger.js +6 -0
- package/dist/src/otel/exporter.d.ts +19 -0
- package/dist/src/otel/exporter.js +94 -0
- package/dist/src/otel/propagation.d.ts +46 -0
- package/dist/src/otel/propagation.js +110 -0
- package/dist/src/otel/span-filter.d.ts +3 -0
- package/dist/src/otel/span-filter.js +61 -0
- package/dist/src/otel/span-processor.d.ts +55 -0
- package/dist/src/otel/span-processor.js +169 -0
- package/dist/src/otel/vercel-ai-sdk-span-filter.d.ts +12 -0
- package/dist/src/otel/vercel-ai-sdk-span-filter.js +88 -0
- package/dist/src/setup.d.ts +50 -0
- package/dist/src/setup.js +155 -0
- package/package.json +11 -5
- package/.prettierignore +0 -2
- package/.prettierrc.json +0 -7
- package/LICENSE-MIT +0 -21
- package/NOTICE +0 -12
- package/dist/api/generated/index.d.ts +0 -2
- package/dist/api/generated/types.gen.d.ts +0 -1005
- package/eslint.config.mjs +0 -36
- package/index.d.ts +0 -170
- package/openapi-ts.config.mjs +0 -9
- package/scripts/generate_facade.mjs +0 -86
- package/src/api/caseConversion.ts +0 -58
- package/src/api/generated/client/client.gen.ts +0 -277
- package/src/api/generated/client/index.ts +0 -27
- package/src/api/generated/client/types.gen.ts +0 -218
- package/src/api/generated/client/utils.gen.ts +0 -316
- package/src/api/generated/client.gen.ts +0 -16
- package/src/api/generated/core/auth.gen.ts +0 -48
- package/src/api/generated/core/bodySerializer.gen.ts +0 -82
- package/src/api/generated/core/params.gen.ts +0 -178
- package/src/api/generated/core/pathSerializer.gen.ts +0 -171
- package/src/api/generated/core/queryKeySerializer.gen.ts +0 -117
- package/src/api/generated/core/serverSentEvents.gen.ts +0 -242
- package/src/api/generated/core/types.gen.ts +0 -110
- package/src/api/generated/core/utils.gen.ts +0 -140
- package/src/api/generated/facade.gen.ts +0 -104
- package/src/api/generated/index.ts +0 -4
- package/src/api/generated/sdk.gen.ts +0 -175
- package/src/api/index.ts +0 -45
- package/src/api/makeEndpoint.ts +0 -54
- package/src/auto-instrument.js +0 -172
- package/src/index.js +0 -19
- package/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +0 -118
- package/src/instrumentation/anthropic/get_cache_config_telemetry.js +0 -90
- package/src/instrumentation/anthropic/get_streaming_stop_reason_telemetry.js +0 -121
- package/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +0 -55
- package/src/instrumentation/anthropic/set_telemetry_attributes.js +0 -39
- package/src/instrumentation/bedrock/get_cache_config_telemetry.js +0 -106
- package/src/instrumentation/bedrock/get_cache_telemetry.js +0 -109
- package/src/instrumentation/bedrock/get_input_message_content_telemetry.js +0 -94
- package/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +0 -87
- package/src/instrumentation/bedrock/set_telemetry_attributes.js +0 -40
- package/src/instrumentation/cohere/get_chat_telemetry.js +0 -88
- package/src/instrumentation/cohere/get_embeddings_telemetry.js +0 -107
- package/src/instrumentation/cohere/set_telemetry_attributes.js +0 -32
- package/src/instrumentation/elevenlabs/full_instrumentation.js +0 -236
- package/src/instrumentation/google/get_audio_telemetry.js +0 -30
- package/src/instrumentation/google/get_cache_operations_telemetry.js +0 -171
- package/src/instrumentation/google/get_embeddings_telemetry.js +0 -99
- package/src/instrumentation/google/set_telemetry_attributes.js +0 -104
- package/src/instrumentation/openai/get_audio_telemetry.js +0 -149
- package/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +0 -71
- package/src/instrumentation/openai/get_cache_config_telemetry.js +0 -63
- package/src/instrumentation/openai/get_embeddings_telemetry.js +0 -107
- package/src/instrumentation/openai/get_streaming_usage.js +0 -81
- package/src/instrumentation/openai/set_telemetry_attributes.js +0 -41
- package/src/instrumentation/vercel/full_instrumentation.js +0 -52
- package/src/instrumentation/vercel/get_cache_creation_telemetry.js +0 -70
- package/src/logger.js +0 -8
- package/src/otel/exporter.js +0 -108
- package/src/otel/propagation.js +0 -146
- package/src/otel/span-filter.js +0 -69
- package/src/otel/span-processor.js +0 -170
- package/src/otel/vercel-ai-sdk-span-filter.js +0 -79
- package/src/setup.js +0 -167
- package/tests/api/index.test.js +0 -437
- package/tests/index.test.js +0 -884
- package/tests/instrumentation/anthropic/get_cache_and_reasoning_telemetry.test.js +0 -181
- package/tests/instrumentation/anthropic/get_cache_config_telemetry.test.js +0 -92
- package/tests/instrumentation/anthropic/get_streaming_stop_reason_telemetry.test.js +0 -117
- package/tests/instrumentation/anthropic/get_tool_definitions_telemetry.test.js +0 -97
- package/tests/instrumentation/bedrock/get_cache_config_telemetry.test.js +0 -107
- package/tests/instrumentation/bedrock/get_cache_telemetry.test.js +0 -118
- package/tests/instrumentation/bedrock/get_input_message_content_telemetry.test.js +0 -89
- package/tests/instrumentation/bedrock/get_streaming_output_message_telemetry.test.js +0 -87
- package/tests/instrumentation/cohere/get_chat_telemetry.test.js +0 -148
- package/tests/instrumentation/cohere/get_embeddings_telemetry.test.js +0 -132
- package/tests/instrumentation/elevenlabs/full_instrumentation.test.js +0 -258
- package/tests/instrumentation/google/get_cache_operations_telemetry.test.js +0 -130
- package/tests/instrumentation/google/get_embeddings_telemetry.test.js +0 -128
- package/tests/instrumentation/google/get_reasoning_telemetry.test.js +0 -41
- package/tests/instrumentation/google/set_telemetry_attributes.test.js +0 -219
- package/tests/instrumentation/openai/get_audio_telemetry.test.js +0 -170
- package/tests/instrumentation/openai/get_cache_and_reasoning_telemetry.test.js +0 -83
- package/tests/instrumentation/openai/get_cache_config_telemetry.test.js +0 -83
- package/tests/instrumentation/openai/get_embeddings_telemetry.test.js +0 -145
- package/tests/instrumentation/openai/get_streaming_usage.test.js +0 -105
- package/tests/instrumentation/vercel/full_instrumentation.test.js +0 -16
- package/tests/instrumentation/vercel/get_cache_creation_telemetry.test.js +0 -96
- package/tests/otel/vercel-ai-sdk-span-filter.test.js +0 -159
- package/tsconfig.json +0 -18
- /package/dist/{api → src/api}/caseConversion.d.ts +0 -0
- /package/dist/{api → src/api}/caseConversion.js +0 -0
- /package/dist/{api → src/api}/generated/client/client.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/client.gen.js +0 -0
- /package/dist/{api → src/api}/generated/client/index.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/index.js +0 -0
- /package/dist/{api → src/api}/generated/client/types.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/types.gen.js +0 -0
- /package/dist/{api → src/api}/generated/client/utils.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/utils.gen.js +0 -0
- /package/dist/{api → src/api}/generated/client.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/auth.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/auth.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/bodySerializer.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/bodySerializer.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/params.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/params.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/pathSerializer.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/pathSerializer.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/types.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/types.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/utils.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/utils.gen.js +0 -0
- /package/dist/{api → src/api}/generated/types.gen.js +0 -0
- /package/dist/{api → src/api}/index.d.ts +0 -0
- /package/dist/{api → src/api}/index.js +0 -0
- /package/dist/{api → src/api}/makeEndpoint.d.ts +0 -0
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Tests for the bundled ElevenLabs audio instrumentor.
|
|
4
|
-
//
|
|
5
|
-
// The real `@elevenlabs/elevenlabs-js` clients are stubbed with methods that
|
|
6
|
-
// mirror the SDK's shapes — the streaming TTS entrypoints (`convert` / `stream`)
|
|
7
|
-
// resolve to a ReadableStream, `streamWithTimestamps` to an async-iterable, and
|
|
8
|
-
// the unary `convertWithTimestamps` and Speech-to-Text `convert` to a response
|
|
9
|
-
// object — so the instrumentor can be exercised without network access or the
|
|
10
|
-
// dependency installed.
|
|
11
|
-
|
|
12
|
-
const test = require('node:test');
|
|
13
|
-
const assert = require('node:assert/strict');
|
|
14
|
-
const Module = require('node:module');
|
|
15
|
-
|
|
16
|
-
const { trace, SpanStatusCode } = require('@opentelemetry/api');
|
|
17
|
-
const {
|
|
18
|
-
BasicTracerProvider,
|
|
19
|
-
InMemorySpanExporter,
|
|
20
|
-
SimpleSpanProcessor,
|
|
21
|
-
} = require('@opentelemetry/sdk-trace-base');
|
|
22
|
-
|
|
23
|
-
const {
|
|
24
|
-
ElevenLabsInstrumentor,
|
|
25
|
-
} = require('../../../src/instrumentation/elevenlabs/full_instrumentation');
|
|
26
|
-
|
|
27
|
-
const TTS_CLIENT_MODULE = '@elevenlabs/elevenlabs-js/api/resources/textToSpeech/client/Client';
|
|
28
|
-
const STT_CLIENT_MODULE = '@elevenlabs/elevenlabs-js/api/resources/speechToText/client/Client';
|
|
29
|
-
|
|
30
|
-
// The instrumentor emits via the global tracer provider. node's test runner
|
|
31
|
-
// isolates each test file in its own process, so registering one provider +
|
|
32
|
-
// in-memory exporter for the whole file is safe.
|
|
33
|
-
const exporter = new InMemorySpanExporter();
|
|
34
|
-
trace.setGlobalTracerProvider(
|
|
35
|
-
new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] })
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
// The exact chunk objects the streaming stubs yield. Shared so the passthrough
|
|
39
|
-
// assertions can compare object identity — proof our proxies re-emit the user's
|
|
40
|
-
// chunks without copying or mutating them.
|
|
41
|
-
const TTS_BYTE_CHUNKS = [Buffer.from('a'), Buffer.from('b')];
|
|
42
|
-
const TTS_OBJECT_CHUNKS = [{ audioBase64: 'eA==' }, { audioBase64: 'YmI=' }];
|
|
43
|
-
|
|
44
|
-
function readableOf(chunks) {
|
|
45
|
-
let index = 0;
|
|
46
|
-
return new ReadableStream({
|
|
47
|
-
pull(controller) {
|
|
48
|
-
if (index < chunks.length) controller.enqueue(chunks[index++]);
|
|
49
|
-
else controller.close();
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function failingReadable(error) {
|
|
55
|
-
return new ReadableStream({
|
|
56
|
-
pull() {
|
|
57
|
-
throw error;
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function asyncIterableOf(chunks) {
|
|
63
|
-
return {
|
|
64
|
-
async *[Symbol.asyncIterator]() {
|
|
65
|
-
for (const chunk of chunks) yield chunk;
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
class StubTextToSpeechClient {
|
|
71
|
-
convert(_voiceId, request = {}) {
|
|
72
|
-
if (request.text === 'boom') return Promise.resolve(failingReadable(new Error('api error')));
|
|
73
|
-
return Promise.resolve(readableOf(TTS_BYTE_CHUNKS));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
stream(_voiceId, _request = {}) {
|
|
77
|
-
return Promise.resolve(readableOf([Buffer.from('x')]));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
streamWithTimestamps(_voiceId, _request = {}) {
|
|
81
|
-
return Promise.resolve(asyncIterableOf(TTS_OBJECT_CHUNKS));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
convertWithTimestamps(_voiceId, _request = {}) {
|
|
85
|
-
return Promise.resolve({ audioBase64: 'YQ==' });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
class StubSpeechToTextClient {
|
|
90
|
-
convert(request = {}) {
|
|
91
|
-
if (request.modelId === 'boom') return Promise.reject(new Error('api error'));
|
|
92
|
-
return Promise.resolve({ audioDurationSecs: 12.4, text: 'hello' });
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async function drain(stream) {
|
|
97
|
-
const reader = stream.getReader();
|
|
98
|
-
const chunks = [];
|
|
99
|
-
for (;;) {
|
|
100
|
-
const { done, value } = await reader.read();
|
|
101
|
-
if (done) break;
|
|
102
|
-
chunks.push(value);
|
|
103
|
-
}
|
|
104
|
-
return chunks;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function drainIterable(iterable) {
|
|
108
|
-
const chunks = [];
|
|
109
|
-
for await (const chunk of iterable) chunks.push(chunk);
|
|
110
|
-
return chunks;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Stub the elevenlabs client modules, install the instrumentor + the in-memory
|
|
114
|
-
// exporter, and return a teardown that restores everything.
|
|
115
|
-
function instrumented() {
|
|
116
|
-
const stubs = {
|
|
117
|
-
[TTS_CLIENT_MODULE]: { TextToSpeechClient: StubTextToSpeechClient },
|
|
118
|
-
[STT_CLIENT_MODULE]: { SpeechToTextClient: StubSpeechToTextClient },
|
|
119
|
-
};
|
|
120
|
-
const origResolve = Module._resolveFilename;
|
|
121
|
-
Module._resolveFilename = function patched(request, ...rest) {
|
|
122
|
-
if (request in stubs) return request;
|
|
123
|
-
return origResolve.call(this, request, ...rest);
|
|
124
|
-
};
|
|
125
|
-
for (const [moduleId, exports] of Object.entries(stubs)) {
|
|
126
|
-
require.cache[moduleId] = { id: moduleId, filename: moduleId, loaded: true, exports };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const instrumentor = new ElevenLabsInstrumentor();
|
|
130
|
-
instrumentor.instrument();
|
|
131
|
-
|
|
132
|
-
return () => {
|
|
133
|
-
instrumentor.uninstrument();
|
|
134
|
-
Module._resolveFilename = origResolve;
|
|
135
|
-
for (const moduleId of Object.keys(stubs)) delete require.cache[moduleId];
|
|
136
|
-
exporter.reset();
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
test('convert emits genai span with char count', async () => {
|
|
141
|
-
const teardown = instrumented();
|
|
142
|
-
try {
|
|
143
|
-
const client = new StubTextToSpeechClient();
|
|
144
|
-
const stream = await client.convert('voice', { text: 'hello world', modelId: 'eleven_v2' });
|
|
145
|
-
// Same count, order, and object identity: the byte-stream proxy re-emits each
|
|
146
|
-
// chunk by reference — no telemetry collision with the caller's audio.
|
|
147
|
-
const collected = await drain(stream);
|
|
148
|
-
assert.equal(collected.length, TTS_BYTE_CHUNKS.length);
|
|
149
|
-
collected.forEach((chunk, index) => assert.equal(chunk, TTS_BYTE_CHUNKS[index]));
|
|
150
|
-
|
|
151
|
-
const [span] = exporter.getFinishedSpans();
|
|
152
|
-
assert.equal(span.name, 'text_to_speech');
|
|
153
|
-
assert.equal(span.attributes['gen_ai.system'], 'elevenlabs');
|
|
154
|
-
assert.equal(span.attributes['gen_ai.operation.name'], 'text_to_speech');
|
|
155
|
-
assert.equal(span.attributes['gen_ai.request.model'], 'eleven_v2');
|
|
156
|
-
assert.equal(span.attributes['gen_ai.usage.input_characters'], 'hello world'.length);
|
|
157
|
-
assert.equal(span.status.code, SpanStatusCode.UNSET);
|
|
158
|
-
} finally {
|
|
159
|
-
teardown();
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test('convert records error status on failure', async () => {
|
|
164
|
-
const teardown = instrumented();
|
|
165
|
-
try {
|
|
166
|
-
const client = new StubTextToSpeechClient();
|
|
167
|
-
const stream = await client.convert('voice', { text: 'boom', modelId: 'm' });
|
|
168
|
-
await assert.rejects(() => drain(stream), /api error/);
|
|
169
|
-
|
|
170
|
-
const [span] = exporter.getFinishedSpans();
|
|
171
|
-
assert.equal(span.status.code, SpanStatusCode.ERROR);
|
|
172
|
-
} finally {
|
|
173
|
-
teardown();
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test('convert with timestamps emits span with char count', async () => {
|
|
178
|
-
const teardown = instrumented();
|
|
179
|
-
try {
|
|
180
|
-
const client = new StubTextToSpeechClient();
|
|
181
|
-
// The unary timestamp variant resolves to a single response, not a stream.
|
|
182
|
-
const result = await client.convertWithTimestamps('voice', { text: 'hello', modelId: 'm' });
|
|
183
|
-
assert.equal(result.audioBase64, 'YQ==');
|
|
184
|
-
|
|
185
|
-
const [span] = exporter.getFinishedSpans();
|
|
186
|
-
assert.equal(span.name, 'text_to_speech');
|
|
187
|
-
assert.equal(span.attributes['gen_ai.usage.input_characters'], 'hello'.length);
|
|
188
|
-
assert.equal(span.attributes['gen_ai.usage.input_seconds'], undefined);
|
|
189
|
-
} finally {
|
|
190
|
-
teardown();
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
test('stream with timestamps emits span with char count', async () => {
|
|
195
|
-
const teardown = instrumented();
|
|
196
|
-
try {
|
|
197
|
-
const client = new StubTextToSpeechClient();
|
|
198
|
-
const stream = await client.streamWithTimestamps('voice', { text: 'hello', modelId: 'm' });
|
|
199
|
-
// Same count, order, and object identity: the object-stream proxy re-yields
|
|
200
|
-
// each chunk by reference — no telemetry collision with the caller's payload.
|
|
201
|
-
const collected = await drainIterable(stream);
|
|
202
|
-
assert.equal(collected.length, TTS_OBJECT_CHUNKS.length);
|
|
203
|
-
collected.forEach((chunk, index) => assert.equal(chunk, TTS_OBJECT_CHUNKS[index]));
|
|
204
|
-
|
|
205
|
-
const [span] = exporter.getFinishedSpans();
|
|
206
|
-
assert.equal(span.name, 'text_to_speech');
|
|
207
|
-
assert.equal(span.attributes['gen_ai.usage.input_characters'], 'hello'.length);
|
|
208
|
-
} finally {
|
|
209
|
-
teardown();
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
test('uninstrument restores original methods', async () => {
|
|
214
|
-
const teardown = instrumented();
|
|
215
|
-
try {
|
|
216
|
-
const client = new StubTextToSpeechClient();
|
|
217
|
-
assert.deepEqual(await drain(await client.stream('voice', { text: 'x' })), [Buffer.from('x')]);
|
|
218
|
-
assert.equal(exporter.getFinishedSpans().length, 1);
|
|
219
|
-
} finally {
|
|
220
|
-
teardown();
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
test('speech to text emits span with audio duration', async () => {
|
|
225
|
-
const teardown = instrumented();
|
|
226
|
-
try {
|
|
227
|
-
const client = new StubSpeechToTextClient();
|
|
228
|
-
const result = await client.convert({ modelId: 'scribe_v1', file: Buffer.from('audio') });
|
|
229
|
-
assert.equal(result.audioDurationSecs, 12.4);
|
|
230
|
-
|
|
231
|
-
const [span] = exporter.getFinishedSpans();
|
|
232
|
-
assert.equal(span.name, 'speech_to_text');
|
|
233
|
-
assert.equal(span.attributes['gen_ai.system'], 'elevenlabs');
|
|
234
|
-
assert.equal(span.attributes['gen_ai.operation.name'], 'speech_to_text');
|
|
235
|
-
assert.equal(span.attributes['gen_ai.request.model'], 'scribe_v1');
|
|
236
|
-
assert.equal(span.attributes['gen_ai.usage.input_seconds'], 12.4);
|
|
237
|
-
assert.equal(span.attributes['gen_ai.usage.input_characters'], undefined);
|
|
238
|
-
assert.equal(span.status.code, SpanStatusCode.UNSET);
|
|
239
|
-
} finally {
|
|
240
|
-
teardown();
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
test('speech to text records error status on failure', async () => {
|
|
245
|
-
const teardown = instrumented();
|
|
246
|
-
try {
|
|
247
|
-
const client = new StubSpeechToTextClient();
|
|
248
|
-
await assert.rejects(
|
|
249
|
-
() => client.convert({ modelId: 'boom', file: Buffer.from('audio') }),
|
|
250
|
-
/api error/
|
|
251
|
-
);
|
|
252
|
-
|
|
253
|
-
const [span] = exporter.getFinishedSpans();
|
|
254
|
-
assert.equal(span.status.code, SpanStatusCode.ERROR);
|
|
255
|
-
} finally {
|
|
256
|
-
teardown();
|
|
257
|
-
}
|
|
258
|
-
});
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Tests for the Google GenAI explicit-cache lifecycle telemetry.
|
|
4
|
-
//
|
|
5
|
-
// The @google/genai `Caches` class is stubbed with prototype
|
|
6
|
-
// create/update/delete methods mirroring the SDK shape.
|
|
7
|
-
// `instrumentCacheOperations(Caches, patched)` wraps them and pushes the
|
|
8
|
-
// restore tuples onto `patched`.
|
|
9
|
-
|
|
10
|
-
const test = require('node:test');
|
|
11
|
-
const assert = require('node:assert/strict');
|
|
12
|
-
|
|
13
|
-
const { trace, SpanStatusCode } = require('@opentelemetry/api');
|
|
14
|
-
const {
|
|
15
|
-
BasicTracerProvider,
|
|
16
|
-
InMemorySpanExporter,
|
|
17
|
-
SimpleSpanProcessor,
|
|
18
|
-
} = require('@opentelemetry/sdk-trace-base');
|
|
19
|
-
|
|
20
|
-
const {
|
|
21
|
-
instrumentCacheOperations,
|
|
22
|
-
} = require('../../../src/instrumentation/google/get_cache_operations_telemetry');
|
|
23
|
-
|
|
24
|
-
const exporter = new InMemorySpanExporter();
|
|
25
|
-
trace.setGlobalTracerProvider(
|
|
26
|
-
new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] })
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
const CACHED_CONTENT = {
|
|
30
|
-
name: 'cachedContents/abc123',
|
|
31
|
-
expireTime: '2026-07-16T14:00:00Z',
|
|
32
|
-
usageMetadata: { totalTokenCount: 5300 },
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
class StubCaches {
|
|
36
|
-
create(params = {}) {
|
|
37
|
-
if (params.model === 'boom') return Promise.reject(new Error('api error'));
|
|
38
|
-
return Promise.resolve(CACHED_CONTENT);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
update() {
|
|
42
|
-
return Promise.resolve(CACHED_CONTENT);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
delete() {
|
|
46
|
-
return Promise.resolve({});
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function instrumented() {
|
|
51
|
-
const patched = [];
|
|
52
|
-
instrumentCacheOperations(StubCaches, patched);
|
|
53
|
-
return () => {
|
|
54
|
-
for (const [owner, methodName, original] of patched) owner[methodName] = original;
|
|
55
|
-
exporter.reset();
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
test('create span carries cache facts and content', async () => {
|
|
60
|
-
const teardown = instrumented();
|
|
61
|
-
try {
|
|
62
|
-
await new StubCaches().create({
|
|
63
|
-
model: 'models/gemini-2.5-flash',
|
|
64
|
-
config: {
|
|
65
|
-
contents: ['a very large document to cache'],
|
|
66
|
-
systemInstruction: 'Answer from the document.',
|
|
67
|
-
ttl: '3600s',
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const [span] = exporter.getFinishedSpans();
|
|
72
|
-
assert.equal(span.name, 'cache_create');
|
|
73
|
-
assert.equal(span.attributes['gen_ai.system'], 'gemini');
|
|
74
|
-
assert.equal(span.attributes['gen_ai.request.model'], 'gemini-2.5-flash');
|
|
75
|
-
assert.equal(span.attributes['weflayr.cache.operation'], 'create');
|
|
76
|
-
assert.equal(span.attributes['weflayr.cache.cached_content_id'], 'cachedContents/abc123');
|
|
77
|
-
assert.equal(span.attributes['weflayr.cache.expire_time'], '2026-07-16T14:00:00Z');
|
|
78
|
-
assert.equal(span.attributes['gen_ai.usage.input_tokens'], 5300);
|
|
79
|
-
assert.deepEqual(JSON.parse(span.attributes['gen_ai.input.messages']), [
|
|
80
|
-
{ role: 'user', parts: [{ type: 'text', content: 'a very large document to cache' }] },
|
|
81
|
-
]);
|
|
82
|
-
assert.deepEqual(JSON.parse(span.attributes['gen_ai.system_instructions']), [
|
|
83
|
-
{ type: 'text', content: 'Answer from the document.' },
|
|
84
|
-
]);
|
|
85
|
-
} finally {
|
|
86
|
-
teardown();
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test('update span carries the new expiry but no token count', async () => {
|
|
91
|
-
const teardown = instrumented();
|
|
92
|
-
try {
|
|
93
|
-
await new StubCaches().update({ name: 'cachedContents/abc123', config: { ttl: '180s' } });
|
|
94
|
-
|
|
95
|
-
const [span] = exporter.getFinishedSpans();
|
|
96
|
-
assert.equal(span.name, 'cache_update');
|
|
97
|
-
assert.equal(span.attributes['weflayr.cache.operation'], 'update');
|
|
98
|
-
assert.equal(span.attributes['weflayr.cache.expire_time'], '2026-07-16T14:00:00Z');
|
|
99
|
-
assert.ok(!('gen_ai.usage.input_tokens' in span.attributes));
|
|
100
|
-
} finally {
|
|
101
|
-
teardown();
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test('delete span carries operation and cache id', async () => {
|
|
106
|
-
const teardown = instrumented();
|
|
107
|
-
try {
|
|
108
|
-
await new StubCaches().delete({ name: 'cachedContents/abc123' });
|
|
109
|
-
|
|
110
|
-
const [span] = exporter.getFinishedSpans();
|
|
111
|
-
assert.equal(span.name, 'cache_delete');
|
|
112
|
-
assert.equal(span.attributes['weflayr.cache.operation'], 'delete');
|
|
113
|
-
assert.equal(span.attributes['weflayr.cache.cached_content_id'], 'cachedContents/abc123');
|
|
114
|
-
assert.ok(!('gen_ai.usage.input_tokens' in span.attributes));
|
|
115
|
-
} finally {
|
|
116
|
-
teardown();
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
test('error span records status', async () => {
|
|
121
|
-
const teardown = instrumented();
|
|
122
|
-
try {
|
|
123
|
-
await assert.rejects(new StubCaches().create({ model: 'boom' }));
|
|
124
|
-
|
|
125
|
-
const [span] = exporter.getFinishedSpans();
|
|
126
|
-
assert.equal(span.status.code, SpanStatusCode.ERROR);
|
|
127
|
-
} finally {
|
|
128
|
-
teardown();
|
|
129
|
-
}
|
|
130
|
-
});
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Tests for the bundled Google GenAI (Gemini) embeddings telemetry.
|
|
4
|
-
//
|
|
5
|
-
// The @google/genai `Models` class is stubbed with the prototype method
|
|
6
|
-
// `embedContentInternal` (the stable patch point that the public `embedContent`
|
|
7
|
-
// arrow delegates to). The Gemini Developer API returns no token usage, so the
|
|
8
|
-
// billable unit is the input character count. `instrumentEmbeddings(Models,
|
|
9
|
-
// patched)` wraps the method and pushes its restore tuple onto `patched`.
|
|
10
|
-
|
|
11
|
-
const test = require('node:test');
|
|
12
|
-
const assert = require('node:assert/strict');
|
|
13
|
-
|
|
14
|
-
const { trace, SpanStatusCode } = require('@opentelemetry/api');
|
|
15
|
-
const {
|
|
16
|
-
BasicTracerProvider,
|
|
17
|
-
InMemorySpanExporter,
|
|
18
|
-
SimpleSpanProcessor,
|
|
19
|
-
} = require('@opentelemetry/sdk-trace-base');
|
|
20
|
-
|
|
21
|
-
const {
|
|
22
|
-
instrumentEmbeddings,
|
|
23
|
-
} = require('../../../src/instrumentation/google/get_embeddings_telemetry');
|
|
24
|
-
|
|
25
|
-
const exporter = new InMemorySpanExporter();
|
|
26
|
-
trace.setGlobalTracerProvider(
|
|
27
|
-
new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] })
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
class StubModels {
|
|
31
|
-
embedContentInternal(params = {}) {
|
|
32
|
-
if (params.model === 'boom') return Promise.reject(new Error('api error'));
|
|
33
|
-
return Promise.resolve({ embeddings: [{ values: [0.1] }] });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function instrumented() {
|
|
38
|
-
const patched = [];
|
|
39
|
-
instrumentEmbeddings(StubModels, patched);
|
|
40
|
-
return () => {
|
|
41
|
-
for (const [owner, methodName, original] of patched) owner[methodName] = original;
|
|
42
|
-
exporter.reset();
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
test('embeddings emits genai span with character count and stripped model', async () => {
|
|
47
|
-
const teardown = instrumented();
|
|
48
|
-
try {
|
|
49
|
-
const client = new StubModels();
|
|
50
|
-
await client.embedContentInternal({
|
|
51
|
-
model: 'models/text-embedding-004',
|
|
52
|
-
contents: 'hello world',
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const [span] = exporter.getFinishedSpans();
|
|
56
|
-
assert.equal(span.name, 'embeddings');
|
|
57
|
-
// No apiClient on the stub → Gemini Developer API.
|
|
58
|
-
assert.equal(span.attributes['gen_ai.system'], 'gemini');
|
|
59
|
-
assert.equal(span.attributes['gen_ai.operation.name'], 'embeddings');
|
|
60
|
-
// The "models/" prefix is stripped to match the chat path.
|
|
61
|
-
assert.equal(span.attributes['gen_ai.request.model'], 'text-embedding-004');
|
|
62
|
-
assert.equal(span.attributes['gen_ai.usage.input_characters'], 'hello world'.length);
|
|
63
|
-
assert.deepEqual(JSON.parse(span.attributes['gen_ai.input.messages']), [
|
|
64
|
-
{ role: 'user', parts: [{ type: 'text', content: 'hello world' }] },
|
|
65
|
-
]);
|
|
66
|
-
assert.equal(span.status.code, SpanStatusCode.UNSET);
|
|
67
|
-
} finally {
|
|
68
|
-
teardown();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('embeddings counts characters across list/part contents', async () => {
|
|
73
|
-
const teardown = instrumented();
|
|
74
|
-
try {
|
|
75
|
-
const client = new StubModels();
|
|
76
|
-
await client.embedContentInternal({
|
|
77
|
-
model: 'text-embedding-004',
|
|
78
|
-
contents: ['ab', { text: 'cde' }, { parts: [{ text: 'fg' }] }],
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const [span] = exporter.getFinishedSpans();
|
|
82
|
-
assert.equal(span.attributes['gen_ai.usage.input_characters'], 7);
|
|
83
|
-
} finally {
|
|
84
|
-
teardown();
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test('embeddings system is vertex_ai when client targets vertex', async () => {
|
|
89
|
-
const teardown = instrumented();
|
|
90
|
-
try {
|
|
91
|
-
const client = new StubModels();
|
|
92
|
-
// The Vertex backend is read off the api client.
|
|
93
|
-
client.apiClient = { isVertexAI: () => true };
|
|
94
|
-
await client.embedContentInternal({ model: 'text-embedding-004', contents: 'hi' });
|
|
95
|
-
|
|
96
|
-
const [span] = exporter.getFinishedSpans();
|
|
97
|
-
assert.equal(span.attributes['gen_ai.system'], 'vertex_ai');
|
|
98
|
-
} finally {
|
|
99
|
-
teardown();
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test('embeddings records error status on failure', async () => {
|
|
104
|
-
const teardown = instrumented();
|
|
105
|
-
try {
|
|
106
|
-
const client = new StubModels();
|
|
107
|
-
await assert.rejects(
|
|
108
|
-
() => client.embedContentInternal({ model: 'boom', contents: 'x' }),
|
|
109
|
-
/api error/
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const [span] = exporter.getFinishedSpans();
|
|
113
|
-
assert.equal(span.status.code, SpanStatusCode.ERROR);
|
|
114
|
-
} finally {
|
|
115
|
-
teardown();
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test('uninstrument restores the original method', async () => {
|
|
120
|
-
const teardown = instrumented();
|
|
121
|
-
const client = new StubModels();
|
|
122
|
-
await client.embedContentInternal({ model: 'text-embedding-004', contents: 'x' });
|
|
123
|
-
assert.equal(exporter.getFinishedSpans().length, 1);
|
|
124
|
-
teardown();
|
|
125
|
-
// After teardown the prototype method is restored (no new span is recorded).
|
|
126
|
-
await client.embedContentInternal({ model: 'text-embedding-004', contents: 'y' });
|
|
127
|
-
assert.equal(exporter.getFinishedSpans().length, 0);
|
|
128
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Tests for the Gemini reasoning (thinking) token complement. It stamps
|
|
4
|
-
// usageMetadata.thoughtsTokenCount onto the chat span as
|
|
5
|
-
// gen_ai.usage.thoughts_token_count so the normalizer can fold the
|
|
6
|
-
// (separately-reported) thinking tokens into the completion count.
|
|
7
|
-
|
|
8
|
-
const test = require('node:test');
|
|
9
|
-
const assert = require('node:assert/strict');
|
|
10
|
-
|
|
11
|
-
const {
|
|
12
|
-
setReasoningTelemetry,
|
|
13
|
-
} = require('../../../src/instrumentation/google/get_reasoning_telemetry');
|
|
14
|
-
|
|
15
|
-
function fakeSpan() {
|
|
16
|
-
const attrs = {};
|
|
17
|
-
return {
|
|
18
|
-
attrs,
|
|
19
|
-
setAttribute(key, value) {
|
|
20
|
-
attrs[key] = value;
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
test('stamps thoughts token count', () => {
|
|
26
|
-
const span = fakeSpan();
|
|
27
|
-
setReasoningTelemetry(span, { usageMetadata: { thoughtsTokenCount: 369 } });
|
|
28
|
-
assert.equal(span.attrs['gen_ai.usage.thoughts_token_count'], 369);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('sets nothing when thoughts is zero', () => {
|
|
32
|
-
const span = fakeSpan();
|
|
33
|
-
setReasoningTelemetry(span, { usageMetadata: { thoughtsTokenCount: 0 } });
|
|
34
|
-
assert.equal(span.attrs['gen_ai.usage.thoughts_token_count'], undefined);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test('is a no-op without usageMetadata', () => {
|
|
38
|
-
const span = fakeSpan();
|
|
39
|
-
setReasoningTelemetry(span, {});
|
|
40
|
-
assert.equal(Object.keys(span.attrs).length, 0);
|
|
41
|
-
});
|