weflayr 0.23.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.
Files changed (225) hide show
  1. package/README.md +2 -2
  2. package/dist/{api → src/api}/generated/facade.gen.d.ts +163 -12
  3. package/dist/{api → src/api}/generated/facade.gen.js +10 -2
  4. package/dist/src/api/generated/index.d.ts +2 -0
  5. package/dist/{api → src/api}/generated/index.js +9 -1
  6. package/dist/{api → src/api}/generated/sdk.gen.d.ts +35 -3
  7. package/dist/{api → src/api}/generated/sdk.gen.js +88 -4
  8. package/{src/api/generated/types.gen.ts → dist/src/api/generated/types.gen.d.ts} +692 -116
  9. package/dist/{api → src/api}/makeEndpoint.js +1 -3
  10. package/dist/src/auto-instrument.d.ts +42 -0
  11. package/dist/src/auto-instrument.js +156 -0
  12. package/dist/src/index.d.ts +9 -0
  13. package/dist/src/index.js +49 -0
  14. package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.d.ts +20 -0
  15. package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +114 -0
  16. package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.d.ts +28 -0
  17. package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.js +92 -0
  18. package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.d.ts +25 -0
  19. package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.js +141 -0
  20. package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.d.ts +9 -0
  21. package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.js +17 -0
  22. package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.d.ts +15 -0
  23. package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +50 -0
  24. package/dist/src/instrumentation/anthropic/set_telemetry_attributes.d.ts +15 -0
  25. package/dist/src/instrumentation/anthropic/set_telemetry_attributes.js +39 -0
  26. package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.d.ts +22 -0
  27. package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.js +97 -0
  28. package/dist/src/instrumentation/bedrock/get_cache_telemetry.d.ts +22 -0
  29. package/dist/src/instrumentation/bedrock/get_cache_telemetry.js +102 -0
  30. package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.d.ts +15 -0
  31. package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.js +91 -0
  32. package/dist/src/instrumentation/bedrock/get_model_id_telemetry.d.ts +21 -0
  33. package/dist/src/instrumentation/bedrock/get_model_id_telemetry.js +54 -0
  34. package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.d.ts +19 -0
  35. package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.js +81 -0
  36. package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.d.ts +27 -0
  37. package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +126 -0
  38. package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.d.ts +17 -0
  39. package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.js +85 -0
  40. package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.d.ts +15 -0
  41. package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.js +68 -0
  42. package/dist/src/instrumentation/bedrock/set_telemetry_attributes.d.ts +18 -0
  43. package/dist/src/instrumentation/bedrock/set_telemetry_attributes.js +47 -0
  44. package/dist/src/instrumentation/cohere/get_chat_telemetry.d.ts +23 -0
  45. package/dist/src/instrumentation/cohere/get_chat_telemetry.js +77 -0
  46. package/dist/src/instrumentation/cohere/get_embeddings_telemetry.d.ts +18 -0
  47. package/dist/src/instrumentation/cohere/get_embeddings_telemetry.js +88 -0
  48. package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.d.ts +12 -0
  49. package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.js +18 -0
  50. package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.d.ts +31 -0
  51. package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.js +106 -0
  52. package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.d.ts +27 -0
  53. package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.js +75 -0
  54. package/dist/src/instrumentation/cohere/set_telemetry_attributes.d.ts +17 -0
  55. package/dist/src/instrumentation/cohere/set_telemetry_attributes.js +44 -0
  56. package/dist/src/instrumentation/elevenlabs/full_instrumentation.d.ts +28 -0
  57. package/dist/src/instrumentation/elevenlabs/full_instrumentation.js +209 -0
  58. package/dist/src/instrumentation/google/get_audio_telemetry.d.ts +9 -0
  59. package/dist/src/instrumentation/google/get_audio_telemetry.js +28 -0
  60. package/dist/src/instrumentation/google/get_cache_operations_telemetry.d.ts +23 -0
  61. package/dist/src/instrumentation/google/get_cache_operations_telemetry.js +154 -0
  62. package/dist/src/instrumentation/google/get_cache_telemetry.d.ts +16 -0
  63. package/dist/src/instrumentation/google/get_cache_telemetry.js +38 -0
  64. package/dist/src/instrumentation/google/get_embeddings_telemetry.d.ts +12 -0
  65. package/dist/src/instrumentation/google/get_embeddings_telemetry.js +85 -0
  66. package/dist/src/instrumentation/google/get_provider_name.d.ts +11 -0
  67. package/{src → dist/src}/instrumentation/google/get_provider_name.js +11 -12
  68. package/{src/instrumentation/google/get_reasoning_telemetry.js → dist/src/instrumentation/google/get_reasoning_telemetry.d.ts} +1 -11
  69. package/dist/src/instrumentation/google/get_reasoning_telemetry.js +21 -0
  70. package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.d.ts +12 -0
  71. package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.js +19 -0
  72. package/dist/src/instrumentation/google/set_telemetry_attributes.d.ts +18 -0
  73. package/dist/src/instrumentation/google/set_telemetry_attributes.js +98 -0
  74. package/dist/src/instrumentation/openai/get_audio_telemetry.d.ts +25 -0
  75. package/dist/src/instrumentation/openai/get_audio_telemetry.js +123 -0
  76. package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.d.ts +35 -0
  77. package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.js +148 -0
  78. package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.d.ts +27 -0
  79. package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +72 -0
  80. package/dist/src/instrumentation/openai/get_cache_config_telemetry.d.ts +28 -0
  81. package/dist/src/instrumentation/openai/get_cache_config_telemetry.js +91 -0
  82. package/dist/src/instrumentation/openai/get_embeddings_telemetry.d.ts +18 -0
  83. package/dist/src/instrumentation/openai/get_embeddings_telemetry.js +86 -0
  84. package/dist/src/instrumentation/openai/get_streaming_usage.d.ts +21 -0
  85. package/dist/src/instrumentation/openai/get_streaming_usage.js +74 -0
  86. package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.d.ts +12 -0
  87. package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.js +20 -0
  88. package/dist/src/instrumentation/openai/set_telemetry_attributes.d.ts +17 -0
  89. package/dist/src/instrumentation/openai/set_telemetry_attributes.js +47 -0
  90. package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.d.ts +35 -0
  91. package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.js +76 -0
  92. package/dist/src/instrumentation/vercel/full_instrumentation.d.ts +3 -0
  93. package/dist/src/instrumentation/vercel/full_instrumentation.js +54 -0
  94. package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.d.ts +22 -0
  95. package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.js +66 -0
  96. package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.d.ts +24 -0
  97. package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.js +84 -0
  98. package/dist/src/logger.d.ts +1 -0
  99. package/dist/src/logger.js +6 -0
  100. package/dist/src/otel/exporter.d.ts +19 -0
  101. package/dist/src/otel/exporter.js +94 -0
  102. package/dist/src/otel/propagation.d.ts +46 -0
  103. package/dist/src/otel/propagation.js +110 -0
  104. package/dist/src/otel/span-filter.d.ts +3 -0
  105. package/dist/src/otel/span-filter.js +61 -0
  106. package/dist/src/otel/span-processor.d.ts +55 -0
  107. package/dist/src/otel/span-processor.js +169 -0
  108. package/dist/src/otel/vercel-ai-sdk-span-filter.d.ts +12 -0
  109. package/dist/src/otel/vercel-ai-sdk-span-filter.js +88 -0
  110. package/dist/src/setup.d.ts +50 -0
  111. package/dist/src/setup.js +155 -0
  112. package/package.json +11 -5
  113. package/.prettierignore +0 -2
  114. package/.prettierrc.json +0 -7
  115. package/LICENSE-MIT +0 -21
  116. package/NOTICE +0 -12
  117. package/dist/api/generated/index.d.ts +0 -2
  118. package/dist/api/generated/types.gen.d.ts +0 -749
  119. package/eslint.config.mjs +0 -36
  120. package/index.d.ts +0 -167
  121. package/openapi-ts.config.mjs +0 -9
  122. package/scripts/generate_facade.mjs +0 -86
  123. package/src/api/caseConversion.ts +0 -58
  124. package/src/api/generated/client/client.gen.ts +0 -277
  125. package/src/api/generated/client/index.ts +0 -27
  126. package/src/api/generated/client/types.gen.ts +0 -218
  127. package/src/api/generated/client/utils.gen.ts +0 -316
  128. package/src/api/generated/client.gen.ts +0 -16
  129. package/src/api/generated/core/auth.gen.ts +0 -48
  130. package/src/api/generated/core/bodySerializer.gen.ts +0 -82
  131. package/src/api/generated/core/params.gen.ts +0 -178
  132. package/src/api/generated/core/pathSerializer.gen.ts +0 -171
  133. package/src/api/generated/core/queryKeySerializer.gen.ts +0 -117
  134. package/src/api/generated/core/serverSentEvents.gen.ts +0 -242
  135. package/src/api/generated/core/types.gen.ts +0 -110
  136. package/src/api/generated/core/utils.gen.ts +0 -140
  137. package/src/api/generated/facade.gen.ts +0 -68
  138. package/src/api/generated/index.ts +0 -4
  139. package/src/api/generated/sdk.gen.ts +0 -121
  140. package/src/api/index.ts +0 -45
  141. package/src/api/makeEndpoint.ts +0 -54
  142. package/src/auto-instrument.js +0 -171
  143. package/src/index.js +0 -19
  144. package/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +0 -107
  145. package/src/instrumentation/anthropic/get_streaming_stop_reason_telemetry.js +0 -121
  146. package/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +0 -50
  147. package/src/instrumentation/anthropic/set_telemetry_attributes.js +0 -37
  148. package/src/instrumentation/bedrock/get_cache_telemetry.js +0 -104
  149. package/src/instrumentation/bedrock/get_input_message_content_telemetry.js +0 -94
  150. package/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +0 -87
  151. package/src/instrumentation/bedrock/set_telemetry_attributes.js +0 -36
  152. package/src/instrumentation/cohere/get_chat_telemetry.js +0 -88
  153. package/src/instrumentation/cohere/get_embeddings_telemetry.js +0 -107
  154. package/src/instrumentation/cohere/set_telemetry_attributes.js +0 -32
  155. package/src/instrumentation/elevenlabs/full_instrumentation.js +0 -236
  156. package/src/instrumentation/google/get_audio_telemetry.js +0 -30
  157. package/src/instrumentation/google/get_cache_telemetry.js +0 -25
  158. package/src/instrumentation/google/get_embeddings_telemetry.js +0 -99
  159. package/src/instrumentation/google/set_telemetry_attributes.js +0 -98
  160. package/src/instrumentation/openai/get_audio_telemetry.js +0 -149
  161. package/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +0 -71
  162. package/src/instrumentation/openai/get_embeddings_telemetry.js +0 -107
  163. package/src/instrumentation/openai/get_streaming_usage.js +0 -81
  164. package/src/instrumentation/openai/set_telemetry_attributes.js +0 -39
  165. package/src/instrumentation/vercel/full_instrumentation.js +0 -44
  166. package/src/logger.js +0 -8
  167. package/src/otel/exporter.js +0 -108
  168. package/src/otel/propagation.js +0 -133
  169. package/src/otel/span-filter.js +0 -69
  170. package/src/otel/span-processor.js +0 -162
  171. package/src/otel/vercel-ai-sdk-span-filter.js +0 -79
  172. package/src/setup.js +0 -167
  173. package/tests/api/index.test.js +0 -437
  174. package/tests/index.test.js +0 -824
  175. package/tests/instrumentation/anthropic/get_cache_and_reasoning_telemetry.test.js +0 -158
  176. package/tests/instrumentation/anthropic/get_streaming_stop_reason_telemetry.test.js +0 -117
  177. package/tests/instrumentation/anthropic/get_tool_definitions_telemetry.test.js +0 -82
  178. package/tests/instrumentation/bedrock/get_cache_telemetry.test.js +0 -102
  179. package/tests/instrumentation/bedrock/get_input_message_content_telemetry.test.js +0 -89
  180. package/tests/instrumentation/bedrock/get_streaming_output_message_telemetry.test.js +0 -87
  181. package/tests/instrumentation/cohere/get_chat_telemetry.test.js +0 -148
  182. package/tests/instrumentation/cohere/get_embeddings_telemetry.test.js +0 -132
  183. package/tests/instrumentation/elevenlabs/full_instrumentation.test.js +0 -258
  184. package/tests/instrumentation/google/get_embeddings_telemetry.test.js +0 -128
  185. package/tests/instrumentation/google/get_reasoning_telemetry.test.js +0 -41
  186. package/tests/instrumentation/google/set_telemetry_attributes.test.js +0 -219
  187. package/tests/instrumentation/openai/get_audio_telemetry.test.js +0 -170
  188. package/tests/instrumentation/openai/get_cache_and_reasoning_telemetry.test.js +0 -83
  189. package/tests/instrumentation/openai/get_embeddings_telemetry.test.js +0 -145
  190. package/tests/instrumentation/openai/get_streaming_usage.test.js +0 -105
  191. package/tests/instrumentation/vercel/full_instrumentation.test.js +0 -16
  192. package/tests/otel/vercel-ai-sdk-span-filter.test.js +0 -159
  193. package/tsconfig.json +0 -18
  194. /package/dist/{api → src/api}/caseConversion.d.ts +0 -0
  195. /package/dist/{api → src/api}/caseConversion.js +0 -0
  196. /package/dist/{api → src/api}/generated/client/client.gen.d.ts +0 -0
  197. /package/dist/{api → src/api}/generated/client/client.gen.js +0 -0
  198. /package/dist/{api → src/api}/generated/client/index.d.ts +0 -0
  199. /package/dist/{api → src/api}/generated/client/index.js +0 -0
  200. /package/dist/{api → src/api}/generated/client/types.gen.d.ts +0 -0
  201. /package/dist/{api → src/api}/generated/client/types.gen.js +0 -0
  202. /package/dist/{api → src/api}/generated/client/utils.gen.d.ts +0 -0
  203. /package/dist/{api → src/api}/generated/client/utils.gen.js +0 -0
  204. /package/dist/{api → src/api}/generated/client.gen.d.ts +0 -0
  205. /package/dist/{api → src/api}/generated/client.gen.js +0 -0
  206. /package/dist/{api → src/api}/generated/core/auth.gen.d.ts +0 -0
  207. /package/dist/{api → src/api}/generated/core/auth.gen.js +0 -0
  208. /package/dist/{api → src/api}/generated/core/bodySerializer.gen.d.ts +0 -0
  209. /package/dist/{api → src/api}/generated/core/bodySerializer.gen.js +0 -0
  210. /package/dist/{api → src/api}/generated/core/params.gen.d.ts +0 -0
  211. /package/dist/{api → src/api}/generated/core/params.gen.js +0 -0
  212. /package/dist/{api → src/api}/generated/core/pathSerializer.gen.d.ts +0 -0
  213. /package/dist/{api → src/api}/generated/core/pathSerializer.gen.js +0 -0
  214. /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.d.ts +0 -0
  215. /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.js +0 -0
  216. /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.d.ts +0 -0
  217. /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.js +0 -0
  218. /package/dist/{api → src/api}/generated/core/types.gen.d.ts +0 -0
  219. /package/dist/{api → src/api}/generated/core/types.gen.js +0 -0
  220. /package/dist/{api → src/api}/generated/core/utils.gen.d.ts +0 -0
  221. /package/dist/{api → src/api}/generated/core/utils.gen.js +0 -0
  222. /package/dist/{api → src/api}/generated/types.gen.js +0 -0
  223. /package/dist/{api → src/api}/index.d.ts +0 -0
  224. /package/dist/{api → src/api}/index.js +0 -0
  225. /package/dist/{api → src/api}/makeEndpoint.d.ts +0 -0
@@ -1,94 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Input message content for Bedrock invoke_model spans the instrumentor misses.
5
- *
6
- * `@traceloop/instrumentation-bedrock` parses the request body per model vendor,
7
- * so a call whose model id has no recognizable vendor (e.g. an invalid model —
8
- * exactly the error spans) gets no `gen_ai.input.messages`. Wrap the
9
- * instrumentor's `_startSpan({ params })` to stamp the input messages from the
10
- * request body whenever the instrumentor did not. The span processor strips the
11
- * attribute when message-content capture is disabled.
12
- */
13
-
14
- function _contentToParts(content) {
15
- if (typeof content === 'string') {
16
- return [{ type: 'text', content }];
17
- }
18
- if (Array.isArray(content)) {
19
- return content
20
- .filter((block) => block && typeof block.text === 'string')
21
- .map((block) => ({ type: 'text', content: block.text }));
22
- }
23
- return [];
24
- }
25
-
26
- // Messages in the role+parts shape from an InvokeModel JSON body — the
27
- // `messages` schema (Nova, Anthropic-on-Bedrock) or the flat `inputText` /
28
- // `prompt` schemas (Titan, legacy).
29
- function _inputMessagesFromRequestBody(rawBody) {
30
- if (typeof rawBody !== 'string') return [];
31
- let body;
32
- try {
33
- body = JSON.parse(rawBody);
34
- } catch {
35
- return [];
36
- }
37
- if (!body || typeof body !== 'object') return [];
38
- if (Array.isArray(body.messages)) {
39
- return body.messages
40
- .filter((message) => message && typeof message === 'object')
41
- .map((message) => ({
42
- role: String(message.role || ''),
43
- parts: _contentToParts(message.content),
44
- }));
45
- }
46
- const prompt = body.inputText || body.prompt;
47
- if (typeof prompt === 'string') {
48
- return [{ role: 'user', parts: [{ type: 'text', content: prompt }] }];
49
- }
50
- return [];
51
- }
52
-
53
- class BedrockInputMessageContentInstrumentor {
54
- constructor() {
55
- // [instrumentation, methodName, originalFunction] for uninstrument().
56
- this._patched = [];
57
- }
58
-
59
- // No-op (and never throws) if the instrumentor's internals have changed shape —
60
- // the worst case is missing input messages, never a crash.
61
- instrument(instrumentation) {
62
- if (!instrumentation) return;
63
- const original = instrumentation._startSpan;
64
- if (typeof original !== 'function') return;
65
-
66
- instrumentation._startSpan = function startSpanWithInputMessages(request) {
67
- const span = original.call(this, request);
68
- try {
69
- const attributes = span && span.attributes;
70
- if (attributes && attributes['gen_ai.input.messages'] == null) {
71
- const body =
72
- request && request.params && request.params.input && request.params.input.body;
73
- const messages = _inputMessagesFromRequestBody(body);
74
- if (messages.length) {
75
- span.setAttribute('gen_ai.input.messages', JSON.stringify(messages));
76
- }
77
- }
78
- } catch {
79
- // Never break span creation over an enrichment failure.
80
- }
81
- return span;
82
- };
83
- this._patched.push([instrumentation, '_startSpan', original]);
84
- }
85
-
86
- uninstrument() {
87
- for (const [owner, methodName, original] of this._patched) {
88
- owner[methodName] = original;
89
- }
90
- this._patched = [];
91
- }
92
- }
93
-
94
- module.exports = { BedrockInputMessageContentInstrumentor };
@@ -1,87 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Streamed-output message content for the Bedrock invoke_model stream span.
5
- *
6
- * `@traceloop/instrumentation-bedrock` accumulates the streamed text but formats
7
- * the final `gen_ai.output.messages` by passing that string through its chat
8
- * block mapper, which only accepts block arrays — so streamed Nova spans end up
9
- * with an assistant message whose `parts` is empty. This complement wraps the
10
- * instrumentor's per-chunk `_handleNovaStreamingMetadata(span, parsedResponse)`
11
- * hook: it accumulates the `contentBlockDelta` text and the `messageStop` stop
12
- * reason itself, and re-stamps a correct output message when the trailing
13
- * `metadata` chunk (always last in a Nova stream) arrives — after the
14
- * instrumentor has written its empty-parts message. The span processor strips
15
- * the attribute when message-content capture is disabled.
16
- */
17
-
18
- // Nova stop reasons mapped to the OTel finish_reason values the instrumentor
19
- // uses on non-streamed spans, so streamed and non-streamed rows normalize alike.
20
- const FINISH_REASON_BY_STOP_REASON = {
21
- end_turn: 'stop',
22
- stop_sequence: 'stop',
23
- max_tokens: 'length',
24
- tool_use: 'tool_call',
25
- };
26
-
27
- class BedrockStreamingOutputMessageInstrumentor {
28
- constructor() {
29
- // [instrumentation, methodName, originalFunction] for uninstrument().
30
- this._patched = [];
31
- // span -> {text, stopReason} accumulated across the stream's chunks.
32
- this._streamStateBySpan = new WeakMap();
33
- }
34
-
35
- // No-op (and never throws) if the instrumentor's internals have changed shape —
36
- // the worst case is an empty streamed output message, never a crash.
37
- instrument(instrumentation) {
38
- if (!instrumentation) return;
39
- const original = instrumentation._handleNovaStreamingMetadata;
40
- if (typeof original !== 'function') return;
41
-
42
- const streamStateBySpan = this._streamStateBySpan;
43
- instrumentation._handleNovaStreamingMetadata = function handleWithOutputMessage(
44
- span,
45
- parsedResponse
46
- ) {
47
- try {
48
- const state = streamStateBySpan.get(span) || { text: '', stopReason: null };
49
- const delta =
50
- parsedResponse &&
51
- parsedResponse.contentBlockDelta &&
52
- parsedResponse.contentBlockDelta.delta &&
53
- parsedResponse.contentBlockDelta.delta.text;
54
- if (typeof delta === 'string') state.text += delta;
55
- const stopReason =
56
- parsedResponse && parsedResponse.messageStop && parsedResponse.messageStop.stopReason;
57
- if (stopReason != null) state.stopReason = stopReason;
58
- streamStateBySpan.set(span, state);
59
-
60
- if (parsedResponse && parsedResponse.metadata && state.text) {
61
- const message = {
62
- role: 'assistant',
63
- parts: [{ type: 'text', content: state.text }],
64
- };
65
- if (state.stopReason != null) {
66
- message.finish_reason =
67
- FINISH_REASON_BY_STOP_REASON[state.stopReason] || state.stopReason;
68
- }
69
- span.setAttribute('gen_ai.output.messages', JSON.stringify([message]));
70
- }
71
- } catch {
72
- // Never break the caller's stream over an enrichment failure.
73
- }
74
- return original.call(this, span, parsedResponse);
75
- };
76
- this._patched.push([instrumentation, '_handleNovaStreamingMetadata', original]);
77
- }
78
-
79
- uninstrument() {
80
- for (const [owner, methodName, original] of this._patched) {
81
- owner[methodName] = original;
82
- }
83
- this._patched = [];
84
- }
85
- }
86
-
87
- module.exports = { BedrockStreamingOutputMessageInstrumentor };
@@ -1,36 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Bedrock telemetry complement — the registered orchestrator.
5
- *
6
- * Wires the weflayr-supplied patches the traceloop Bedrock instrumentor misses:
7
- * cached-prompt token counts on the invoke_model span (Nova returns them in the
8
- * response body but traceloop never reads them) and the streamed output message
9
- * content (its stream path formats an empty-parts message).
10
- */
11
-
12
- const { BedrockPromptCachingInstrumentor } = require('./get_cache_telemetry');
13
- const { BedrockInputMessageContentInstrumentor } = require('./get_input_message_content_telemetry');
14
- const {
15
- BedrockStreamingOutputMessageInstrumentor,
16
- } = require('./get_streaming_output_message_telemetry');
17
-
18
- class BedrockTelemetryInstrumentor {
19
- constructor() {
20
- this._subInstrumentors = [
21
- new BedrockPromptCachingInstrumentor(),
22
- new BedrockInputMessageContentInstrumentor(),
23
- new BedrockStreamingOutputMessageInstrumentor(),
24
- ];
25
- }
26
-
27
- instrument(instrumentation) {
28
- for (const sub of this._subInstrumentors) sub.instrument(instrumentation);
29
- }
30
-
31
- uninstrument() {
32
- for (const sub of this._subInstrumentors) sub.uninstrument();
33
- }
34
- }
35
-
36
- module.exports = { BedrockTelemetryInstrumentor };
@@ -1,88 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Chat token-usage enrichment complement for the Cohere v1 chat path.
5
- *
6
- * `@traceloop/instrumentation-cohere` creates the `cohere.chat` span but reads
7
- * token usage from the obsolete `result.token_count.{prompt,response}_tokens`
8
- * shape; modern cohere-ai returns usage under `meta.billedUnits` instead, so the
9
- * traceloop span ends up with zero chat tokens. This thin complement backfills
10
- * `gen_ai.usage.{input,output}_tokens` from `meta.billedUnits`, the same source
11
- * traceloop already uses for the `generate` endpoint — bringing Node chat tokens
12
- * to parity with the Python SDK (OpenLLMetry captures them natively, so there is
13
- * no Python counterpart).
14
- *
15
- * It hooks the internal `CohereClient.prototype.__chat` (which the public `chat`
16
- * delegates to synchronously) rather than the public `chat`: traceloop wraps
17
- * `chat` and opens the span around it, so `__chat` runs while that span is the
18
- * active span — letting this complement enrich it regardless of patch order.
19
- */
20
-
21
- const { trace } = require('@opentelemetry/api');
22
-
23
- function _billedUnits(result) {
24
- // Public `chat` resolves to the response body, but `__chat` resolves to the
25
- // Fern wrapper `{ data, rawResponse }`; read billedUnits off either shape.
26
- const response = result && result.data ? result.data : result;
27
- return response && response.meta ? response.meta.billedUnits : undefined;
28
- }
29
-
30
- function _setChatTokenUsage(span, result) {
31
- const billedUnits = _billedUnits(result);
32
- if (!billedUnits) return;
33
- if (typeof billedUnits.inputTokens === 'number') {
34
- span.setAttribute('gen_ai.usage.input_tokens', billedUnits.inputTokens);
35
- }
36
- if (typeof billedUnits.outputTokens === 'number') {
37
- span.setAttribute('gen_ai.usage.output_tokens', billedUnits.outputTokens);
38
- }
39
- }
40
-
41
- class CohereChatTokenUsageInstrumentor {
42
- constructor() {
43
- // [ownerPrototype, methodName, originalFunction] for uninstrument().
44
- this._patched = [];
45
- }
46
-
47
- instrument() {
48
- let CohereClient;
49
- try {
50
- ({ CohereClient } = require('cohere-ai/Client'));
51
- } catch (err) {
52
- throw new Error(
53
- 'weflayr.autoInstrument(COHERE): the cohere-ai client is not installed. ' +
54
- 'Install it with: npm install cohere-ai\n' +
55
- `Underlying error: ${err.message}`
56
- );
57
- }
58
-
59
- this._wrap(CohereClient.prototype, '__chat');
60
- }
61
-
62
- uninstrument() {
63
- for (const [owner, methodName, original] of this._patched) {
64
- owner[methodName] = original;
65
- }
66
- this._patched = [];
67
- }
68
-
69
- _wrap(owner, methodName) {
70
- const original = owner[methodName];
71
-
72
- function wrapper(...args) {
73
- // Captured synchronously, while traceloop's chat span is still active.
74
- const span = trace.getActiveSpan();
75
- const result = original.apply(this, args);
76
- if (!span || !span.isRecording || !span.isRecording()) return result;
77
- return Promise.resolve(result).then((response) => {
78
- _setChatTokenUsage(span, response);
79
- return response;
80
- });
81
- }
82
-
83
- owner[methodName] = wrapper;
84
- this._patched.push([owner, methodName, original]);
85
- }
86
- }
87
-
88
- module.exports = { CohereChatTokenUsageInstrumentor };
@@ -1,107 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Hand-written OTel instrumentor for the Cohere embeddings endpoint.
5
- *
6
- * `@traceloop/instrumentation-cohere` (the package weflayr uses for Cohere on
7
- * Node) wraps chat/generate/rerank but not `embed`, so this ships inside weflayr
8
- * to cover it. OpenLLMetry's cohere instrumentor doesn't cover `embed` either, so
9
- * the Python SDK has a mirror complement (`cohere_embeddings.py`) shaped to
10
- * normalize identically. It is registered alongside the traceloop instrumentor
11
- * whenever `autoInstrument({ aiSdks: 'cohere' })` runs.
12
- *
13
- * Embeddings are billed per input token, so the span records the input tokens
14
- * Cohere returns under `gen_ai.usage.input_tokens`; there is no completion.
15
- */
16
-
17
- const { trace, SpanStatusCode } = require('@opentelemetry/api');
18
-
19
- const TRACER_NAME = 'weflayr.instrumentation.cohere_embeddings';
20
- // Matches the gen_ai.system the cohere chat instrumentors set (Python + Node).
21
- const SYSTEM = 'Cohere';
22
- const EMBEDDINGS_OPERATION = 'embeddings';
23
-
24
- function _recordError(span, error) {
25
- span.setStatus({ code: SpanStatusCode.ERROR, message: error?.message ?? String(error) });
26
- span.recordException(error);
27
- }
28
-
29
- function _wrapEmbed(owner, patched) {
30
- const original = owner.embed;
31
-
32
- function wrapper(request, ...rest) {
33
- const span = trace.getTracer(TRACER_NAME).startSpan(EMBEDDINGS_OPERATION);
34
- span.setAttribute('gen_ai.system', SYSTEM);
35
- span.setAttribute('gen_ai.operation.name', EMBEDDINGS_OPERATION);
36
- if (request && request.model) {
37
- span.setAttribute('gen_ai.request.model', request.model);
38
- }
39
- // The embedded texts are the prompt; stamp one user message per text, like
40
- // the chat path. The span processor strips it when content capture is off.
41
- if (request && Array.isArray(request.texts) && request.texts.length) {
42
- span.setAttribute(
43
- 'gen_ai.input.messages',
44
- JSON.stringify(
45
- request.texts.map((text) => ({ role: 'user', parts: [{ type: 'text', content: text }] }))
46
- )
47
- );
48
- }
49
- return Promise.resolve(original.call(this, request, ...rest)).then(
50
- (response) => {
51
- // Node SDK reports the billed input tokens under camelCase keys.
52
- const inputTokens =
53
- response?.meta?.billedUnits?.inputTokens ?? response?.meta?.tokens?.inputTokens;
54
- if (inputTokens != null) {
55
- span.setAttribute('gen_ai.usage.input_tokens', inputTokens);
56
- }
57
- span.end();
58
- return response;
59
- },
60
- (error) => {
61
- _recordError(span, error);
62
- span.end();
63
- throw error;
64
- }
65
- );
66
- }
67
-
68
- owner.embed = wrapper;
69
- patched.push([owner, 'embed', original]);
70
- }
71
-
72
- class CohereEmbeddingsInstrumentor {
73
- constructor() {
74
- // [ownerPrototype, methodName, originalFunction] for uninstrument().
75
- this._patched = [];
76
- }
77
-
78
- instrument() {
79
- let CohereClient;
80
- let V2Client;
81
- try {
82
- // v1 `embed` is a prototype method on CohereClient; v2 `embed` lives on
83
- // V2Client.prototype (CohereClientV2 binds it as an instance property, so
84
- // it must be patched on the underlying V2Client class instead).
85
- ({ CohereClient } = require('cohere-ai/Client'));
86
- ({ V2Client } = require('cohere-ai/api/resources/v2/client/Client'));
87
- } catch (err) {
88
- throw new Error(
89
- 'weflayr.autoInstrument(COHERE): the cohere-ai client is not installed. ' +
90
- 'Install it with: npm install cohere-ai\n' +
91
- `Underlying error: ${err.message}`
92
- );
93
- }
94
-
95
- _wrapEmbed(CohereClient.prototype, this._patched);
96
- _wrapEmbed(V2Client.prototype, this._patched);
97
- }
98
-
99
- uninstrument() {
100
- for (const [owner, methodName, original] of this._patched) {
101
- owner[methodName] = original;
102
- }
103
- this._patched = [];
104
- }
105
- }
106
-
107
- module.exports = { CohereEmbeddingsInstrumentor };
@@ -1,32 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Cohere telemetry complement — the registered orchestrator.
5
- *
6
- * Wires the weflayr-supplied patches the traceloop Cohere instrumentor misses:
7
- * - chat token usage (traceloop reads the obsolete usage shape and records
8
- * zero chat tokens), and
9
- * - the embeddings endpoint it doesn't cover.
10
- */
11
-
12
- const { CohereChatTokenUsageInstrumentor } = require('./get_chat_telemetry');
13
- const { CohereEmbeddingsInstrumentor } = require('./get_embeddings_telemetry');
14
-
15
- class CohereTelemetryInstrumentor {
16
- constructor() {
17
- this._subInstrumentors = [
18
- new CohereChatTokenUsageInstrumentor(),
19
- new CohereEmbeddingsInstrumentor(),
20
- ];
21
- }
22
-
23
- instrument(instrumentation) {
24
- for (const sub of this._subInstrumentors) sub.instrument(instrumentation);
25
- }
26
-
27
- uninstrument() {
28
- for (const sub of this._subInstrumentors) sub.uninstrument();
29
- }
30
- }
31
-
32
- module.exports = { CohereTelemetryInstrumentor };
@@ -1,236 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Hand-written OTel instrumentor for the ElevenLabs audio clients.
5
- *
6
- * No official OpenTelemetry instrumentor exists for the ElevenLabs SDK (it's
7
- * audio, not an LLM), so this ships inside weflayr. It wraps the Text-to-Speech
8
- * and Speech-to-Text entrypoints to emit one `gen_ai.*` span per call, which
9
- * flows through the standard span processor -> exporter with no new transport code.
10
- *
11
- * The billable unit differs by API, so each span records the one ElevenLabs bills:
12
- * - Text-to-Speech is billed per input character -> `gen_ai.usage.input_characters`.
13
- * - Speech-to-Text is billed per second of audio -> `gen_ai.usage.input_seconds`.
14
- *
15
- * Entrypoints come in three result shapes, independent of which API they belong to:
16
- * - *byte stream* methods resolve to a `ReadableStream` of audio chunks;
17
- * - *object stream* methods resolve to an async-iterable of chunk objects;
18
- * - *unary* methods resolve to the full response.
19
- * The HTTP request -- plus any error -- only happens while a stream is awaited
20
- * and consumed, so the span is started eagerly (to capture the
21
- * `propagateMetadata` context active at the call site) and ended once the result
22
- * is exhausted (streams) or returned (unary), giving an `elapsed_ms` that covers
23
- * the whole call. The per-second billable unit is read off the STT response.
24
- */
25
-
26
- const { trace, SpanStatusCode } = require('@opentelemetry/api');
27
-
28
- const TRACER_NAME = 'weflayr.instrumentation.elevenlabs';
29
- const SYSTEM = 'elevenlabs';
30
- const TTS_OPERATION = 'text_to_speech';
31
- const STT_OPERATION = 'speech_to_text';
32
-
33
- function _startSpan(operation, request) {
34
- const span = trace.getTracer(TRACER_NAME).startSpan(operation);
35
- span.setAttribute('gen_ai.system', SYSTEM);
36
- span.setAttribute('gen_ai.operation.name', operation);
37
- // `modelId` lives on the request body passed to every audio entrypoint.
38
- const modelId = request && request.modelId;
39
- if (modelId) {
40
- span.setAttribute('gen_ai.request.model', modelId);
41
- }
42
- return span;
43
- }
44
-
45
- function _setInputCharacters(span, request) {
46
- // `text` lives on the request body of every TTS entrypoint; the billable unit
47
- // is its length.
48
- span.setAttribute('gen_ai.usage.input_characters', ((request && request.text) || '').length);
49
- }
50
-
51
- function _setAudioDuration(span, response) {
52
- // The transcription response exposes the transcribed audio length in seconds.
53
- const durationSecs = response && response.audioDurationSecs;
54
- if (durationSecs != null) {
55
- span.setAttribute('gen_ai.usage.input_seconds', durationSecs);
56
- }
57
- }
58
-
59
- function _recordError(span, error) {
60
- span.setStatus({ code: SpanStatusCode.ERROR, message: error?.message ?? String(error) });
61
- span.recordException(error);
62
- }
63
-
64
- // Proxy a `ReadableStream` of audio bytes so the span ends -- and any error is
65
- // recorded -- once the whole stream has been consumed (or the consumer cancels).
66
- // The span ends exactly once across every exit path.
67
- function _consumeByteStream(span, responsePromise) {
68
- let ended = false;
69
- const end = () => {
70
- if (ended) return;
71
- ended = true;
72
- span.end();
73
- };
74
-
75
- return responsePromise.then(
76
- (audioStream) => {
77
- const reader = audioStream.getReader();
78
- return new ReadableStream({
79
- async pull(controller) {
80
- try {
81
- const { done, value } = await reader.read();
82
- if (done) {
83
- end();
84
- controller.close();
85
- return;
86
- }
87
- controller.enqueue(value);
88
- } catch (error) {
89
- _recordError(span, error);
90
- end();
91
- controller.error(error);
92
- }
93
- },
94
- cancel(reason) {
95
- end();
96
- return reader.cancel(reason);
97
- },
98
- });
99
- },
100
- (error) => {
101
- _recordError(span, error);
102
- end();
103
- throw error;
104
- }
105
- );
106
- }
107
-
108
- // Proxy an async-iterable of chunk objects (the streaming "with timestamps"
109
- // variant) so the span ends once iteration completes.
110
- function _consumeObjectStream(span, responsePromise) {
111
- async function* iterate(stream) {
112
- try {
113
- for await (const chunk of stream) {
114
- yield chunk;
115
- }
116
- } catch (error) {
117
- _recordError(span, error);
118
- throw error;
119
- } finally {
120
- span.end();
121
- }
122
- }
123
-
124
- return responsePromise.then(
125
- (stream) => iterate(stream),
126
- (error) => {
127
- _recordError(span, error);
128
- span.end();
129
- throw error;
130
- }
131
- );
132
- }
133
-
134
- // Wrap a request/response entrypoint: the span spans the single call, and any
135
- // response-derived billable unit is read off the result.
136
- function _consumeUnary(span, responsePromise, setResponseAttributes) {
137
- return responsePromise.then(
138
- (response) => {
139
- if (setResponseAttributes) {
140
- setResponseAttributes(span, response);
141
- }
142
- span.end();
143
- return response;
144
- },
145
- (error) => {
146
- _recordError(span, error);
147
- span.end();
148
- throw error;
149
- }
150
- );
151
- }
152
-
153
- class ElevenLabsInstrumentor {
154
- constructor() {
155
- // [ownerPrototype, methodName, originalFunction] for uninstrument().
156
- this._patched = [];
157
- }
158
-
159
- instrument() {
160
- let TextToSpeechClient;
161
- let SpeechToTextClient;
162
- try {
163
- ({
164
- TextToSpeechClient,
165
- } = require('@elevenlabs/elevenlabs-js/api/resources/textToSpeech/client/Client'));
166
- ({
167
- SpeechToTextClient,
168
- } = require('@elevenlabs/elevenlabs-js/api/resources/speechToText/client/Client'));
169
- } catch (err) {
170
- throw new Error(
171
- 'weflayr.autoInstrument(ELEVENLABS): the @elevenlabs/elevenlabs-js client is not ' +
172
- 'installed. Install it with: npm install @elevenlabs/elevenlabs-js\n' +
173
- `Underlying error: ${err.message}`
174
- );
175
- }
176
-
177
- // TTS — request body is the 2nd arg (after voice_id); billed per character.
178
- this._wrap(TextToSpeechClient.prototype, 'convert', {
179
- operation: TTS_OPERATION,
180
- requestArgIndex: 1,
181
- setRequestAttributes: _setInputCharacters,
182
- consume: _consumeByteStream,
183
- });
184
- this._wrap(TextToSpeechClient.prototype, 'stream', {
185
- operation: TTS_OPERATION,
186
- requestArgIndex: 1,
187
- setRequestAttributes: _setInputCharacters,
188
- consume: _consumeByteStream,
189
- });
190
- this._wrap(TextToSpeechClient.prototype, 'streamWithTimestamps', {
191
- operation: TTS_OPERATION,
192
- requestArgIndex: 1,
193
- setRequestAttributes: _setInputCharacters,
194
- consume: _consumeObjectStream,
195
- });
196
- this._wrap(TextToSpeechClient.prototype, 'convertWithTimestamps', {
197
- operation: TTS_OPERATION,
198
- requestArgIndex: 1,
199
- setRequestAttributes: _setInputCharacters,
200
- consume: (span, responsePromise) => _consumeUnary(span, responsePromise, null),
201
- });
202
-
203
- // STT — request body is the 1st arg; billed per second of audio.
204
- this._wrap(SpeechToTextClient.prototype, 'convert', {
205
- operation: STT_OPERATION,
206
- requestArgIndex: 0,
207
- setRequestAttributes: null,
208
- consume: (span, responsePromise) => _consumeUnary(span, responsePromise, _setAudioDuration),
209
- });
210
- }
211
-
212
- uninstrument() {
213
- for (const [owner, methodName, original] of this._patched) {
214
- owner[methodName] = original;
215
- }
216
- this._patched = [];
217
- }
218
-
219
- _wrap(owner, methodName, { operation, requestArgIndex, setRequestAttributes, consume }) {
220
- const original = owner[methodName];
221
-
222
- function wrapper(...args) {
223
- const request = args[requestArgIndex];
224
- const span = _startSpan(operation, request);
225
- if (setRequestAttributes) {
226
- setRequestAttributes(span, request);
227
- }
228
- return consume(span, original.apply(this, args));
229
- }
230
-
231
- owner[methodName] = wrapper;
232
- this._patched.push([owner, methodName, original]);
233
- }
234
- }
235
-
236
- module.exports = { ElevenLabsInstrumentor };