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.
Files changed (234) hide show
  1. package/README.md +2 -2
  2. package/dist/{api → src/api}/generated/facade.gen.d.ts +86 -12
  3. package/dist/{api → src/api}/generated/facade.gen.js +4 -2
  4. package/dist/src/api/generated/index.d.ts +2 -0
  5. package/dist/{api → src/api}/generated/index.js +3 -1
  6. package/dist/{api → src/api}/generated/sdk.gen.d.ts +11 -3
  7. package/dist/{api → src/api}/generated/sdk.gen.js +34 -4
  8. package/{src/api/generated/types.gen.ts → dist/src/api/generated/types.gen.d.ts} +436 -153
  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/{src → dist/src}/instrumentation/google/get_cache_telemetry.js +18 -19
  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 -1005
  119. package/eslint.config.mjs +0 -36
  120. package/index.d.ts +0 -170
  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 -104
  138. package/src/api/generated/index.ts +0 -4
  139. package/src/api/generated/sdk.gen.ts +0 -175
  140. package/src/api/index.ts +0 -45
  141. package/src/api/makeEndpoint.ts +0 -54
  142. package/src/auto-instrument.js +0 -172
  143. package/src/index.js +0 -19
  144. package/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +0 -118
  145. package/src/instrumentation/anthropic/get_cache_config_telemetry.js +0 -90
  146. package/src/instrumentation/anthropic/get_streaming_stop_reason_telemetry.js +0 -121
  147. package/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +0 -55
  148. package/src/instrumentation/anthropic/set_telemetry_attributes.js +0 -39
  149. package/src/instrumentation/bedrock/get_cache_config_telemetry.js +0 -106
  150. package/src/instrumentation/bedrock/get_cache_telemetry.js +0 -109
  151. package/src/instrumentation/bedrock/get_input_message_content_telemetry.js +0 -94
  152. package/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +0 -87
  153. package/src/instrumentation/bedrock/set_telemetry_attributes.js +0 -40
  154. package/src/instrumentation/cohere/get_chat_telemetry.js +0 -88
  155. package/src/instrumentation/cohere/get_embeddings_telemetry.js +0 -107
  156. package/src/instrumentation/cohere/set_telemetry_attributes.js +0 -32
  157. package/src/instrumentation/elevenlabs/full_instrumentation.js +0 -236
  158. package/src/instrumentation/google/get_audio_telemetry.js +0 -30
  159. package/src/instrumentation/google/get_cache_operations_telemetry.js +0 -171
  160. package/src/instrumentation/google/get_embeddings_telemetry.js +0 -99
  161. package/src/instrumentation/google/set_telemetry_attributes.js +0 -104
  162. package/src/instrumentation/openai/get_audio_telemetry.js +0 -149
  163. package/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +0 -71
  164. package/src/instrumentation/openai/get_cache_config_telemetry.js +0 -63
  165. package/src/instrumentation/openai/get_embeddings_telemetry.js +0 -107
  166. package/src/instrumentation/openai/get_streaming_usage.js +0 -81
  167. package/src/instrumentation/openai/set_telemetry_attributes.js +0 -41
  168. package/src/instrumentation/vercel/full_instrumentation.js +0 -52
  169. package/src/instrumentation/vercel/get_cache_creation_telemetry.js +0 -70
  170. package/src/logger.js +0 -8
  171. package/src/otel/exporter.js +0 -108
  172. package/src/otel/propagation.js +0 -146
  173. package/src/otel/span-filter.js +0 -69
  174. package/src/otel/span-processor.js +0 -170
  175. package/src/otel/vercel-ai-sdk-span-filter.js +0 -79
  176. package/src/setup.js +0 -167
  177. package/tests/api/index.test.js +0 -437
  178. package/tests/index.test.js +0 -884
  179. package/tests/instrumentation/anthropic/get_cache_and_reasoning_telemetry.test.js +0 -181
  180. package/tests/instrumentation/anthropic/get_cache_config_telemetry.test.js +0 -92
  181. package/tests/instrumentation/anthropic/get_streaming_stop_reason_telemetry.test.js +0 -117
  182. package/tests/instrumentation/anthropic/get_tool_definitions_telemetry.test.js +0 -97
  183. package/tests/instrumentation/bedrock/get_cache_config_telemetry.test.js +0 -107
  184. package/tests/instrumentation/bedrock/get_cache_telemetry.test.js +0 -118
  185. package/tests/instrumentation/bedrock/get_input_message_content_telemetry.test.js +0 -89
  186. package/tests/instrumentation/bedrock/get_streaming_output_message_telemetry.test.js +0 -87
  187. package/tests/instrumentation/cohere/get_chat_telemetry.test.js +0 -148
  188. package/tests/instrumentation/cohere/get_embeddings_telemetry.test.js +0 -132
  189. package/tests/instrumentation/elevenlabs/full_instrumentation.test.js +0 -258
  190. package/tests/instrumentation/google/get_cache_operations_telemetry.test.js +0 -130
  191. package/tests/instrumentation/google/get_embeddings_telemetry.test.js +0 -128
  192. package/tests/instrumentation/google/get_reasoning_telemetry.test.js +0 -41
  193. package/tests/instrumentation/google/set_telemetry_attributes.test.js +0 -219
  194. package/tests/instrumentation/openai/get_audio_telemetry.test.js +0 -170
  195. package/tests/instrumentation/openai/get_cache_and_reasoning_telemetry.test.js +0 -83
  196. package/tests/instrumentation/openai/get_cache_config_telemetry.test.js +0 -83
  197. package/tests/instrumentation/openai/get_embeddings_telemetry.test.js +0 -145
  198. package/tests/instrumentation/openai/get_streaming_usage.test.js +0 -105
  199. package/tests/instrumentation/vercel/full_instrumentation.test.js +0 -16
  200. package/tests/instrumentation/vercel/get_cache_creation_telemetry.test.js +0 -96
  201. package/tests/otel/vercel-ai-sdk-span-filter.test.js +0 -159
  202. package/tsconfig.json +0 -18
  203. /package/dist/{api → src/api}/caseConversion.d.ts +0 -0
  204. /package/dist/{api → src/api}/caseConversion.js +0 -0
  205. /package/dist/{api → src/api}/generated/client/client.gen.d.ts +0 -0
  206. /package/dist/{api → src/api}/generated/client/client.gen.js +0 -0
  207. /package/dist/{api → src/api}/generated/client/index.d.ts +0 -0
  208. /package/dist/{api → src/api}/generated/client/index.js +0 -0
  209. /package/dist/{api → src/api}/generated/client/types.gen.d.ts +0 -0
  210. /package/dist/{api → src/api}/generated/client/types.gen.js +0 -0
  211. /package/dist/{api → src/api}/generated/client/utils.gen.d.ts +0 -0
  212. /package/dist/{api → src/api}/generated/client/utils.gen.js +0 -0
  213. /package/dist/{api → src/api}/generated/client.gen.d.ts +0 -0
  214. /package/dist/{api → src/api}/generated/client.gen.js +0 -0
  215. /package/dist/{api → src/api}/generated/core/auth.gen.d.ts +0 -0
  216. /package/dist/{api → src/api}/generated/core/auth.gen.js +0 -0
  217. /package/dist/{api → src/api}/generated/core/bodySerializer.gen.d.ts +0 -0
  218. /package/dist/{api → src/api}/generated/core/bodySerializer.gen.js +0 -0
  219. /package/dist/{api → src/api}/generated/core/params.gen.d.ts +0 -0
  220. /package/dist/{api → src/api}/generated/core/params.gen.js +0 -0
  221. /package/dist/{api → src/api}/generated/core/pathSerializer.gen.d.ts +0 -0
  222. /package/dist/{api → src/api}/generated/core/pathSerializer.gen.js +0 -0
  223. /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.d.ts +0 -0
  224. /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.js +0 -0
  225. /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.d.ts +0 -0
  226. /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.js +0 -0
  227. /package/dist/{api → src/api}/generated/core/types.gen.d.ts +0 -0
  228. /package/dist/{api → src/api}/generated/core/types.gen.js +0 -0
  229. /package/dist/{api → src/api}/generated/core/utils.gen.d.ts +0 -0
  230. /package/dist/{api → src/api}/generated/core/utils.gen.js +0 -0
  231. /package/dist/{api → src/api}/generated/types.gen.js +0 -0
  232. /package/dist/{api → src/api}/index.d.ts +0 -0
  233. /package/dist/{api → src/api}/index.js +0 -0
  234. /package/dist/{api → src/api}/makeEndpoint.d.ts +0 -0
@@ -1,108 +0,0 @@
1
- 'use strict';
2
-
3
- const retry = require('async-retry');
4
- const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
5
-
6
- const { debug } = require('../logger');
7
-
8
- // OTLP-spec retryable statuses: rate-limit + transient server errors.
9
- const _RETRYABLE_STATUS = new Set([429, 502, 503, 504]);
10
-
11
- function _isNonRetryable(err) {
12
- // Tells async-retry's `bail` whether to give up: bail on 4xx (other than
13
- // 429); retry on retryable statuses and on transport errors (no status).
14
- const status = err?.exportResult?.error?.code;
15
- return status !== undefined && !_RETRYABLE_STATUS.has(status);
16
- }
17
-
18
- function _formatFailure(result, url) {
19
- const err = result?.error;
20
- const status = err?.code;
21
- const body = typeof err?.data === 'string' ? err.data.slice(0, 200) : undefined;
22
- const message = err?.message || String(err) || 'unknown error';
23
- let hint = '';
24
- if (status === 401 || status === 403) {
25
- hint = ' Check your apiKey / WEFLAYR_API_KEY.';
26
- } else if (status === 404) {
27
- hint = ' Check the baseUrl is correct.';
28
- } else if (!status && /ECONN|ENOTFOUND|timeout/i.test(message)) {
29
- hint = ' The endpoint is unreachable — check baseUrl and network.';
30
- }
31
- return (
32
- `Weflayr: failed to export telemetry to ${url}` +
33
- (status ? ` (HTTP ${status})` : '') +
34
- `: ${message}.${hint}` +
35
- (body ? ` Response: ${body}` : '')
36
- );
37
- }
38
-
39
- // Wrap a callback-style OTel exporter `export(spans, cb)` with retry. Retries
40
- // transport errors + retryable HTTP statuses; bails on other 4xx.
41
- function _exportWithRetry(originalExport, { maxRetries, maxRetryMs }) {
42
- return (spans, resultCallback) => {
43
- retry(
44
- async (bail) => {
45
- const result = await new Promise((resolve) => originalExport(spans, resolve));
46
- if (result?.code === 0) return result;
47
- const err = new Error(result?.error?.message || 'export failed');
48
- err.exportResult = result;
49
- if (_isNonRetryable(err)) {
50
- bail(err);
51
- return;
52
- }
53
- throw err;
54
- },
55
- { retries: maxRetries - 1, minTimeout: 50, maxRetryTime: maxRetryMs, factor: 2 }
56
- )
57
- .then((result) => resultCallback(result))
58
- .catch((err) => resultCallback(err.exportResult || { code: 1, error: err }));
59
- };
60
- }
61
-
62
- function buildExporter({
63
- baseUrl,
64
- apiKey,
65
- timeoutMs = 5000,
66
- warnOnExportError = true,
67
- maxRetries = 2,
68
- maxRetryMs = 1000,
69
- }) {
70
- const url = `${baseUrl.replace(/\/$/, '')}/`;
71
- const exporter = new OTLPTraceExporter({
72
- url,
73
- headers: {
74
- Authorization: `Bearer ${apiKey}`,
75
- },
76
- timeoutMillis: timeoutMs,
77
- });
78
- const originalExport = exporter.export.bind(exporter);
79
- const wrappedExport = _exportWithRetry(originalExport, { maxRetries, maxRetryMs });
80
- exporter.export = (spans, resultCallback) => {
81
- const start = Date.now();
82
- debug('exporter.export: posting count=%d', spans.length);
83
- wrappedExport(spans, (result) => {
84
- const ms = Date.now() - start;
85
- if (result && result.code === 0) {
86
- debug('exporter.export: ok count=%d elapsed_ms=%d', spans.length, ms);
87
- } else {
88
- debug(
89
- 'exporter.export: FAIL count=%d elapsed_ms=%d code=%s error=%s',
90
- spans.length,
91
- ms,
92
- result?.code,
93
- result?.error?.message || result?.error || '(none)'
94
- );
95
- if (warnOnExportError) {
96
- // console.warn writes to stderr synchronously. process.emitWarning
97
- // is queued for the next tick, so a caller doing process.exit() from
98
- // their error handler races past it and the warning is lost.
99
- console.warn(`[weflayr] ${_formatFailure(result, url)}`);
100
- }
101
- }
102
- resultCallback(result);
103
- });
104
- };
105
- return exporter;
106
- }
107
-
108
- module.exports = { buildExporter, _exportWithRetry, _RETRYABLE_STATUS };
@@ -1,146 +0,0 @@
1
- // Copyright 2024 Langfuse GmbH
2
- // Licensed under the MIT License.
3
- // Original source: https://github.com/langfuse/langfuse-js/blob/main/packages/core/src/propagation.ts
4
- //
5
- // Modifications copyright 2026 Weflayr
6
- // This file has been modified from its original form:
7
- // - Translated from TypeScript to JavaScript
8
- // - Replaced Langfuse's fixed schema with Weflayr's structured metadata
9
- // (featureName, customerName, providerNameOverride, extraTags) plus an
10
- // auto-generated per-call uuid
11
- // - Removed asBaggage cross-process propagation (not needed yet)
12
- // - Removed experiment framework keys
13
- // - Structured fields are written under stable `weflayr.*` span attribute
14
- // keys; extraTags entries are written verbatim
15
- //
16
- // See LICENSE-MIT in the package root for the full license text.
17
-
18
- 'use strict';
19
-
20
- const { randomUUID } = require('node:crypto');
21
- const { context: otelContext, trace, createContextKey } = require('@opentelemetry/api');
22
-
23
- const WEFLAYR_METADATA_CONTEXT_KEY = createContextKey('weflayr_metadata');
24
-
25
- const FEATURE_NAME_ATTR = 'weflayr.feature_name';
26
- const CUSTOMER_NAME_ATTR = 'weflayr.customer_name';
27
- const PROVIDER_NAME_ATTR = 'weflayr.provider_name';
28
- const UUID_ATTR = 'weflayr.uuid';
29
- // Prefix for user-supplied `extraTags` so downstream normalizers can pick
30
- // them out without colliding with instrumentor-set `gen_ai.*` attributes.
31
- const EXTRA_TAG_PREFIX = 'weflayr.tag.';
32
-
33
- function getMergedMetadataFromContext(parentContext) {
34
- const ctx = parentContext ?? otelContext.active();
35
- const existing = ctx.getValue(WEFLAYR_METADATA_CONTEXT_KEY);
36
- return existing && typeof existing === 'object' ? { ...existing } : {};
37
- }
38
-
39
- function _buildAttributes({
40
- featureName,
41
- customerName,
42
- providerNameOverride,
43
- extraTags,
44
- spanUuid,
45
- }) {
46
- const attributes = {
47
- [FEATURE_NAME_ATTR]: featureName,
48
- [CUSTOMER_NAME_ATTR]: customerName,
49
- [UUID_ATTR]: spanUuid,
50
- };
51
- for (const [key, value] of Object.entries(extraTags)) {
52
- attributes[`${EXTRA_TAG_PREFIX}${key}`] = value;
53
- }
54
- if (providerNameOverride !== undefined && providerNameOverride !== null) {
55
- attributes[PROVIDER_NAME_ATTR] = providerNameOverride;
56
- }
57
- return attributes;
58
- }
59
-
60
- /**
61
- * Attach Weflayr metadata to every LLM span created inside this scope.
62
- *
63
- * Callable form: `propagateMetadata(options, fn)` runs `fn` immediately.
64
- * Decorator form: `propagateMetadata(options)` returns a wrapper usable as a
65
- * function-decorator (`@propagateMetadata(...)` on class methods) or as a
66
- * plain `wrap(fn)` -> wrappedFn helper. Each invocation of the wrapped
67
- * function mints a fresh `uuid`, matching the callable form's "one uuid per
68
- * propagateMetadata call" contract.
69
- */
70
- function propagateMetadata(options, fn) {
71
- const { featureName, customerId, providerName } = options ?? {};
72
- let { customerName, providerNameOverride } = options ?? {};
73
- if (customerId != null) {
74
- process.emitWarning(
75
- 'propagateMetadata: `customerId` is deprecated, use `customerName`',
76
- 'DeprecationWarning'
77
- );
78
- customerName = customerName ?? customerId;
79
- }
80
- if (providerName != null) {
81
- process.emitWarning(
82
- 'propagateMetadata: `providerName` is deprecated, use `providerNameOverride`',
83
- 'DeprecationWarning'
84
- );
85
- providerNameOverride = providerNameOverride ?? providerName;
86
- }
87
- if (featureName == null || customerName == null) {
88
- throw new Error('propagateMetadata: `featureName` and `customerName` are required');
89
- }
90
- const normalizedOptions = { ...options, customerName, providerNameOverride };
91
-
92
- if (typeof fn === 'function') {
93
- return _runWithMetadata(normalizedOptions, fn);
94
- }
95
-
96
- return function decorator(target, key, descriptor) {
97
- if (descriptor && typeof descriptor.value === 'function') {
98
- const original = descriptor.value;
99
- descriptor.value = function wrapped(...args) {
100
- return _runWithMetadata(normalizedOptions, () => original.apply(this, args));
101
- };
102
- return descriptor;
103
- }
104
- if (typeof target === 'function') {
105
- return function wrapped(...args) {
106
- return _runWithMetadata(normalizedOptions, () => target.apply(this, args));
107
- };
108
- }
109
- return target;
110
- };
111
- }
112
-
113
- function _runWithMetadata(options, fn) {
114
- const { featureName, customerName, providerNameOverride, extraTags } = options;
115
- const attributes = _buildAttributes({
116
- featureName,
117
- customerName,
118
- providerNameOverride,
119
- extraTags: extraTags ?? {},
120
- spanUuid: randomUUID().replace(/-/g, ''),
121
- });
122
-
123
- const parent = otelContext.active();
124
- const merged = { ...getMergedMetadataFromContext(parent), ...attributes };
125
- const newContext = parent.setValue(WEFLAYR_METADATA_CONTEXT_KEY, merged);
126
-
127
- const activeSpan = trace.getActiveSpan();
128
- if (activeSpan && activeSpan.isRecording && activeSpan.isRecording()) {
129
- for (const [k, v] of Object.entries(attributes)) {
130
- activeSpan.setAttribute(k, v);
131
- }
132
- }
133
-
134
- return otelContext.with(newContext, fn);
135
- }
136
-
137
- module.exports = {
138
- propagateMetadata,
139
- getMergedMetadataFromContext,
140
- WEFLAYR_METADATA_CONTEXT_KEY,
141
- FEATURE_NAME_ATTR,
142
- CUSTOMER_NAME_ATTR,
143
- PROVIDER_NAME_ATTR,
144
- UUID_ATTR,
145
- EXTRA_TAG_PREFIX,
146
- };
@@ -1,69 +0,0 @@
1
- // Copyright 2024 Langfuse GmbH
2
- // Licensed under the MIT License.
3
- // Original source: https://github.com/langfuse/langfuse-js/blob/main/packages/otel/src/span-filter.ts
4
- //
5
- // Modifications copyright 2026 Weflayr
6
- // This file has been modified from its original form:
7
- // - Translated from TypeScript to JavaScript
8
- // - Dropped the LANGFUSE_TRACER_NAME special case (we have no SDK-internal tracer)
9
- // - Dropped isLangfuseSpan
10
- // - Export only spans from known LLM instrumentation scopes: general-purpose
11
- // APM SDKs (Sentry, Datadog, ...) also instrument LLM calls with gen_ai.*
12
- // attributes, so the original "any span with gen_ai.* attributes" check
13
- // exported the same call twice
14
- //
15
- // See LICENSE-MIT in the package root for the full license text.
16
-
17
- 'use strict';
18
-
19
- const KNOWN_LLM_INSTRUMENTATION_SCOPE_PREFIXES = [
20
- 'agent_framework',
21
- 'ai',
22
- 'gen_ai',
23
- 'haystack',
24
- 'langsmith',
25
- 'litellm',
26
- 'mistralai_sdk_tracer',
27
- 'openinference',
28
- 'opentelemetry.instrumentation.anthropic',
29
- 'opentelemetry.instrumentation.aws_bedrock',
30
- 'opentelemetry.instrumentation.bedrock',
31
- 'opentelemetry.instrumentation.cohere',
32
- 'opentelemetry.instrumentation.gemini',
33
- 'opentelemetry.instrumentation.google_genai',
34
- 'opentelemetry.instrumentation.google_generativeai',
35
- 'opentelemetry.instrumentation.openai',
36
- 'opentelemetry.instrumentation.openai_v2',
37
- 'opentelemetry.instrumentation.vertex_ai',
38
- 'opentelemetry.instrumentation.vertexai',
39
- 'weflayr.instrumentation',
40
- 'strands-agents',
41
- 'vllm',
42
- '@traceloop/instrumentation-openai',
43
- '@traceloop/instrumentation-anthropic',
44
- '@traceloop/instrumentation-bedrock',
45
- '@traceloop/instrumentation-cohere',
46
- '@traceloop/instrumentation-google-generativeai',
47
- '@traceloop/instrumentation-langchain',
48
- '@traceloop/instrumentation-llamaindex',
49
- '@traceloop/instrumentation-pinecone',
50
- '@traceloop/instrumentation-chromadb',
51
- '@traceloop/instrumentation-qdrant',
52
- '@traceloop/instrumentation-mcp',
53
- ];
54
-
55
- function isKnownLLMInstrumentor(span) {
56
- const scope = span.instrumentationScope.name;
57
- return KNOWN_LLM_INSTRUMENTATION_SCOPE_PREFIXES.some(
58
- (prefix) => scope === prefix || scope.startsWith(`${prefix}.`)
59
- );
60
- }
61
-
62
- function isDefaultExportSpan(span) {
63
- return isKnownLLMInstrumentor(span);
64
- }
65
-
66
- module.exports = {
67
- isKnownLLMInstrumentor,
68
- isDefaultExportSpan,
69
- };
@@ -1,170 +0,0 @@
1
- // Copyright 2024 Langfuse GmbH
2
- // Licensed under the MIT License.
3
- // Original source: https://github.com/langfuse/langfuse-js/blob/main/packages/otel/src/span-processor.ts
4
- //
5
- // Modifications copyright 2026 Weflayr
6
- // This file has been modified from its original form:
7
- // - Translated from TypeScript to JavaScript
8
- // - Removed MediaService integration (no media upload support yet)
9
- // - Removed LangfuseAPIClient / app-root marker logic (not used)
10
- // - Removed Langfuse-specific span attributes (TRACE_INPUT/OUTPUT/METADATA, IS_APP_ROOT, ENVIRONMENT, RELEASE)
11
- // - Mask hook now receives the full flat attribute bag, not a {data} envelope, and runs synchronously
12
- // - default_tags are applied as span attributes in onStart
13
- // - propagated tags come from Weflayr's tag bag (see propagation.js), not Langfuse's typed schema
14
- //
15
- // See LICENSE-MIT in the package root for the full license text.
16
-
17
- 'use strict';
18
-
19
- const { SpanStatusCode } = require('@opentelemetry/api');
20
- const { BatchSpanProcessor, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
21
- const { EXTRA_TAG_PREFIX, getMergedMetadataFromContext } = require('./propagation');
22
- const { isDefaultExportSpan, isKnownLLMInstrumentor } = require('./span-filter');
23
- const {
24
- VercelAiSdkSpanFilter,
25
- stampVercelGatewayProviderName,
26
- } = require('./vercel-ai-sdk-span-filter');
27
- const { debug } = require('../logger');
28
-
29
- // setup({captureMessageContent: ...}) records the choice in this env var (the
30
- // official OTel GenAI one). Instrumentors gate content on their own knobs
31
- // (openllmetry reads its own config and captures by default), so the processor
32
- // enforces the flag itself: when the env var is "false", message content is
33
- // stripped from every span before export.
34
- const CONTENT_CAPTURE_ENV = 'OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT';
35
-
36
- // The new-semconv JSON message attributes and the legacy indexed
37
- // `gen_ai.prompt.{i}.*` / `gen_ai.completion.{i}.*` attributes.
38
- const CONTENT_ATTRIBUTES = [
39
- 'gen_ai.input.messages',
40
- 'gen_ai.output.messages',
41
- 'gen_ai.system_instructions',
42
- ];
43
- const CONTENT_ATTRIBUTE_PREFIXES = ['gen_ai.prompt.', 'gen_ai.completion.'];
44
-
45
- function _isContentAttribute(key) {
46
- return (
47
- CONTENT_ATTRIBUTES.includes(key) ||
48
- CONTENT_ATTRIBUTE_PREFIXES.some((prefix) => key.startsWith(prefix))
49
- );
50
- }
51
-
52
- // Stamped on every exported span when a `mask` is configured: the mask
53
- // function's source code, so the stored raw event shows what redaction ran
54
- // client-side when debugging missing attributes.
55
- const MASK_FUNCTION_ATTRIBUTE = 'weflayr.mask_function';
56
-
57
- class WeflayrSpanProcessor {
58
- constructor({ exporter, exportMode = 'batch', defaultTags = {}, mask, shouldExportSpan } = {}) {
59
- if (!exporter) {
60
- throw new Error('WeflayrSpanProcessor: exporter is required');
61
- }
62
- this._delegate =
63
- exportMode === 'immediate'
64
- ? new SimpleSpanProcessor(exporter)
65
- : new BatchSpanProcessor(exporter);
66
- this._defaultTags = defaultTags;
67
- this._mask = mask;
68
- this._maskFunctionSource = mask ? String(mask) : null;
69
- this._shouldExportSpan = shouldExportSpan ?? isDefaultExportSpan;
70
- this._vercelAiSdkSpanFilter = new VercelAiSdkSpanFilter();
71
- // LLM spans we've started but not yet seen end. On forceFlush we end any
72
- // leftovers with ERROR status — covers cases like openllmetry's anthropic
73
- // streaming wrapper, which leaks the span when the underlying call
74
- // rejects. Generic across providers; no per-provider patching needed.
75
- this._openLlmSpans = new Set();
76
- }
77
-
78
- onStart(span, parentContext) {
79
- for (const [k, v] of Object.entries(this._defaultTags)) {
80
- span.setAttribute(`${EXTRA_TAG_PREFIX}${k}`, v);
81
- }
82
- const propagated = getMergedMetadataFromContext(parentContext);
83
- for (const [k, v] of Object.entries(propagated)) {
84
- span.setAttribute(k, v);
85
- }
86
- if (isKnownLLMInstrumentor(span)) {
87
- this._openLlmSpans.add(span);
88
- }
89
- this._vercelAiSdkSpanFilter.onStart(span);
90
- debug(
91
- 'span start: name=%s defaultTags=%d propagatedMetadata=%d',
92
- span.name,
93
- Object.keys(this._defaultTags).length,
94
- Object.keys(propagated).length
95
- );
96
- return this._delegate.onStart(span, parentContext);
97
- }
98
-
99
- onEnd(span) {
100
- this._openLlmSpans.delete(span);
101
- try {
102
- const vercelVerdict = this._vercelAiSdkSpanFilter.shouldExport(span);
103
- if (vercelVerdict === true) {
104
- stampVercelGatewayProviderName(span);
105
- }
106
- if (vercelVerdict === false || (vercelVerdict === null && !this._shouldExportSpan(span))) {
107
- debug(
108
- 'span end: filtered out name=%s scope=%s',
109
- span.name,
110
- span.instrumentationScope?.name
111
- );
112
- return;
113
- }
114
- } catch {
115
- return;
116
- }
117
- debug('span end: exporting name=%s scope=%s', span.name, span.instrumentationScope?.name);
118
-
119
- if ((process.env[CONTENT_CAPTURE_ENV] || '').toLowerCase() === 'false') {
120
- for (const key of Object.keys(span.attributes)) {
121
- if (_isContentAttribute(key)) delete span.attributes[key];
122
- }
123
- }
124
-
125
- if (this._mask) {
126
- try {
127
- const masked = this._mask(span.attributes);
128
- if (masked && masked !== span.attributes) {
129
- for (const k of Object.keys(span.attributes)) delete span.attributes[k];
130
- Object.assign(span.attributes, masked);
131
- }
132
- } catch {
133
- for (const k of Object.keys(span.attributes)) delete span.attributes[k];
134
- }
135
- // Stamped after masking so the mask can't strip it.
136
- span.attributes[MASK_FUNCTION_ATTRIBUTE] = this._maskFunctionSource;
137
- }
138
-
139
- return this._delegate.onEnd(span);
140
- }
141
-
142
- async forceFlush() {
143
- this._endOrphanedLlmSpans();
144
- return this._delegate.forceFlush();
145
- }
146
-
147
- _endOrphanedLlmSpans() {
148
- const orphans = [...this._openLlmSpans];
149
- this._openLlmSpans.clear();
150
- for (const span of orphans) {
151
- try {
152
- if (typeof span.isRecording === 'function' && !span.isRecording()) continue;
153
- span.setStatus({
154
- code: SpanStatusCode.ERROR,
155
- message: 'weflayr: span did not complete before flush',
156
- });
157
- span.end();
158
- debug('forceFlush: ended orphaned LLM span name=%s', span.name);
159
- } catch (err) {
160
- debug('forceFlush: failed to end orphan span: %s', err?.message || err);
161
- }
162
- }
163
- }
164
-
165
- shutdown() {
166
- return this._delegate.shutdown();
167
- }
168
- }
169
-
170
- module.exports = { CONTENT_CAPTURE_ENV, WeflayrSpanProcessor };
@@ -1,79 +0,0 @@
1
- 'use strict';
2
-
3
- // The Vercel AI SDK's OTel integrations emit aggregate spans around each model
4
- // call, all repeating the same usage counts:
5
- // - `@ai-sdk/otel` (ai >= 7, scope "gen_ai"): per-call "chat" spans are
6
- // wrapped in "agent_step" + "invoke_agent" spans, and embed/embedMany
7
- // emits an outer "embeddings" operation span around the model-call
8
- // "embeddings" span(s).
9
- // - the legacy integration (ai <= 6, scope "ai"): `ai.<fn>.do<Call>` spans
10
- // are wrapped in an outer `ai.<fn>` span.
11
- // Exactly one span per model call may reach the exporter — exporting an
12
- // aggregate alongside its children would bill every call twice.
13
-
14
- const VERCEL_SEMCONV_SCOPE = 'gen_ai';
15
- const VERCEL_LEGACY_SCOPE = 'ai';
16
-
17
- const LEGACY_MODEL_CALL_SPAN_NAME = /\.do(Generate|Stream|Embed)$/;
18
-
19
- function _parentSpanId(span) {
20
- return span.parentSpanContext?.spanId ?? span.parentSpanId;
21
- }
22
-
23
- class VercelAiSdkSpanFilter {
24
- constructor() {
25
- // spanId -> gen_ai.operation.name for open "gen_ai"-scope spans, so a
26
- // span can check what its parent is (children end before their parent).
27
- this._openSpanOperations = new Map();
28
- }
29
-
30
- onStart(span) {
31
- if (span.instrumentationScope?.name !== VERCEL_SEMCONV_SCOPE) return;
32
- this._openSpanOperations.set(
33
- span.spanContext().spanId,
34
- span.attributes['gen_ai.operation.name']
35
- );
36
- }
37
-
38
- /**
39
- * Export verdict for a Vercel AI SDK span, or null when the span is not
40
- * one (the caller falls back to the default filter).
41
- */
42
- shouldExport(span) {
43
- const scope = span.instrumentationScope?.name;
44
- if (scope === VERCEL_LEGACY_SCOPE) {
45
- return LEGACY_MODEL_CALL_SPAN_NAME.test(span.name);
46
- }
47
- if (scope !== VERCEL_SEMCONV_SCOPE) {
48
- return null;
49
- }
50
- const operation = span.attributes['gen_ai.operation.name'];
51
- this._openSpanOperations.delete(span.spanContext().spanId);
52
- if (operation === 'chat') {
53
- return true;
54
- }
55
- if (operation === 'embeddings') {
56
- // Keep the outer aggregate (one event per embed/embedMany call, with the
57
- // total usage) and drop the nested model-call span(s) repeating it.
58
- return this._openSpanOperations.get(_parentSpanId(span)) !== 'embeddings';
59
- }
60
- // invoke_agent / agent_step (usage aggregates) and execute_tool (no usage).
61
- return false;
62
- }
63
- }
64
-
65
- // `@ai-sdk/otel` reports the Vercel AI Gateway as the bare provider id
66
- // "gateway" — too generic a name to special-case downstream. Stamp the weflayr
67
- // provider override (which the normalizer prefers) with the canonical name.
68
- // A providerNameOverride set through propagateMetadata was stamped at span start and
69
- // wins.
70
- function stampVercelGatewayProviderName(span) {
71
- if (
72
- span.attributes['gen_ai.provider.name'] === 'gateway' &&
73
- span.attributes['weflayr.provider_name'] === undefined
74
- ) {
75
- span.attributes['weflayr.provider_name'] = 'vercel_ai_gateway';
76
- }
77
- }
78
-
79
- module.exports = { VercelAiSdkSpanFilter, stampVercelGatewayProviderName };