weflayr 0.24.0 → 0.26.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 (235) hide show
  1. package/README.md +2 -2
  2. package/dist/package.json +51 -0
  3. package/dist/{api → src/api}/generated/facade.gen.d.ts +86 -12
  4. package/dist/{api → src/api}/generated/facade.gen.js +4 -2
  5. package/dist/src/api/generated/index.d.ts +2 -0
  6. package/dist/{api → src/api}/generated/index.js +3 -1
  7. package/dist/{api → src/api}/generated/sdk.gen.d.ts +11 -3
  8. package/dist/{api → src/api}/generated/sdk.gen.js +34 -4
  9. package/{src/api/generated/types.gen.ts → dist/src/api/generated/types.gen.d.ts} +436 -153
  10. package/dist/{api → src/api}/makeEndpoint.js +1 -3
  11. package/dist/src/auto-instrument.d.ts +42 -0
  12. package/dist/src/auto-instrument.js +156 -0
  13. package/dist/src/index.d.ts +9 -0
  14. package/dist/src/index.js +49 -0
  15. package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.d.ts +20 -0
  16. package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +114 -0
  17. package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.d.ts +28 -0
  18. package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.js +92 -0
  19. package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.d.ts +25 -0
  20. package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.js +141 -0
  21. package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.d.ts +9 -0
  22. package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.js +17 -0
  23. package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.d.ts +15 -0
  24. package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +50 -0
  25. package/dist/src/instrumentation/anthropic/set_telemetry_attributes.d.ts +15 -0
  26. package/dist/src/instrumentation/anthropic/set_telemetry_attributes.js +39 -0
  27. package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.d.ts +22 -0
  28. package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.js +97 -0
  29. package/dist/src/instrumentation/bedrock/get_cache_telemetry.d.ts +22 -0
  30. package/dist/src/instrumentation/bedrock/get_cache_telemetry.js +102 -0
  31. package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.d.ts +15 -0
  32. package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.js +91 -0
  33. package/dist/src/instrumentation/bedrock/get_model_id_telemetry.d.ts +21 -0
  34. package/dist/src/instrumentation/bedrock/get_model_id_telemetry.js +54 -0
  35. package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.d.ts +19 -0
  36. package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.js +81 -0
  37. package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.d.ts +27 -0
  38. package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +126 -0
  39. package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.d.ts +17 -0
  40. package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.js +85 -0
  41. package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.d.ts +15 -0
  42. package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.js +68 -0
  43. package/dist/src/instrumentation/bedrock/set_telemetry_attributes.d.ts +18 -0
  44. package/dist/src/instrumentation/bedrock/set_telemetry_attributes.js +47 -0
  45. package/dist/src/instrumentation/cohere/get_chat_telemetry.d.ts +23 -0
  46. package/dist/src/instrumentation/cohere/get_chat_telemetry.js +77 -0
  47. package/dist/src/instrumentation/cohere/get_embeddings_telemetry.d.ts +18 -0
  48. package/dist/src/instrumentation/cohere/get_embeddings_telemetry.js +88 -0
  49. package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.d.ts +12 -0
  50. package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.js +18 -0
  51. package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.d.ts +31 -0
  52. package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.js +106 -0
  53. package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.d.ts +27 -0
  54. package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.js +75 -0
  55. package/dist/src/instrumentation/cohere/set_telemetry_attributes.d.ts +17 -0
  56. package/dist/src/instrumentation/cohere/set_telemetry_attributes.js +44 -0
  57. package/dist/src/instrumentation/elevenlabs/full_instrumentation.d.ts +28 -0
  58. package/dist/src/instrumentation/elevenlabs/full_instrumentation.js +209 -0
  59. package/dist/src/instrumentation/google/get_audio_telemetry.d.ts +9 -0
  60. package/dist/src/instrumentation/google/get_audio_telemetry.js +28 -0
  61. package/dist/src/instrumentation/google/get_cache_operations_telemetry.d.ts +23 -0
  62. package/dist/src/instrumentation/google/get_cache_operations_telemetry.js +154 -0
  63. package/dist/src/instrumentation/google/get_cache_telemetry.d.ts +16 -0
  64. package/{src → dist/src}/instrumentation/google/get_cache_telemetry.js +18 -19
  65. package/dist/src/instrumentation/google/get_embeddings_telemetry.d.ts +12 -0
  66. package/dist/src/instrumentation/google/get_embeddings_telemetry.js +85 -0
  67. package/dist/src/instrumentation/google/get_provider_name.d.ts +11 -0
  68. package/{src → dist/src}/instrumentation/google/get_provider_name.js +11 -12
  69. package/{src/instrumentation/google/get_reasoning_telemetry.js → dist/src/instrumentation/google/get_reasoning_telemetry.d.ts} +1 -11
  70. package/dist/src/instrumentation/google/get_reasoning_telemetry.js +21 -0
  71. package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.d.ts +12 -0
  72. package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.js +19 -0
  73. package/dist/src/instrumentation/google/set_telemetry_attributes.d.ts +18 -0
  74. package/dist/src/instrumentation/google/set_telemetry_attributes.js +98 -0
  75. package/dist/src/instrumentation/openai/get_audio_telemetry.d.ts +25 -0
  76. package/dist/src/instrumentation/openai/get_audio_telemetry.js +123 -0
  77. package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.d.ts +35 -0
  78. package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.js +148 -0
  79. package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.d.ts +27 -0
  80. package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +72 -0
  81. package/dist/src/instrumentation/openai/get_cache_config_telemetry.d.ts +28 -0
  82. package/dist/src/instrumentation/openai/get_cache_config_telemetry.js +91 -0
  83. package/dist/src/instrumentation/openai/get_embeddings_telemetry.d.ts +18 -0
  84. package/dist/src/instrumentation/openai/get_embeddings_telemetry.js +86 -0
  85. package/dist/src/instrumentation/openai/get_streaming_usage.d.ts +21 -0
  86. package/dist/src/instrumentation/openai/get_streaming_usage.js +74 -0
  87. package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.d.ts +12 -0
  88. package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.js +20 -0
  89. package/dist/src/instrumentation/openai/set_telemetry_attributes.d.ts +17 -0
  90. package/dist/src/instrumentation/openai/set_telemetry_attributes.js +47 -0
  91. package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.d.ts +35 -0
  92. package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.js +76 -0
  93. package/dist/src/instrumentation/vercel/full_instrumentation.d.ts +3 -0
  94. package/dist/src/instrumentation/vercel/full_instrumentation.js +54 -0
  95. package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.d.ts +22 -0
  96. package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.js +66 -0
  97. package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.d.ts +24 -0
  98. package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.js +84 -0
  99. package/dist/src/logger.d.ts +1 -0
  100. package/dist/src/logger.js +6 -0
  101. package/dist/src/otel/exporter.d.ts +19 -0
  102. package/dist/src/otel/exporter.js +94 -0
  103. package/dist/src/otel/propagation.d.ts +46 -0
  104. package/dist/src/otel/propagation.js +110 -0
  105. package/dist/src/otel/span-filter.d.ts +3 -0
  106. package/dist/src/otel/span-filter.js +61 -0
  107. package/dist/src/otel/span-processor.d.ts +55 -0
  108. package/dist/src/otel/span-processor.js +169 -0
  109. package/dist/src/otel/vercel-ai-sdk-span-filter.d.ts +12 -0
  110. package/dist/src/otel/vercel-ai-sdk-span-filter.js +88 -0
  111. package/dist/src/setup.d.ts +50 -0
  112. package/dist/src/setup.js +155 -0
  113. package/package.json +12 -5
  114. package/.prettierignore +0 -2
  115. package/.prettierrc.json +0 -7
  116. package/LICENSE-MIT +0 -21
  117. package/NOTICE +0 -12
  118. package/dist/api/generated/index.d.ts +0 -2
  119. package/dist/api/generated/types.gen.d.ts +0 -1005
  120. package/eslint.config.mjs +0 -36
  121. package/index.d.ts +0 -170
  122. package/openapi-ts.config.mjs +0 -9
  123. package/scripts/generate_facade.mjs +0 -86
  124. package/src/api/caseConversion.ts +0 -58
  125. package/src/api/generated/client/client.gen.ts +0 -277
  126. package/src/api/generated/client/index.ts +0 -27
  127. package/src/api/generated/client/types.gen.ts +0 -218
  128. package/src/api/generated/client/utils.gen.ts +0 -316
  129. package/src/api/generated/client.gen.ts +0 -16
  130. package/src/api/generated/core/auth.gen.ts +0 -48
  131. package/src/api/generated/core/bodySerializer.gen.ts +0 -82
  132. package/src/api/generated/core/params.gen.ts +0 -178
  133. package/src/api/generated/core/pathSerializer.gen.ts +0 -171
  134. package/src/api/generated/core/queryKeySerializer.gen.ts +0 -117
  135. package/src/api/generated/core/serverSentEvents.gen.ts +0 -242
  136. package/src/api/generated/core/types.gen.ts +0 -110
  137. package/src/api/generated/core/utils.gen.ts +0 -140
  138. package/src/api/generated/facade.gen.ts +0 -104
  139. package/src/api/generated/index.ts +0 -4
  140. package/src/api/generated/sdk.gen.ts +0 -175
  141. package/src/api/index.ts +0 -45
  142. package/src/api/makeEndpoint.ts +0 -54
  143. package/src/auto-instrument.js +0 -172
  144. package/src/index.js +0 -19
  145. package/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +0 -118
  146. package/src/instrumentation/anthropic/get_cache_config_telemetry.js +0 -90
  147. package/src/instrumentation/anthropic/get_streaming_stop_reason_telemetry.js +0 -121
  148. package/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +0 -55
  149. package/src/instrumentation/anthropic/set_telemetry_attributes.js +0 -39
  150. package/src/instrumentation/bedrock/get_cache_config_telemetry.js +0 -106
  151. package/src/instrumentation/bedrock/get_cache_telemetry.js +0 -109
  152. package/src/instrumentation/bedrock/get_input_message_content_telemetry.js +0 -94
  153. package/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +0 -87
  154. package/src/instrumentation/bedrock/set_telemetry_attributes.js +0 -40
  155. package/src/instrumentation/cohere/get_chat_telemetry.js +0 -88
  156. package/src/instrumentation/cohere/get_embeddings_telemetry.js +0 -107
  157. package/src/instrumentation/cohere/set_telemetry_attributes.js +0 -32
  158. package/src/instrumentation/elevenlabs/full_instrumentation.js +0 -236
  159. package/src/instrumentation/google/get_audio_telemetry.js +0 -30
  160. package/src/instrumentation/google/get_cache_operations_telemetry.js +0 -171
  161. package/src/instrumentation/google/get_embeddings_telemetry.js +0 -99
  162. package/src/instrumentation/google/set_telemetry_attributes.js +0 -104
  163. package/src/instrumentation/openai/get_audio_telemetry.js +0 -149
  164. package/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +0 -71
  165. package/src/instrumentation/openai/get_cache_config_telemetry.js +0 -63
  166. package/src/instrumentation/openai/get_embeddings_telemetry.js +0 -107
  167. package/src/instrumentation/openai/get_streaming_usage.js +0 -81
  168. package/src/instrumentation/openai/set_telemetry_attributes.js +0 -41
  169. package/src/instrumentation/vercel/full_instrumentation.js +0 -52
  170. package/src/instrumentation/vercel/get_cache_creation_telemetry.js +0 -70
  171. package/src/logger.js +0 -8
  172. package/src/otel/exporter.js +0 -108
  173. package/src/otel/propagation.js +0 -146
  174. package/src/otel/span-filter.js +0 -69
  175. package/src/otel/span-processor.js +0 -170
  176. package/src/otel/vercel-ai-sdk-span-filter.js +0 -79
  177. package/src/setup.js +0 -167
  178. package/tests/api/index.test.js +0 -437
  179. package/tests/index.test.js +0 -884
  180. package/tests/instrumentation/anthropic/get_cache_and_reasoning_telemetry.test.js +0 -181
  181. package/tests/instrumentation/anthropic/get_cache_config_telemetry.test.js +0 -92
  182. package/tests/instrumentation/anthropic/get_streaming_stop_reason_telemetry.test.js +0 -117
  183. package/tests/instrumentation/anthropic/get_tool_definitions_telemetry.test.js +0 -97
  184. package/tests/instrumentation/bedrock/get_cache_config_telemetry.test.js +0 -107
  185. package/tests/instrumentation/bedrock/get_cache_telemetry.test.js +0 -118
  186. package/tests/instrumentation/bedrock/get_input_message_content_telemetry.test.js +0 -89
  187. package/tests/instrumentation/bedrock/get_streaming_output_message_telemetry.test.js +0 -87
  188. package/tests/instrumentation/cohere/get_chat_telemetry.test.js +0 -148
  189. package/tests/instrumentation/cohere/get_embeddings_telemetry.test.js +0 -132
  190. package/tests/instrumentation/elevenlabs/full_instrumentation.test.js +0 -258
  191. package/tests/instrumentation/google/get_cache_operations_telemetry.test.js +0 -130
  192. package/tests/instrumentation/google/get_embeddings_telemetry.test.js +0 -128
  193. package/tests/instrumentation/google/get_reasoning_telemetry.test.js +0 -41
  194. package/tests/instrumentation/google/set_telemetry_attributes.test.js +0 -219
  195. package/tests/instrumentation/openai/get_audio_telemetry.test.js +0 -170
  196. package/tests/instrumentation/openai/get_cache_and_reasoning_telemetry.test.js +0 -83
  197. package/tests/instrumentation/openai/get_cache_config_telemetry.test.js +0 -83
  198. package/tests/instrumentation/openai/get_embeddings_telemetry.test.js +0 -145
  199. package/tests/instrumentation/openai/get_streaming_usage.test.js +0 -105
  200. package/tests/instrumentation/vercel/full_instrumentation.test.js +0 -16
  201. package/tests/instrumentation/vercel/get_cache_creation_telemetry.test.js +0 -96
  202. package/tests/otel/vercel-ai-sdk-span-filter.test.js +0 -159
  203. package/tsconfig.json +0 -18
  204. /package/dist/{api → src/api}/caseConversion.d.ts +0 -0
  205. /package/dist/{api → src/api}/caseConversion.js +0 -0
  206. /package/dist/{api → src/api}/generated/client/client.gen.d.ts +0 -0
  207. /package/dist/{api → src/api}/generated/client/client.gen.js +0 -0
  208. /package/dist/{api → src/api}/generated/client/index.d.ts +0 -0
  209. /package/dist/{api → src/api}/generated/client/index.js +0 -0
  210. /package/dist/{api → src/api}/generated/client/types.gen.d.ts +0 -0
  211. /package/dist/{api → src/api}/generated/client/types.gen.js +0 -0
  212. /package/dist/{api → src/api}/generated/client/utils.gen.d.ts +0 -0
  213. /package/dist/{api → src/api}/generated/client/utils.gen.js +0 -0
  214. /package/dist/{api → src/api}/generated/client.gen.d.ts +0 -0
  215. /package/dist/{api → src/api}/generated/client.gen.js +0 -0
  216. /package/dist/{api → src/api}/generated/core/auth.gen.d.ts +0 -0
  217. /package/dist/{api → src/api}/generated/core/auth.gen.js +0 -0
  218. /package/dist/{api → src/api}/generated/core/bodySerializer.gen.d.ts +0 -0
  219. /package/dist/{api → src/api}/generated/core/bodySerializer.gen.js +0 -0
  220. /package/dist/{api → src/api}/generated/core/params.gen.d.ts +0 -0
  221. /package/dist/{api → src/api}/generated/core/params.gen.js +0 -0
  222. /package/dist/{api → src/api}/generated/core/pathSerializer.gen.d.ts +0 -0
  223. /package/dist/{api → src/api}/generated/core/pathSerializer.gen.js +0 -0
  224. /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.d.ts +0 -0
  225. /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.js +0 -0
  226. /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.d.ts +0 -0
  227. /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.js +0 -0
  228. /package/dist/{api → src/api}/generated/core/types.gen.d.ts +0 -0
  229. /package/dist/{api → src/api}/generated/core/types.gen.js +0 -0
  230. /package/dist/{api → src/api}/generated/core/utils.gen.d.ts +0 -0
  231. /package/dist/{api → src/api}/generated/core/utils.gen.js +0 -0
  232. /package/dist/{api → src/api}/generated/types.gen.js +0 -0
  233. /package/dist/{api → src/api}/index.d.ts +0 -0
  234. /package/dist/{api → src/api}/index.js +0 -0
  235. /package/dist/{api → src/api}/makeEndpoint.d.ts +0 -0
@@ -1,118 +0,0 @@
1
- 'use strict';
2
-
3
- // Tests for the Bedrock cached-prompt token complement. It wraps the primary
4
- // instrumentor's `_wrapPromise(span, promise, modelId)` to read Nova's cache-token
5
- // counts off the decoded InvokeModel response body and stamp them as
6
- // gen_ai.usage.cache_* attributes.
7
-
8
- const test = require('node:test');
9
- const assert = require('node:assert/strict');
10
-
11
- const {
12
- BedrockPromptCachingInstrumentor,
13
- } = require('../../../src/instrumentation/bedrock/get_cache_telemetry');
14
-
15
- function fakeSpan() {
16
- const attrs = {};
17
- return {
18
- attrs,
19
- isRecording: () => true,
20
- setAttribute(key, value) {
21
- attrs[key] = value;
22
- },
23
- };
24
- }
25
-
26
- function encode(obj) {
27
- return new TextEncoder().encode(JSON.stringify(obj));
28
- }
29
-
30
- // Pass-through original: resolve to whatever promise it was handed.
31
- function passthroughInstrumentation() {
32
- return { _wrapPromise: (_span, promise) => Promise.resolve(promise) };
33
- }
34
-
35
- test('stamps cache write from an anthropic-on-bedrock usage shape', () => {
36
- const instrumentation = { _wrapPromise: (span, promise) => promise };
37
- new BedrockPromptCachingInstrumentor().instrument(instrumentation);
38
-
39
- const span = fakeSpan();
40
- const body = new TextEncoder().encode(
41
- JSON.stringify({
42
- usage: { input_tokens: 10, cache_creation_input_tokens: 5300, cache_read_input_tokens: 0 },
43
- })
44
- );
45
- return instrumentation._wrapPromise(span, Promise.resolve({ body })).then(() => {
46
- assert.equal(span.attrs['gen_ai.usage.cache_creation_input_tokens'], 5300);
47
- assert.equal(span.attrs['gen_ai.usage.cache_read_input_tokens'], undefined);
48
- });
49
- });
50
-
51
- test('stamps cache read/write from a buffered InvokeModel body', async () => {
52
- const instrumentation = passthroughInstrumentation();
53
- new BedrockPromptCachingInstrumentor().instrument(instrumentation);
54
-
55
- const span = fakeSpan();
56
- const body = encode({
57
- usage: { cacheReadInputTokenCount: 100, cacheWriteInputTokenCount: 1300 },
58
- });
59
- await instrumentation._wrapPromise(span, Promise.resolve({ body }), 'amazon.nova-micro-v1:0');
60
-
61
- assert.equal(span.attrs['gen_ai.usage.cache_read_input_tokens'], 100);
62
- assert.equal(span.attrs['gen_ai.usage.cache_creation_input_tokens'], 1300);
63
- });
64
-
65
- test('sets nothing when cache counts are zero', async () => {
66
- const instrumentation = passthroughInstrumentation();
67
- new BedrockPromptCachingInstrumentor().instrument(instrumentation);
68
-
69
- const span = fakeSpan();
70
- const body = encode({ usage: { cacheReadInputTokenCount: 0, cacheWriteInputTokenCount: 0 } });
71
- await instrumentation._wrapPromise(span, Promise.resolve({ body }), 'm');
72
-
73
- assert.equal(span.attrs['gen_ai.usage.cache_read_input_tokens'], undefined);
74
- assert.equal(span.attrs['gen_ai.usage.cache_creation_input_tokens'], undefined);
75
- });
76
-
77
- test('skips a streamed (async-iterable) body without consuming it', async () => {
78
- const instrumentation = passthroughInstrumentation();
79
- new BedrockPromptCachingInstrumentor().instrument(instrumentation);
80
-
81
- const span = fakeSpan();
82
- let consumed = false;
83
- const body = (async function* () {
84
- consumed = true;
85
- yield {};
86
- })();
87
- await instrumentation._wrapPromise(span, Promise.resolve({ body }), 'm');
88
-
89
- assert.equal(span.attrs['gen_ai.usage.cache_read_input_tokens'], undefined);
90
- assert.equal(consumed, false);
91
- });
92
-
93
- test('stamps cache from the streamed metadata chunk and calls the original', () => {
94
- const calls = [];
95
- const instrumentation = {
96
- _handleNovaStreamingMetadata(span, parsed) {
97
- calls.push(parsed);
98
- },
99
- };
100
- new BedrockPromptCachingInstrumentor().instrument(instrumentation);
101
-
102
- const span = fakeSpan();
103
- instrumentation._handleNovaStreamingMetadata(span, {
104
- metadata: {
105
- usage: { inputTokens: 3, cacheReadInputTokenCount: 1458, cacheWriteInputTokenCount: 0 },
106
- },
107
- });
108
-
109
- assert.equal(span.attrs['gen_ai.usage.cache_read_input_tokens'], 1458);
110
- assert.equal(span.attrs['gen_ai.usage.cache_creation_input_tokens'], undefined);
111
- assert.equal(calls.length, 1);
112
- });
113
-
114
- test('is a no-op when the instrumentor has no _wrapPromise', () => {
115
- const instrumentation = {};
116
- new BedrockPromptCachingInstrumentor().instrument(instrumentation);
117
- assert.equal(instrumentation._wrapPromise, undefined);
118
- });
@@ -1,89 +0,0 @@
1
- 'use strict';
2
-
3
- // Tests for the Bedrock input-message-content complement.
4
- //
5
- // The traceloop instrumentation instance is stubbed with a `_startSpan` that
6
- // returns a fake span — with or without instrumentor-set input messages — so
7
- // the wrap's "only when missing" behaviour can be exercised.
8
-
9
- const test = require('node:test');
10
- const assert = require('node:assert/strict');
11
-
12
- const {
13
- BedrockInputMessageContentInstrumentor,
14
- } = require('../../../src/instrumentation/bedrock/get_input_message_content_telemetry');
15
-
16
- function makeFakeSpan(attributes = {}) {
17
- return {
18
- attributes,
19
- setAttribute(key, value) {
20
- attributes[key] = value;
21
- },
22
- };
23
- }
24
-
25
- function makeStubInstrumentation(spanAttributes) {
26
- return {
27
- _startSpan() {
28
- return makeFakeSpan(spanAttributes);
29
- },
30
- };
31
- }
32
-
33
- function request(body) {
34
- return { params: { input: { modelId: 'model-that-does-not-exist', body } } };
35
- }
36
-
37
- test('stamps input messages when the instrumentor set none', () => {
38
- const instrumentation = makeStubInstrumentation({});
39
- new BedrockInputMessageContentInstrumentor().instrument(instrumentation);
40
-
41
- const span = instrumentation._startSpan(
42
- request(JSON.stringify({ messages: [{ role: 'user', content: [{ text: 'Hello' }] }] }))
43
- );
44
-
45
- assert.deepEqual(JSON.parse(span.attributes['gen_ai.input.messages']), [
46
- { role: 'user', parts: [{ type: 'text', content: 'Hello' }] },
47
- ]);
48
- });
49
-
50
- test('supports the flat inputText schema', () => {
51
- const instrumentation = makeStubInstrumentation({});
52
- new BedrockInputMessageContentInstrumentor().instrument(instrumentation);
53
-
54
- const span = instrumentation._startSpan(request(JSON.stringify({ inputText: 'Hello' })));
55
-
56
- assert.deepEqual(JSON.parse(span.attributes['gen_ai.input.messages']), [
57
- { role: 'user', parts: [{ type: 'text', content: 'Hello' }] },
58
- ]);
59
- });
60
-
61
- test('leaves instrumentor-set input messages untouched', () => {
62
- const existing = '[{"role":"user","parts":[{"type":"text","content":"from-traceloop"}]}]';
63
- const instrumentation = makeStubInstrumentation({ 'gen_ai.input.messages': existing });
64
- new BedrockInputMessageContentInstrumentor().instrument(instrumentation);
65
-
66
- const span = instrumentation._startSpan(
67
- request(JSON.stringify({ messages: [{ role: 'user', content: [{ text: 'other' }] }] }))
68
- );
69
-
70
- assert.equal(span.attributes['gen_ai.input.messages'], existing);
71
- });
72
-
73
- test('no attribute for an unparseable or empty body', () => {
74
- const instrumentation = makeStubInstrumentation({});
75
- new BedrockInputMessageContentInstrumentor().instrument(instrumentation);
76
-
77
- assert.ok(
78
- !('gen_ai.input.messages' in instrumentation._startSpan(request('not-json')).attributes)
79
- );
80
- });
81
-
82
- test('uninstrument restores the original startSpan', () => {
83
- const instrumentation = makeStubInstrumentation({});
84
- const original = instrumentation._startSpan;
85
- const instrumentor = new BedrockInputMessageContentInstrumentor();
86
- instrumentor.instrument(instrumentation);
87
- instrumentor.uninstrument();
88
- assert.equal(instrumentation._startSpan, original);
89
- });
@@ -1,87 +0,0 @@
1
- 'use strict';
2
-
3
- // Tests for the Bedrock streamed-output message complement.
4
- //
5
- // The traceloop instrumentation instance is stubbed with a
6
- // `_handleNovaStreamingMetadata` no-op; chunks are replayed through the wrap the
7
- // way the instrumentation's stream loop calls it.
8
-
9
- const test = require('node:test');
10
- const assert = require('node:assert/strict');
11
-
12
- const {
13
- BedrockStreamingOutputMessageInstrumentor,
14
- } = require('../../../src/instrumentation/bedrock/get_streaming_output_message_telemetry');
15
-
16
- function makeFakeSpan() {
17
- const attributes = {};
18
- return {
19
- attributes,
20
- setAttribute(key, value) {
21
- attributes[key] = value;
22
- },
23
- };
24
- }
25
-
26
- function instrumented() {
27
- const instrumentation = { _handleNovaStreamingMetadata() {} };
28
- const instrumentor = new BedrockStreamingOutputMessageInstrumentor();
29
- instrumentor.instrument(instrumentation);
30
- return { instrumentation, instrumentor };
31
- }
32
-
33
- test('re-stamps the output message from accumulated stream chunks', () => {
34
- const { instrumentation } = instrumented();
35
- const span = makeFakeSpan();
36
-
37
- instrumentation._handleNovaStreamingMetadata(span, {
38
- contentBlockDelta: { delta: { text: 'Hel' } },
39
- });
40
- instrumentation._handleNovaStreamingMetadata(span, {
41
- contentBlockDelta: { delta: { text: 'lo!' } },
42
- });
43
- instrumentation._handleNovaStreamingMetadata(span, {
44
- messageStop: { stopReason: 'end_turn' },
45
- });
46
- assert.ok(!('gen_ai.output.messages' in span.attributes), 'set only on the metadata chunk');
47
-
48
- instrumentation._handleNovaStreamingMetadata(span, { metadata: { usage: {} } });
49
- assert.deepEqual(JSON.parse(span.attributes['gen_ai.output.messages']), [
50
- {
51
- role: 'assistant',
52
- parts: [{ type: 'text', content: 'Hello!' }],
53
- finish_reason: 'stop',
54
- },
55
- ]);
56
- });
57
-
58
- test('maps max_tokens to length', () => {
59
- const { instrumentation } = instrumented();
60
- const span = makeFakeSpan();
61
- instrumentation._handleNovaStreamingMetadata(span, {
62
- contentBlockDelta: { delta: { text: 'OK' } },
63
- });
64
- instrumentation._handleNovaStreamingMetadata(span, {
65
- messageStop: { stopReason: 'max_tokens' },
66
- });
67
- instrumentation._handleNovaStreamingMetadata(span, { metadata: {} });
68
- assert.equal(JSON.parse(span.attributes['gen_ai.output.messages'])[0].finish_reason, 'length');
69
- });
70
-
71
- test('no attribute when no text was streamed', () => {
72
- const { instrumentation } = instrumented();
73
- const span = makeFakeSpan();
74
- instrumentation._handleNovaStreamingMetadata(span, {
75
- messageStop: { stopReason: 'end_turn' },
76
- });
77
- instrumentation._handleNovaStreamingMetadata(span, { metadata: {} });
78
- assert.ok(!('gen_ai.output.messages' in span.attributes));
79
- });
80
-
81
- test('uninstrument restores the original handler', () => {
82
- const { instrumentation, instrumentor } = instrumented();
83
- instrumentor.uninstrument();
84
- const span = makeFakeSpan();
85
- instrumentation._handleNovaStreamingMetadata(span, { metadata: {} });
86
- assert.deepEqual(span.attributes, {});
87
- });
@@ -1,148 +0,0 @@
1
- 'use strict';
2
-
3
- // Tests for the Cohere chat token-usage enrichment complement.
4
- //
5
- // The cohere-ai v1 `CohereClient` is stubbed with an internal `__chat` method
6
- // that mirrors the SDK shape — resolving to `{ data: { meta: { billedUnits } } }`
7
- // — so the complement can be exercised without network access or the dependency
8
- // installed. The complement enriches whichever span is active when `__chat` runs
9
- // (in production, the span traceloop opens around the public `chat`), so the
10
- // tests start a span and make it active before invoking `__chat`.
11
-
12
- const test = require('node:test');
13
- const assert = require('node:assert/strict');
14
- const Module = require('node:module');
15
-
16
- const { trace, context } = require('@opentelemetry/api');
17
- const {
18
- BasicTracerProvider,
19
- InMemorySpanExporter,
20
- SimpleSpanProcessor,
21
- } = require('@opentelemetry/sdk-trace-base');
22
- const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks');
23
-
24
- const {
25
- CohereChatTokenUsageInstrumentor,
26
- } = require('../../../src/instrumentation/cohere/get_chat_telemetry');
27
-
28
- const CLIENT_MODULE = 'cohere-ai/Client';
29
-
30
- const exporter = new InMemorySpanExporter();
31
- trace.setGlobalTracerProvider(
32
- new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] })
33
- );
34
- context.setGlobalContextManager(new AsyncLocalStorageContextManager().enable());
35
- const tracer = trace.getTracer('test');
36
-
37
- class StubCohereClient {
38
- __chat(request = {}) {
39
- if (request.model === 'boom') return Promise.reject(new Error('api error'));
40
- return Promise.resolve({
41
- data: { text: 'hi', meta: { billedUnits: { inputTokens: 7, outputTokens: 3 } } },
42
- });
43
- }
44
- }
45
-
46
- function instrumented() {
47
- const stubs = { [CLIENT_MODULE]: { CohereClient: StubCohereClient } };
48
- const origResolve = Module._resolveFilename;
49
- Module._resolveFilename = function patched(request, ...rest) {
50
- if (request in stubs) return request;
51
- return origResolve.call(this, request, ...rest);
52
- };
53
- for (const [moduleId, exports] of Object.entries(stubs)) {
54
- require.cache[moduleId] = { id: moduleId, filename: moduleId, loaded: true, exports };
55
- }
56
-
57
- const instrumentor = new CohereChatTokenUsageInstrumentor();
58
- instrumentor.instrument();
59
-
60
- return () => {
61
- instrumentor.uninstrument();
62
- Module._resolveFilename = origResolve;
63
- for (const moduleId of Object.keys(stubs)) delete require.cache[moduleId];
64
- exporter.reset();
65
- };
66
- }
67
-
68
- // Runs `__chat` inside an active span, mirroring the context traceloop sets up
69
- // around the public `chat`, and returns the finished span.
70
- async function callChatWithinSpan(client, request) {
71
- const span = tracer.startSpan('cohere.chat');
72
- await context.with(trace.setSpan(context.active(), span), () => client.__chat(request));
73
- span.end();
74
- return exporter.getFinishedSpans().find((finished) => finished.name === 'cohere.chat');
75
- }
76
-
77
- test('enriches the active chat span with input and output tokens', async () => {
78
- const teardown = instrumented();
79
- try {
80
- const client = new StubCohereClient();
81
- const span = await callChatWithinSpan(client, { model: 'command-r-08-2024', message: 'hi' });
82
-
83
- assert.equal(span.attributes['gen_ai.usage.input_tokens'], 7);
84
- assert.equal(span.attributes['gen_ai.usage.output_tokens'], 3);
85
- } finally {
86
- teardown();
87
- }
88
- });
89
-
90
- test('leaves the response unchanged', async () => {
91
- const teardown = instrumented();
92
- try {
93
- const client = new StubCohereClient();
94
- let result;
95
- const span = tracer.startSpan('cohere.chat');
96
- await context.with(trace.setSpan(context.active(), span), async () => {
97
- result = await client.__chat({ model: 'command-r-08-2024', message: 'hi' });
98
- });
99
- span.end();
100
-
101
- assert.equal(result.data.text, 'hi');
102
- assert.equal(result.data.meta.billedUnits.inputTokens, 7);
103
- } finally {
104
- teardown();
105
- }
106
- });
107
-
108
- test('does nothing when no span is active', async () => {
109
- const teardown = instrumented();
110
- try {
111
- const client = new StubCohereClient();
112
- // No active span — must not throw, just pass the response through.
113
- const result = await client.__chat({ model: 'command-r-08-2024', message: 'hi' });
114
- assert.equal(result.data.meta.billedUnits.outputTokens, 3);
115
- assert.equal(exporter.getFinishedSpans().length, 0);
116
- } finally {
117
- teardown();
118
- }
119
- });
120
-
121
- test('propagates errors without enriching the span', async () => {
122
- const teardown = instrumented();
123
- try {
124
- const client = new StubCohereClient();
125
- const span = tracer.startSpan('cohere.chat');
126
- await assert.rejects(
127
- () =>
128
- context.with(trace.setSpan(context.active(), span), () =>
129
- client.__chat({ model: 'boom', message: 'x' })
130
- ),
131
- /api error/
132
- );
133
- span.end();
134
-
135
- const finished = exporter.getFinishedSpans().find((each) => each.name === 'cohere.chat');
136
- assert.equal(finished.attributes['gen_ai.usage.input_tokens'], undefined);
137
- } finally {
138
- teardown();
139
- }
140
- });
141
-
142
- test('uninstrument restores the original method', async () => {
143
- const teardown = instrumented();
144
- const { CohereClient } = require(CLIENT_MODULE);
145
- const wrapped = CohereClient.prototype.__chat;
146
- teardown();
147
- assert.notEqual(CohereClient.prototype.__chat, wrapped);
148
- });
@@ -1,132 +0,0 @@
1
- 'use strict';
2
-
3
- // Tests for the bundled Cohere embeddings instrumentor.
4
- //
5
- // The cohere-ai v1 `CohereClient` and v2 `V2Client` classes are stubbed with an
6
- // `embed` method that mirrors the SDK shape — resolving to a response carrying
7
- // `meta.billedUnits.inputTokens` — so the instrumentor can be exercised without
8
- // network access or the dependency installed.
9
-
10
- const test = require('node:test');
11
- const assert = require('node:assert/strict');
12
- const Module = require('node:module');
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
- CohereEmbeddingsInstrumentor,
23
- } = require('../../../src/instrumentation/cohere/get_embeddings_telemetry');
24
-
25
- const V1_MODULE = 'cohere-ai/Client';
26
- const V2_MODULE = 'cohere-ai/api/resources/v2/client/Client';
27
-
28
- const exporter = new InMemorySpanExporter();
29
- trace.setGlobalTracerProvider(
30
- new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] })
31
- );
32
-
33
- class StubCohereClient {
34
- embed(request = {}) {
35
- if (request.model === 'boom') return Promise.reject(new Error('api error'));
36
- return Promise.resolve({ embeddings: [[0.1]], meta: { billedUnits: { inputTokens: 8 } } });
37
- }
38
- }
39
-
40
- class StubV2Client {
41
- embed(_request = {}) {
42
- return Promise.resolve({
43
- embeddings: { float: [[0.2]] },
44
- meta: { billedUnits: { inputTokens: 5 } },
45
- });
46
- }
47
- }
48
-
49
- function instrumented() {
50
- const stubs = {
51
- [V1_MODULE]: { CohereClient: StubCohereClient },
52
- [V2_MODULE]: { V2Client: StubV2Client },
53
- };
54
- const origResolve = Module._resolveFilename;
55
- Module._resolveFilename = function patched(request, ...rest) {
56
- if (request in stubs) return request;
57
- return origResolve.call(this, request, ...rest);
58
- };
59
- for (const [moduleId, exports] of Object.entries(stubs)) {
60
- require.cache[moduleId] = { id: moduleId, filename: moduleId, loaded: true, exports };
61
- }
62
-
63
- const instrumentor = new CohereEmbeddingsInstrumentor();
64
- instrumentor.instrument();
65
-
66
- return () => {
67
- instrumentor.uninstrument();
68
- Module._resolveFilename = origResolve;
69
- for (const moduleId of Object.keys(stubs)) delete require.cache[moduleId];
70
- exporter.reset();
71
- };
72
- }
73
-
74
- test('v1 embed emits genai span with input tokens', async () => {
75
- const teardown = instrumented();
76
- try {
77
- const client = new StubCohereClient();
78
- const result = await client.embed({ model: 'embed-english-v3.0', texts: ['hi'] });
79
- assert.equal(result.meta.billedUnits.inputTokens, 8);
80
-
81
- const [span] = exporter.getFinishedSpans();
82
- assert.equal(span.name, 'embeddings');
83
- assert.equal(span.attributes['gen_ai.system'], 'Cohere');
84
- assert.equal(span.attributes['gen_ai.operation.name'], 'embeddings');
85
- assert.equal(span.attributes['gen_ai.request.model'], 'embed-english-v3.0');
86
- assert.equal(span.attributes['gen_ai.usage.input_tokens'], 8);
87
- assert.deepEqual(JSON.parse(span.attributes['gen_ai.input.messages']), [
88
- { role: 'user', parts: [{ type: 'text', content: 'hi' }] },
89
- ]);
90
- assert.equal(span.status.code, SpanStatusCode.UNSET);
91
- } finally {
92
- teardown();
93
- }
94
- });
95
-
96
- test('v2 embed emits genai span with input tokens', async () => {
97
- const teardown = instrumented();
98
- try {
99
- const client = new StubV2Client();
100
- await client.embed({ model: 'embed-v4.0', texts: ['hi'] });
101
-
102
- const [span] = exporter.getFinishedSpans();
103
- assert.equal(span.attributes['gen_ai.request.model'], 'embed-v4.0');
104
- assert.equal(span.attributes['gen_ai.usage.input_tokens'], 5);
105
- } finally {
106
- teardown();
107
- }
108
- });
109
-
110
- test('embed records error status on failure', async () => {
111
- const teardown = instrumented();
112
- try {
113
- const client = new StubCohereClient();
114
- await assert.rejects(() => client.embed({ model: 'boom', texts: ['x'] }), /api error/);
115
-
116
- const [span] = exporter.getFinishedSpans();
117
- assert.equal(span.status.code, SpanStatusCode.ERROR);
118
- } finally {
119
- teardown();
120
- }
121
- });
122
-
123
- test('uninstrument restores original methods', async () => {
124
- const teardown = instrumented();
125
- try {
126
- const client = new StubCohereClient();
127
- await client.embed({ model: 'embed-english-v3.0', texts: ['x'] });
128
- assert.equal(exporter.getFinishedSpans().length, 1);
129
- } finally {
130
- teardown();
131
- }
132
- });