@morsehq-dev/sdk 0.4.0-rc.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 (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +294 -0
  3. package/dist/anthropic/index.cjs +39 -0
  4. package/dist/anthropic/index.cjs.map +1 -0
  5. package/dist/anthropic/index.d.cts +213 -0
  6. package/dist/anthropic/index.d.ts +213 -0
  7. package/dist/anthropic/index.js +6 -0
  8. package/dist/anthropic/index.js.map +1 -0
  9. package/dist/anthropic-agent-sdk/index.cjs +744 -0
  10. package/dist/anthropic-agent-sdk/index.cjs.map +1 -0
  11. package/dist/anthropic-agent-sdk/index.d.cts +371 -0
  12. package/dist/anthropic-agent-sdk/index.d.ts +371 -0
  13. package/dist/anthropic-agent-sdk/index.js +735 -0
  14. package/dist/anthropic-agent-sdk/index.js.map +1 -0
  15. package/dist/browser/anthropic/index.cjs +39 -0
  16. package/dist/browser/anthropic/index.cjs.map +1 -0
  17. package/dist/browser/anthropic/index.js +6 -0
  18. package/dist/browser/anthropic/index.js.map +1 -0
  19. package/dist/browser/anthropic-agent-sdk/index.cjs +744 -0
  20. package/dist/browser/anthropic-agent-sdk/index.cjs.map +1 -0
  21. package/dist/browser/anthropic-agent-sdk/index.js +735 -0
  22. package/dist/browser/anthropic-agent-sdk/index.js.map +1 -0
  23. package/dist/browser/chunk-3643DC7K.cjs +365 -0
  24. package/dist/browser/chunk-3643DC7K.cjs.map +1 -0
  25. package/dist/browser/chunk-4FALQMOZ.js +232 -0
  26. package/dist/browser/chunk-4FALQMOZ.js.map +1 -0
  27. package/dist/browser/chunk-5J2QBK75.js +884 -0
  28. package/dist/browser/chunk-5J2QBK75.js.map +1 -0
  29. package/dist/browser/chunk-7MSXWGAH.js +53 -0
  30. package/dist/browser/chunk-7MSXWGAH.js.map +1 -0
  31. package/dist/browser/chunk-A24L5N5N.js +596 -0
  32. package/dist/browser/chunk-A24L5N5N.js.map +1 -0
  33. package/dist/browser/chunk-B7DEUDP6.cjs +177 -0
  34. package/dist/browser/chunk-B7DEUDP6.cjs.map +1 -0
  35. package/dist/browser/chunk-F6CJACNH.cjs +604 -0
  36. package/dist/browser/chunk-F6CJACNH.cjs.map +1 -0
  37. package/dist/browser/chunk-JBOYFQSB.js +412 -0
  38. package/dist/browser/chunk-JBOYFQSB.js.map +1 -0
  39. package/dist/browser/chunk-KRBADE6R.cjs +183 -0
  40. package/dist/browser/chunk-KRBADE6R.cjs.map +1 -0
  41. package/dist/browser/chunk-MCJYZH6W.cjs +415 -0
  42. package/dist/browser/chunk-MCJYZH6W.cjs.map +1 -0
  43. package/dist/browser/chunk-NQG2IAQS.js +178 -0
  44. package/dist/browser/chunk-NQG2IAQS.js.map +1 -0
  45. package/dist/browser/chunk-O4HG3OSK.cjs +929 -0
  46. package/dist/browser/chunk-O4HG3OSK.cjs.map +1 -0
  47. package/dist/browser/chunk-QWRQJO57.js +363 -0
  48. package/dist/browser/chunk-QWRQJO57.js.map +1 -0
  49. package/dist/browser/chunk-SWQOPFE4.cjs +234 -0
  50. package/dist/browser/chunk-SWQOPFE4.cjs.map +1 -0
  51. package/dist/browser/chunk-TYDG747E.js +171 -0
  52. package/dist/browser/chunk-TYDG747E.js.map +1 -0
  53. package/dist/browser/chunk-TZRSDDFP.cjs +56 -0
  54. package/dist/browser/chunk-TZRSDDFP.cjs.map +1 -0
  55. package/dist/browser/index.cjs +587 -0
  56. package/dist/browser/index.cjs.map +1 -0
  57. package/dist/browser/index.js +522 -0
  58. package/dist/browser/index.js.map +1 -0
  59. package/dist/browser/integrations/pino.cjs +89 -0
  60. package/dist/browser/integrations/pino.cjs.map +1 -0
  61. package/dist/browser/integrations/pino.js +86 -0
  62. package/dist/browser/integrations/pino.js.map +1 -0
  63. package/dist/browser/langchain/index.cjs +535 -0
  64. package/dist/browser/langchain/index.cjs.map +1 -0
  65. package/dist/browser/langchain/index.js +528 -0
  66. package/dist/browser/langchain/index.js.map +1 -0
  67. package/dist/browser/langgraph/index.cjs +377 -0
  68. package/dist/browser/langgraph/index.cjs.map +1 -0
  69. package/dist/browser/langgraph/index.js +371 -0
  70. package/dist/browser/langgraph/index.js.map +1 -0
  71. package/dist/browser/openai/index.cjs +125 -0
  72. package/dist/browser/openai/index.cjs.map +1 -0
  73. package/dist/browser/openai/index.js +122 -0
  74. package/dist/browser/openai/index.js.map +1 -0
  75. package/dist/browser/openai-agents/index.cjs +689 -0
  76. package/dist/browser/openai-agents/index.cjs.map +1 -0
  77. package/dist/browser/openai-agents/index.js +678 -0
  78. package/dist/browser/openai-agents/index.js.map +1 -0
  79. package/dist/browser/vercel-ai/index.cjs +233 -0
  80. package/dist/browser/vercel-ai/index.cjs.map +1 -0
  81. package/dist/browser/vercel-ai/index.js +231 -0
  82. package/dist/browser/vercel-ai/index.js.map +1 -0
  83. package/dist/chunk-4R4SHGOK.js +363 -0
  84. package/dist/chunk-4R4SHGOK.js.map +1 -0
  85. package/dist/chunk-7EO7MQBA.cjs +183 -0
  86. package/dist/chunk-7EO7MQBA.cjs.map +1 -0
  87. package/dist/chunk-7YCENA54.cjs +604 -0
  88. package/dist/chunk-7YCENA54.cjs.map +1 -0
  89. package/dist/chunk-CKFOGDUF.js +596 -0
  90. package/dist/chunk-CKFOGDUF.js.map +1 -0
  91. package/dist/chunk-FJUNILZT.cjs +1324 -0
  92. package/dist/chunk-FJUNILZT.cjs.map +1 -0
  93. package/dist/chunk-HDAFUKQ3.js +171 -0
  94. package/dist/chunk-HDAFUKQ3.js.map +1 -0
  95. package/dist/chunk-KBWPNIH4.cjs +234 -0
  96. package/dist/chunk-KBWPNIH4.cjs.map +1 -0
  97. package/dist/chunk-KJEO52QS.cjs +365 -0
  98. package/dist/chunk-KJEO52QS.cjs.map +1 -0
  99. package/dist/chunk-KZBCOZIQ.cjs +177 -0
  100. package/dist/chunk-KZBCOZIQ.cjs.map +1 -0
  101. package/dist/chunk-ME5JALGT.js +53 -0
  102. package/dist/chunk-ME5JALGT.js.map +1 -0
  103. package/dist/chunk-PVHDEPRE.cjs +56 -0
  104. package/dist/chunk-PVHDEPRE.cjs.map +1 -0
  105. package/dist/chunk-RTL23YOQ.js +178 -0
  106. package/dist/chunk-RTL23YOQ.js.map +1 -0
  107. package/dist/chunk-TQWI4UYO.js +1277 -0
  108. package/dist/chunk-TQWI4UYO.js.map +1 -0
  109. package/dist/chunk-VXDBDPDR.cjs +415 -0
  110. package/dist/chunk-VXDBDPDR.cjs.map +1 -0
  111. package/dist/chunk-XTKMUJWI.js +232 -0
  112. package/dist/chunk-XTKMUJWI.js.map +1 -0
  113. package/dist/chunk-ZKUGOWER.js +412 -0
  114. package/dist/chunk-ZKUGOWER.js.map +1 -0
  115. package/dist/index.cjs +843 -0
  116. package/dist/index.cjs.map +1 -0
  117. package/dist/index.d.cts +464 -0
  118. package/dist/index.d.ts +464 -0
  119. package/dist/index.js +778 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/integrations/pino.cjs +89 -0
  122. package/dist/integrations/pino.cjs.map +1 -0
  123. package/dist/integrations/pino.d.cts +65 -0
  124. package/dist/integrations/pino.d.ts +65 -0
  125. package/dist/integrations/pino.js +86 -0
  126. package/dist/integrations/pino.js.map +1 -0
  127. package/dist/langchain/index.cjs +535 -0
  128. package/dist/langchain/index.cjs.map +1 -0
  129. package/dist/langchain/index.d.cts +265 -0
  130. package/dist/langchain/index.d.ts +265 -0
  131. package/dist/langchain/index.js +528 -0
  132. package/dist/langchain/index.js.map +1 -0
  133. package/dist/langgraph/index.cjs +377 -0
  134. package/dist/langgraph/index.cjs.map +1 -0
  135. package/dist/langgraph/index.d.cts +324 -0
  136. package/dist/langgraph/index.d.ts +324 -0
  137. package/dist/langgraph/index.js +371 -0
  138. package/dist/langgraph/index.js.map +1 -0
  139. package/dist/openai/index.cjs +125 -0
  140. package/dist/openai/index.cjs.map +1 -0
  141. package/dist/openai/index.d.cts +136 -0
  142. package/dist/openai/index.d.ts +136 -0
  143. package/dist/openai/index.js +122 -0
  144. package/dist/openai/index.js.map +1 -0
  145. package/dist/openai-agents/index.cjs +689 -0
  146. package/dist/openai-agents/index.cjs.map +1 -0
  147. package/dist/openai-agents/index.d.cts +502 -0
  148. package/dist/openai-agents/index.d.ts +502 -0
  149. package/dist/openai-agents/index.js +678 -0
  150. package/dist/openai-agents/index.js.map +1 -0
  151. package/dist/spans-DZtMuBvc.d.cts +73 -0
  152. package/dist/spans-DZtMuBvc.d.ts +73 -0
  153. package/dist/tracing-BYAqjT5Q.d.cts +114 -0
  154. package/dist/tracing-rz9cWQ8d.d.ts +114 -0
  155. package/dist/vercel-ai/index.cjs +233 -0
  156. package/dist/vercel-ai/index.cjs.map +1 -0
  157. package/dist/vercel-ai/index.d.cts +93 -0
  158. package/dist/vercel-ai/index.d.ts +93 -0
  159. package/dist/vercel-ai/index.js +231 -0
  160. package/dist/vercel-ai/index.js.map +1 -0
  161. package/package.json +182 -0
@@ -0,0 +1,1324 @@
1
+ 'use strict';
2
+
3
+ var crypto = require('crypto');
4
+ var api = require('@opentelemetry/api');
5
+ var core = require('@opentelemetry/core');
6
+ var exporterTraceOtlpProto = require('@opentelemetry/exporter-trace-otlp-proto');
7
+ var otlpExporterBase = require('@opentelemetry/otlp-exporter-base');
8
+ var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
9
+ var sdkTraceNode = require('@opentelemetry/sdk-trace-node');
10
+ var instrumentation = require('@opentelemetry/instrumentation');
11
+ var contextAsyncHooks = require('@opentelemetry/context-async-hooks');
12
+
13
+ var __defProp = Object.defineProperty;
14
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
+ var __getOwnPropNames = Object.getOwnPropertyNames;
16
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
17
+ var __esm = (fn, res, err) => function __init() {
18
+ if (err) throw err[0];
19
+ try {
20
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
21
+ } catch (e) {
22
+ throw err = [e], e;
23
+ }
24
+ };
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __copyProps = (to, from, except, desc) => {
30
+ if (from && typeof from === "object" || typeof from === "function") {
31
+ for (let key of __getOwnPropNames(from))
32
+ if (!__hasOwnProp.call(to, key) && key !== except)
33
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
+ }
35
+ return to;
36
+ };
37
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
+
39
+ // src/_internal/env.ts
40
+ function readEnv(key) {
41
+ if (typeof process !== "undefined" && process.env) {
42
+ const v = process.env[key];
43
+ if (typeof v === "string") return v;
44
+ }
45
+ const denoGlobal = globalThis.Deno;
46
+ if (denoGlobal?.env?.get) {
47
+ try {
48
+ const v = denoGlobal.env.get(key);
49
+ if (typeof v === "string") return v;
50
+ } catch {
51
+ }
52
+ }
53
+ return void 0;
54
+ }
55
+ function truthy(value) {
56
+ if (!value) return false;
57
+ return ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
58
+ }
59
+ function getApiKey() {
60
+ const raw = readEnv("MORSE_API_KEY");
61
+ if (!raw) return void 0;
62
+ const trimmed = raw.trim();
63
+ return trimmed || void 0;
64
+ }
65
+ function getEndpoint() {
66
+ const raw = readEnv("MORSE_ENDPOINT");
67
+ if (!raw) return void 0;
68
+ const trimmed = raw.trim();
69
+ return trimmed || void 0;
70
+ }
71
+ function getFlushIntervalSeconds(defaultSeconds = 2) {
72
+ const raw = readEnv("MORSE_FLUSH_INTERVAL_SECONDS");
73
+ if (!raw) return defaultSeconds;
74
+ const parsed = Number.parseFloat(raw.trim());
75
+ if (!Number.isFinite(parsed) || parsed <= 0) return defaultSeconds;
76
+ return parsed;
77
+ }
78
+ function isDisabled() {
79
+ return truthy(readEnv("MORSE_DISABLED"));
80
+ }
81
+ function isDebug() {
82
+ return truthy(readEnv("MORSE_SDK_DEBUG"));
83
+ }
84
+ function isTelemetryDisabled() {
85
+ return truthy(readEnv("MORSE_SDK_DISABLE_TELEMETRY"));
86
+ }
87
+ function isAutoDetectDisabled() {
88
+ return truthy(readEnv("MORSE_DISABLE_AUTO_DETECT"));
89
+ }
90
+ function getInternalSource() {
91
+ const raw = readEnv("MORSE_INTERNAL_SOURCE");
92
+ if (!raw) return void 0;
93
+ const trimmed = raw.trim().toLowerCase();
94
+ if (!trimmed) return void 0;
95
+ return VALID_INTERNAL_SOURCES.has(trimmed) ? trimmed : void 0;
96
+ }
97
+ function isValidInternalSource(value) {
98
+ return typeof value === "string" && VALID_INTERNAL_SOURCES.has(value);
99
+ }
100
+ function getSampleRate(defaultRate = 1) {
101
+ const raw = readEnv("MORSE_SAMPLE_RATE");
102
+ if (!raw) return defaultRate;
103
+ const parsed = Number.parseFloat(raw.trim());
104
+ if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) return defaultRate;
105
+ return parsed;
106
+ }
107
+ function getMaxFieldBytes(defaultBytes = 65536) {
108
+ const raw = readEnv("MORSE_MAX_FIELD_BYTES");
109
+ if (!raw) return defaultBytes;
110
+ const parsed = Number.parseInt(raw.trim(), 10);
111
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultBytes;
112
+ }
113
+ function getMaxQueueSize(defaultSize = 2048) {
114
+ const raw = readEnv("MORSE_MAX_QUEUE_SIZE");
115
+ if (!raw) return defaultSize;
116
+ const parsed = Number.parseInt(raw.trim(), 10);
117
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultSize;
118
+ }
119
+ function getMaxBatchSize(defaultSize = 512) {
120
+ const raw = readEnv("MORSE_MAX_BATCH_SIZE");
121
+ if (!raw) return defaultSize;
122
+ const parsed = Number.parseInt(raw.trim(), 10);
123
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultSize;
124
+ }
125
+ function isLegacyTransport() {
126
+ return truthy(readEnv("MORSE_LEGACY_TRANSPORT"));
127
+ }
128
+ function isDbCaptureEnabled() {
129
+ return truthy(readEnv("MORSE_CAPTURE_DB")) || truthy(readEnv("MORSE_CAPTURE_INFRA"));
130
+ }
131
+ exports.DEFAULT_ENDPOINT = void 0; var VALID_INTERNAL_SOURCES;
132
+ var init_env = __esm({
133
+ "src/_internal/env.ts"() {
134
+ exports.DEFAULT_ENDPOINT = "https://api.morsehq.dev/api/v1/traces/batch";
135
+ VALID_INTERNAL_SOURCES = /* @__PURE__ */ new Set(["copilot", "investigator", "refagent", "ui-bot"]);
136
+ }
137
+ });
138
+
139
+ // src/_internal/spans.ts
140
+ function generateTraceId() {
141
+ return randomHex(32);
142
+ }
143
+ function generateSpanId() {
144
+ return randomHex(32);
145
+ }
146
+ function randomHex(chars) {
147
+ const bytes = new Uint8Array(Math.ceil(chars / 2));
148
+ const cryptoObj = globalThis.crypto;
149
+ if (cryptoObj?.getRandomValues) {
150
+ cryptoObj.getRandomValues(bytes);
151
+ } else {
152
+ for (let i = 0; i < bytes.length; i++) {
153
+ bytes[i] = Math.floor(Math.random() * 256);
154
+ }
155
+ }
156
+ let hex = "";
157
+ for (const b of bytes) {
158
+ hex += b.toString(16).padStart(2, "0");
159
+ }
160
+ return hex.slice(0, chars);
161
+ }
162
+ function nowIso() {
163
+ return (/* @__PURE__ */ new Date()).toISOString();
164
+ }
165
+ function spanToWire(span) {
166
+ const out = {};
167
+ for (const [k, v] of Object.entries(span)) {
168
+ if (v !== void 0 && v !== null) {
169
+ out[k] = v;
170
+ }
171
+ }
172
+ return out;
173
+ }
174
+ function buildTraceEntry(fields, spans) {
175
+ return {
176
+ trace: fields,
177
+ spans: spans.map(spanToWire)
178
+ };
179
+ }
180
+ exports.SpanType = void 0;
181
+ var init_spans = __esm({
182
+ "src/_internal/spans.ts"() {
183
+ exports.SpanType = {
184
+ AGENT: "agent",
185
+ LLM: "llm",
186
+ TOOL: "tool",
187
+ HTTP: "http",
188
+ DB: "db",
189
+ CUSTOM: "custom",
190
+ MEMORY: "memory",
191
+ // MHQ-482: matches Python's `SpanType.RETRIEVER` (apps/sdk/python/src/morse_ai/spans.py).
192
+ // @beta — retriever span type is subject to change before SDK v1.0 (see
193
+ // the plain-LangChain adapter's on_retriever_* callbacks in src/langchain/).
194
+ RETRIEVER: "retriever"
195
+ };
196
+ }
197
+ });
198
+
199
+ // src/_internal/redaction.ts
200
+ function buildRedactionConfig(options) {
201
+ const opts = options ?? {};
202
+ const enabled = opts.enabled !== false;
203
+ if (!enabled) {
204
+ return {
205
+ enabled: false,
206
+ enabledPatterns: /* @__PURE__ */ new Set(),
207
+ extraCompiled: []
208
+ };
209
+ }
210
+ const disabled = new Set(opts.disabledPatterns ?? []);
211
+ for (const key of disabled) {
212
+ if (MANDATORY_PATTERNS.has(key)) {
213
+ throw new Error(`redaction pattern '${key}' cannot be disabled (server-side mandatory)`);
214
+ }
215
+ }
216
+ const active = /* @__PURE__ */ new Set();
217
+ for (const key of PATTERN_ORDER) {
218
+ if (DEFAULT_OFF_PATTERNS.has(key)) continue;
219
+ if (disabled.has(key)) continue;
220
+ active.add(key);
221
+ }
222
+ const extraInput = opts.extraPatterns ?? [];
223
+ if (extraInput.length > EXTRA_PATTERN_CAP) {
224
+ throw new Error(
225
+ `too many redaction extra patterns: ${extraInput.length} (max ${EXTRA_PATTERN_CAP})`
226
+ );
227
+ }
228
+ const extraCompiled = [];
229
+ for (const raw of extraInput) {
230
+ if (typeof raw !== "string") {
231
+ throw new Error(`redaction extra pattern must be a string, got ${typeof raw}`);
232
+ }
233
+ if (raw.length > EXTRA_PATTERN_CHAR_CAP) {
234
+ throw new Error(`redaction extra pattern exceeds ${EXTRA_PATTERN_CHAR_CAP} chars`);
235
+ }
236
+ let compiled;
237
+ try {
238
+ compiled = new RegExp(raw, "g");
239
+ } catch (err) {
240
+ const msg = err instanceof Error ? err.message : String(err);
241
+ throw new Error(`redaction extra pattern failed to compile: ${JSON.stringify(raw)} \u2014 ${msg}`);
242
+ }
243
+ extraCompiled.push(compiled);
244
+ }
245
+ return {
246
+ enabled: true,
247
+ enabledPatterns: active,
248
+ extraCompiled
249
+ };
250
+ }
251
+ function luhnValid(s) {
252
+ let sum = 0;
253
+ let alt = false;
254
+ let digits = 0;
255
+ for (let i = s.length - 1; i >= 0; i--) {
256
+ const ch = s.charCodeAt(i);
257
+ if (ch < 48 || ch > 57) continue;
258
+ let n = ch - 48;
259
+ if (alt) {
260
+ n *= 2;
261
+ if (n > 9) n -= 9;
262
+ }
263
+ sum += n;
264
+ alt = !alt;
265
+ digits++;
266
+ }
267
+ if (digits < 13 || digits > 19) return false;
268
+ return sum % 10 === 0;
269
+ }
270
+ function resolveEnabled(config, override) {
271
+ return config.enabledPatterns;
272
+ }
273
+ function redactString(s, config, enabledOverride) {
274
+ if (!config.enabled && enabledOverride === void 0) {
275
+ return s;
276
+ }
277
+ if (s.length === 0) return s;
278
+ const enabled = resolveEnabled(config);
279
+ let out = s;
280
+ for (const key of PATTERN_ORDER) {
281
+ if (!enabled.has(key)) continue;
282
+ const re = PATTERNS[key];
283
+ if (re === void 0) continue;
284
+ re.lastIndex = 0;
285
+ const replacement = `[REDACTED:${SHORT_KEYS[key]}]`;
286
+ if (key === "credit_card") {
287
+ out = out.replace(re, (m) => luhnValid(m) ? replacement : m);
288
+ } else {
289
+ out = out.replace(re, replacement);
290
+ }
291
+ }
292
+ for (const re of config.extraCompiled) {
293
+ re.lastIndex = 0;
294
+ out = out.replace(re, "[REDACTED:custom]");
295
+ }
296
+ return out;
297
+ }
298
+ function redactValue(value, config, depth = 0) {
299
+ if (!config.enabled) return value;
300
+ if (value === null || value === void 0) return value;
301
+ if (typeof value === "string") return redactString(value, config);
302
+ if (typeof value === "number" || typeof value === "boolean") return value;
303
+ if (depth >= MAX_DEPTH) return value;
304
+ if (Array.isArray(value)) {
305
+ return value.map((item) => redactValue(item, config, depth + 1));
306
+ }
307
+ if (typeof value === "object") {
308
+ const proto = Object.getPrototypeOf(value);
309
+ if (proto === Object.prototype || proto === null) {
310
+ const out = {};
311
+ for (const [k, v] of Object.entries(value)) {
312
+ out[k] = redactValue(v, config, depth + 1);
313
+ }
314
+ return out;
315
+ }
316
+ }
317
+ return value;
318
+ }
319
+ var PATTERN_ORDER, MANDATORY_PATTERNS, DEFAULT_OFF_PATTERNS, SHORT_KEYS, PATTERNS, EXTRA_PATTERN_CAP, EXTRA_PATTERN_CHAR_CAP, MAX_DEPTH;
320
+ var init_redaction = __esm({
321
+ "src/_internal/redaction.ts"() {
322
+ PATTERN_ORDER = [
323
+ "api_key_prefixed",
324
+ "jwt",
325
+ "credit_card",
326
+ "email",
327
+ "phone_us",
328
+ "phone_e164",
329
+ "ssn_us",
330
+ "ip_address"
331
+ ];
332
+ MANDATORY_PATTERNS = /* @__PURE__ */ new Set([
333
+ "api_key_prefixed",
334
+ "jwt",
335
+ "credit_card",
336
+ "ssn_us"
337
+ ]);
338
+ DEFAULT_OFF_PATTERNS = /* @__PURE__ */ new Set(["ip_address"]);
339
+ SHORT_KEYS = {
340
+ api_key_prefixed: "api_key",
341
+ jwt: "jwt",
342
+ credit_card: "credit_card",
343
+ email: "email",
344
+ phone_us: "phone",
345
+ phone_e164: "phone",
346
+ ssn_us: "ssn",
347
+ ip_address: "ip"
348
+ };
349
+ PATTERNS = {
350
+ api_key_prefixed: new RegExp(
351
+ "\\b(?:sk-[A-Za-z0-9_-]{20,}|sk_(?:live|test)_[A-Za-z0-9]{20,}|mhq_[A-Za-z0-9]{20,}|av_[A-Za-z0-9]{20,}|ghp_[A-Za-z0-9]{36}|gho_[A-Za-z0-9]{36}|ghu_[A-Za-z0-9]{36}|ghs_[A-Za-z0-9]{36}|ghr_[A-Za-z0-9]{36}|xox[bopsa]-[0-9A-Za-z\\-]{10,}|(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16})\\b",
352
+ "g"
353
+ ),
354
+ jwt: new RegExp(
355
+ "\\beyJ[A-Za-z0-9_=-]{16,}\\.eyJ[A-Za-z0-9_=-]{16,}\\.[A-Za-z0-9_=-]{16,}\\b",
356
+ "g"
357
+ ),
358
+ credit_card: new RegExp("\\b(?:\\d[ -]?){12,18}\\d\\b", "g"),
359
+ email: new RegExp("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b", "gi"),
360
+ // The leading `(?<!\d)` and trailing `(?!\d)` lookarounds prevent
361
+ // the phone matcher from carving a 10-digit substring out of a longer
362
+ // continuous digit run (e.g., a 16-digit credit-card-shaped number that
363
+ // failed Luhn). Without them, `1234567890123456` would emit a
364
+ // `[REDACTED:phone]` for digits 7-16 even though the whole run was
365
+ // never a real phone number. The canonical Python regex needs the same
366
+ // shim — see redaction.py.
367
+ phone_us: new RegExp(
368
+ "(?<!\\d)(?:\\+?1[ \\-.])?\\(?[2-9]\\d{2}\\)?[ \\-.]?\\d{3}[ \\-.]?\\d{4}(?!\\d)",
369
+ "g"
370
+ ),
371
+ phone_e164: new RegExp("(?<!\\d)\\+(?:[0-9][ \\-.]?){8,14}[0-9](?!\\d)", "g"),
372
+ ssn_us: new RegExp(
373
+ "\\b(?!000|666|9\\d{2})\\d{3}[ \\-.](?!00)\\d{2}[ \\-.](?!0000)\\d{4}\\b",
374
+ "g"
375
+ ),
376
+ ip_address: new RegExp(
377
+ "\\b(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}|(?:[A-F0-9]{1,4}:){2,7}[A-F0-9]{1,4})\\b",
378
+ "gi"
379
+ )
380
+ };
381
+ EXTRA_PATTERN_CAP = 10;
382
+ EXTRA_PATTERN_CHAR_CAP = 256;
383
+ MAX_DEPTH = 10;
384
+ }
385
+ });
386
+ function ensureGlobalContextManager() {
387
+ if (contextManagerRegistered) return;
388
+ contextManagerRegistered = true;
389
+ try {
390
+ api.context.setGlobalContextManager(new contextAsyncHooks.AsyncHooksContextManager().enable());
391
+ } catch {
392
+ }
393
+ }
394
+ function withOtelSpanContext(traceIdHex, spanIdHex, fn) {
395
+ const eng = getEngine();
396
+ if (eng.provider === null) return fn();
397
+ ensureGlobalContextManager();
398
+ const sampled = eng.resolveSampled(traceIdHex);
399
+ const spanCtx = {
400
+ traceId: traceIdHex,
401
+ spanId: spanIdHex,
402
+ isRemote: true,
403
+ traceFlags: sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
404
+ };
405
+ const withCtx = api.trace.setSpanContext(api.context.active(), spanCtx);
406
+ return api.context.with(withCtx, fn);
407
+ }
408
+ function capBytes(value, maxBytes) {
409
+ if (maxBytes <= 0) return value;
410
+ const encoded = Buffer.from(value, "utf-8");
411
+ if (encoded.length <= maxBytes) return value;
412
+ const markerBytes = Buffer.byteLength(TRUNCATION_MARKER, "utf-8");
413
+ const budget = Math.max(maxBytes - markerBytes, 0);
414
+ let truncated = encoded.subarray(0, budget);
415
+ const decoder = new TextDecoder("utf-8", { fatal: true });
416
+ while (truncated.length > 0) {
417
+ try {
418
+ return decoder.decode(truncated) + TRUNCATION_MARKER;
419
+ } catch {
420
+ truncated = truncated.subarray(0, truncated.length - 1);
421
+ }
422
+ }
423
+ return TRUNCATION_MARKER;
424
+ }
425
+ function jsonCapped(value, maxBytes) {
426
+ if (value === null || value === void 0) return null;
427
+ if (typeof value === "string") {
428
+ return JSON.stringify(capBytes(value, maxBytes));
429
+ }
430
+ let encoded;
431
+ try {
432
+ encoded = JSON.stringify(value, (_k, v) => typeof v === "bigint" ? String(v) : v) ?? "null";
433
+ } catch {
434
+ encoded = JSON.stringify(String(value));
435
+ }
436
+ return capBytes(encoded, maxBytes);
437
+ }
438
+ function decorrelateTraceIdForSampling(traceIdHex) {
439
+ const traceIdBytes = Buffer.from(traceIdHex.padStart(32, "0").slice(0, 32), "hex");
440
+ return crypto.createHash("sha256").update(traceIdBytes).digest();
441
+ }
442
+ function ratioSample(traceIdHex, rate) {
443
+ if (rate <= 0) return false;
444
+ if (rate >= 1) return true;
445
+ const digest = decorrelateTraceIdForSampling(traceIdHex);
446
+ const low64 = digest.subarray(8, 16).readBigUInt64BE();
447
+ const threshold = BigInt(Math.round(rate * Number(MAX_U64)));
448
+ return low64 < threshold;
449
+ }
450
+ function redactAttrValue(value, config) {
451
+ if (typeof value === "string") return redactString(value, config);
452
+ if (Array.isArray(value)) {
453
+ return value.map((v) => typeof v === "string" ? redactString(v, config) : v);
454
+ }
455
+ return value;
456
+ }
457
+ function getEngine() {
458
+ if (engine === null) engine = new OtelEngine();
459
+ return engine;
460
+ }
461
+ function spanDictToOtelAttributes(spanDict, traceDict, resourceDict, opts) {
462
+ const attrs = {};
463
+ const spanType = spanDict.type;
464
+ if (typeof spanType === "string" && spanType) attrs["av.span_type"] = spanType;
465
+ const model = spanDict.model;
466
+ if (model !== void 0 && model !== null) attrs["gen_ai.request.model"] = String(model);
467
+ const tokenFields = [
468
+ ["input_tokens", "gen_ai.usage.input_tokens"],
469
+ ["output_tokens", "gen_ai.usage.output_tokens"],
470
+ ["cached_input_tokens", "gen_ai.usage.cache_read_input_tokens"],
471
+ ["cache_write_tokens", "gen_ai.usage.cache_creation_input_tokens"],
472
+ ["reasoning_tokens", "gen_ai.usage.reasoning_tokens"]
473
+ ];
474
+ for (const [src, otelKey] of tokenFields) {
475
+ const v = spanDict[src];
476
+ if (v !== void 0 && v !== null) {
477
+ const n = Number(v);
478
+ if (Number.isFinite(n)) attrs[otelKey] = Math.trunc(n);
479
+ }
480
+ }
481
+ const costUsd = spanDict.cost_usd;
482
+ if (costUsd !== void 0 && costUsd !== null) {
483
+ attrs["av.cost_usd"] = String(costUsd);
484
+ }
485
+ for (const [src, otelKey] of [
486
+ ["input_data", "av.input_data"],
487
+ ["output_data", "av.output_data"],
488
+ ["context_segments", "av.context_segments"]
489
+ ]) {
490
+ const v = spanDict[src];
491
+ if (v !== void 0 && v !== null) {
492
+ const encoded = jsonCapped(v, opts.maxFieldBytes);
493
+ if (encoded !== null) attrs[otelKey] = encoded;
494
+ }
495
+ }
496
+ const metadata = spanDict.metadata;
497
+ if (metadata && typeof metadata === "object") {
498
+ for (const [key, value] of Object.entries(metadata)) {
499
+ const encoded = jsonCapped(value, opts.maxFieldBytes);
500
+ if (encoded !== null) attrs[`av.metadata.${key}`] = encoded;
501
+ }
502
+ }
503
+ const errorMessage = spanDict.error_message;
504
+ if (opts.isRoot) {
505
+ const threadId = traceDict.thread_id;
506
+ if (threadId !== void 0 && threadId !== null) attrs["av.thread_id"] = String(threadId);
507
+ const userId = traceDict.user_id;
508
+ if (userId !== void 0 && userId !== null) attrs["av.user_id"] = String(userId);
509
+ const userMetadata = traceDict.user_metadata;
510
+ if (userMetadata && typeof userMetadata === "object") {
511
+ const entries = Object.entries(userMetadata);
512
+ if (entries.length > 0) {
513
+ attrs["av.user_metadata"] = JSON.stringify(
514
+ Object.fromEntries(entries.map(([k, v]) => [k, String(v)]))
515
+ );
516
+ }
517
+ }
518
+ const success = traceDict.success;
519
+ if (success !== void 0 && success !== null) attrs["av.outcome.success"] = Boolean(success);
520
+ const outcome = traceDict.outcome;
521
+ if (outcome !== void 0 && outcome !== null) attrs["av.outcome.label"] = String(outcome);
522
+ const framework = resourceDict["morse_ai.framework"];
523
+ if (typeof framework === "string" && framework) attrs["av.framework"] = framework;
524
+ const source = resourceDict["morse_ai.source"];
525
+ if (typeof source === "string" && source) attrs["av.source"] = source;
526
+ }
527
+ if (errorMessage && spanDict.status === "failed") {
528
+ attrs["av.error_message"] = String(errorMessage);
529
+ }
530
+ return attrs;
531
+ }
532
+ function isoToTimeInputMillis(value) {
533
+ if (typeof value !== "string" || !value) return void 0;
534
+ const ms = Date.parse(value);
535
+ return Number.isNaN(ms) ? void 0 : ms;
536
+ }
537
+ function emitTraceEntry(entry) {
538
+ const eng = getEngine();
539
+ const tracer = eng.tracer;
540
+ if (tracer === null) return;
541
+ const traceDict = entry.trace ?? {};
542
+ const spanDicts = entry.spans ?? [];
543
+ const resourceDict = entry.resource ?? {};
544
+ if (spanDicts.length === 0) return;
545
+ const traceIdHexRaw = traceDict.trace_id;
546
+ if (typeof traceIdHexRaw !== "string" || traceIdHexRaw.length === 0) return;
547
+ const traceIdHex = traceIdHexRaw.toLowerCase().padStart(32, "0").slice(0, 32);
548
+ if (!/^[0-9a-f]{32}$/.test(traceIdHex) || /^0+$/.test(traceIdHex)) return;
549
+ const sampled = eng.resolveSampled(traceIdHex);
550
+ const syntheticParentContext = {
551
+ traceId: traceIdHex,
552
+ // Placeholder — only traceId/traceFlags matter here; every real span
553
+ // in the trace gets its own OTel-minted spanId via startSpan().
554
+ spanId: "0000000000000001",
555
+ isRemote: true,
556
+ traceFlags: sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
557
+ };
558
+ const rootParentCtx = api.trace.setSpanContext(api.ROOT_CONTEXT, syntheticParentContext);
559
+ let rootSpanId;
560
+ for (const s of spanDicts) {
561
+ if (!s.parent_span_id) {
562
+ rootSpanId = s.span_id;
563
+ break;
564
+ }
565
+ }
566
+ if (rootSpanId === void 0 && spanDicts.length > 0) {
567
+ rootSpanId = spanDicts[0].span_id;
568
+ }
569
+ const ordered = [...spanDicts].sort((a, b) => {
570
+ const aIsRoot = a.span_id === rootSpanId ? 0 : 1;
571
+ const bIsRoot = b.span_id === rootSpanId ? 0 : 1;
572
+ return aIsRoot - bIsRoot;
573
+ });
574
+ const spanCtxById = /* @__PURE__ */ new Map();
575
+ const maxFieldBytes = eng.maxFieldBytes;
576
+ for (const spanDict of ordered) {
577
+ const spanIdHex = typeof spanDict.span_id === "string" ? spanDict.span_id : void 0;
578
+ const parentIdHex = typeof spanDict.parent_span_id === "string" ? spanDict.parent_span_id : void 0;
579
+ let parentCtx = rootParentCtx;
580
+ if (parentIdHex && spanCtxById.has(parentIdHex)) {
581
+ parentCtx = api.trace.setSpanContext(api.ROOT_CONTEXT, spanCtxById.get(parentIdHex));
582
+ }
583
+ const attributes = spanDictToOtelAttributes(spanDict, traceDict, resourceDict, {
584
+ isRoot: spanDict.span_id === rootSpanId,
585
+ maxFieldBytes
586
+ });
587
+ const startTime = isoToTimeInputMillis(spanDict.started_at);
588
+ const endTime = isoToTimeInputMillis(spanDict.ended_at) ?? startTime;
589
+ try {
590
+ const otelSpan = tracer.startSpan(
591
+ typeof spanDict.name === "string" && spanDict.name ? spanDict.name : "span",
592
+ {
593
+ kind: api.SpanKind.INTERNAL,
594
+ attributes,
595
+ startTime
596
+ },
597
+ parentCtx
598
+ );
599
+ if (spanIdHex) {
600
+ spanCtxById.set(spanIdHex, otelSpan.spanContext());
601
+ }
602
+ if (spanDict.status === "failed") {
603
+ otelSpan.setStatus({
604
+ code: api.SpanStatusCode.ERROR,
605
+ message: String(spanDict.error_message ?? "")
606
+ });
607
+ }
608
+ otelSpan.end(endTime);
609
+ } catch {
610
+ }
611
+ }
612
+ }
613
+ var INSTRUMENTATION_NAME, DEFAULT_MAX_FIELD_BYTES, TRUNCATION_MARKER, contextManagerRegistered, MAX_U64, RedactingSpanExporter, RecordingSpanExporter, ResultCapturingExporter, OtelEngine, engine;
614
+ var init_otel_provider = __esm({
615
+ "src/_internal/otel-provider.ts"() {
616
+ init_redaction();
617
+ INSTRUMENTATION_NAME = "morse-typescript";
618
+ DEFAULT_MAX_FIELD_BYTES = 65536;
619
+ TRUNCATION_MARKER = "\u2026[truncated]";
620
+ contextManagerRegistered = false;
621
+ MAX_U64 = (1n << 64n) - 1n;
622
+ RedactingSpanExporter = class {
623
+ constructor(inner, redactionConfig2) {
624
+ this.inner = inner;
625
+ this.redactionConfig = redactionConfig2;
626
+ }
627
+ inner;
628
+ redactionConfig;
629
+ export(spans, resultCallback) {
630
+ const config = this.redactionConfig;
631
+ if (config && (config.enabled || config.extraCompiled.length > 0)) {
632
+ for (const span of spans) {
633
+ const attrs = span.attributes;
634
+ if (!attrs) continue;
635
+ for (const key of Object.keys(attrs)) {
636
+ attrs[key] = redactAttrValue(attrs[key], config);
637
+ }
638
+ }
639
+ }
640
+ this.inner.export(spans, resultCallback);
641
+ }
642
+ shutdown() {
643
+ return this.inner.shutdown();
644
+ }
645
+ forceFlush() {
646
+ return this.inner.forceFlush ? this.inner.forceFlush() : Promise.resolve();
647
+ }
648
+ };
649
+ RecordingSpanExporter = class {
650
+ spans = [];
651
+ export(spans, resultCallback) {
652
+ this.spans.push(...spans);
653
+ resultCallback({ code: core.ExportResultCode.SUCCESS });
654
+ }
655
+ shutdown() {
656
+ return Promise.resolve();
657
+ }
658
+ forceFlush() {
659
+ return Promise.resolve();
660
+ }
661
+ clear() {
662
+ this.spans = [];
663
+ }
664
+ };
665
+ ResultCapturingExporter = class {
666
+ constructor(inner, sink) {
667
+ this.inner = inner;
668
+ this.sink = sink;
669
+ }
670
+ inner;
671
+ sink;
672
+ export(spans, resultCallback) {
673
+ this.inner.export(spans, (result) => {
674
+ this.sink(result);
675
+ resultCallback(result);
676
+ });
677
+ }
678
+ shutdown() {
679
+ return this.inner.shutdown();
680
+ }
681
+ forceFlush() {
682
+ return this.inner.forceFlush ? this.inner.forceFlush() : Promise.resolve();
683
+ }
684
+ };
685
+ OtelEngine = class {
686
+ provider = null;
687
+ tracer = null;
688
+ sampleRate = 1;
689
+ recorder = null;
690
+ maxFieldBytes = DEFAULT_MAX_FIELD_BYTES;
691
+ exitHookRegistered = false;
692
+ /**
693
+ * (Re)build the provider. Mirrors Python's `_Client.__init__` semantics:
694
+ * calling this again (e.g. a second `init()`) tears down the previous
695
+ * provider first (fire-and-forget — Node has no synchronous blocking
696
+ * shutdown equivalent to Python's `atexit`).
697
+ */
698
+ configure(opts) {
699
+ if (this.provider !== null) {
700
+ const prior = this.provider;
701
+ void prior.shutdown().catch(() => {
702
+ });
703
+ }
704
+ this.maxFieldBytes = opts.maxFieldBytes;
705
+ this.sampleRate = Math.min(1, Math.max(0, opts.sampleRate));
706
+ const sampler = new sdkTraceBase.ParentBasedSampler({
707
+ root: new sdkTraceBase.TraceIdRatioBasedSampler(this.sampleRate)
708
+ });
709
+ const otlpExporter = new exporterTraceOtlpProto.OTLPTraceExporter({
710
+ url: opts.endpoint,
711
+ headers: { Authorization: `Bearer ${opts.apiKey}` },
712
+ compression: otlpExporterBase.CompressionAlgorithm.GZIP,
713
+ timeoutMillis: opts.timeoutMillis
714
+ });
715
+ let exporter = new RedactingSpanExporter(otlpExporter, opts.redactionConfig);
716
+ if (opts.resultSink) {
717
+ exporter = new ResultCapturingExporter(exporter, opts.resultSink);
718
+ }
719
+ this.recorder = opts.captureForTests ? new RecordingSpanExporter() : null;
720
+ const spanProcessors = [
721
+ new sdkTraceBase.BatchSpanProcessor(exporter, {
722
+ maxQueueSize: opts.maxQueueSize,
723
+ scheduledDelayMillis: opts.scheduleDelayMillis,
724
+ maxExportBatchSize: opts.maxExportBatchSize
725
+ })
726
+ ];
727
+ if (this.recorder !== null) {
728
+ spanProcessors.push(new sdkTraceBase.BatchSpanProcessor(this.recorder));
729
+ }
730
+ this.provider = new sdkTraceNode.NodeTracerProvider({ sampler, spanProcessors });
731
+ this.tracer = this.provider.getTracer(INSTRUMENTATION_NAME);
732
+ if (!this.exitHookRegistered) {
733
+ process.once("beforeExit", () => {
734
+ this.shutdown();
735
+ });
736
+ this.exitHookRegistered = true;
737
+ }
738
+ }
739
+ shutdown() {
740
+ if (this.provider !== null) {
741
+ const provider = this.provider;
742
+ void provider.shutdown().catch(() => {
743
+ });
744
+ this.provider = null;
745
+ this.tracer = null;
746
+ }
747
+ }
748
+ /**
749
+ * Test-only fast reset: drop the provider reference WITHOUT blocking on
750
+ * `shutdown()`. Mirrors Python's `reset_for_testing` — the OTLP
751
+ * exporter's retry-with-backoff behavior against an unreachable test
752
+ * endpoint would otherwise make every test file's teardown slow. The
753
+ * queued background work is not awaited; it either finishes or is
754
+ * abandoned with the process, same trade-off as Python's daemon worker
755
+ * thread.
756
+ */
757
+ resetForTesting() {
758
+ this.provider = null;
759
+ this.tracer = null;
760
+ this.recorder = null;
761
+ }
762
+ /** Block until in-flight exports finish (or the timeout elapses). */
763
+ async flush() {
764
+ const provider = this.provider;
765
+ if (provider !== null) {
766
+ try {
767
+ await provider.forceFlush();
768
+ } catch {
769
+ }
770
+ }
771
+ }
772
+ /**
773
+ * Run the deterministic ratio sampler directly for a trace id with no
774
+ * real parent. See `ratioSample` for the decorrelation rationale — feeding
775
+ * a raw uuid4 trace id straight to a ratio sampler produces a hard
776
+ * 0%/100% step function because of uuid4's fixed variant bits.
777
+ */
778
+ resolveSampled(traceIdHex) {
779
+ return ratioSample(traceIdHex, this.sampleRate);
780
+ }
781
+ /**
782
+ * Register OTel `Instrumentation` instances (e.g. the community DB-driver
783
+ * auto-instrumentation packages, see `./db-capture.ts`, MHQ-482) against
784
+ * THIS engine's `NodeTracerProvider` — so spans they emit flow through
785
+ * the same `BatchSpanProcessor` -> `RedactingSpanExporter` ->
786
+ * `OTLPTraceExporter` pipeline `configure()` built, landing in the same
787
+ * OTLP stream (and, when nested inside an active OTel context, the same
788
+ * trace) as the rest of the SDK's spans.
789
+ *
790
+ * No-op (silently, returns `null`) if `configure()` hasn't run yet —
791
+ * mirrors `emitTraceEntry`'s "no transport configured -> silent"
792
+ * contract. Callers (`index.ts::buildSingleton`) must call this AFTER
793
+ * `configure()`.
794
+ */
795
+ registerInstrumentations(instrumentations) {
796
+ if (this.provider === null) return null;
797
+ return instrumentation.registerInstrumentations({
798
+ tracerProvider: this.provider,
799
+ instrumentations
800
+ });
801
+ }
802
+ };
803
+ engine = null;
804
+ }
805
+ });
806
+
807
+ // src/_internal/tracing.ts
808
+ function tryLoadAls() {
809
+ if (alsLoaded) return als;
810
+ alsLoaded = true;
811
+ if (typeof process === "undefined" || !process.versions?.node) {
812
+ als = null;
813
+ return als;
814
+ }
815
+ try {
816
+ const dynamicRequire = Function("m", "return require(m)");
817
+ const mod = dynamicRequire("node:async_hooks");
818
+ if (mod?.AsyncLocalStorage) {
819
+ als = new mod.AsyncLocalStorage();
820
+ return als;
821
+ }
822
+ } catch {
823
+ }
824
+ als = null;
825
+ return als;
826
+ }
827
+ function getActiveTraceState() {
828
+ const store = tryLoadAls();
829
+ if (store) {
830
+ return store.getStore() ?? null;
831
+ }
832
+ return browserState;
833
+ }
834
+ function setActiveTraceState(state) {
835
+ const previous = browserState;
836
+ browserState = state;
837
+ return () => {
838
+ browserState = previous;
839
+ };
840
+ }
841
+ function setTransport(t) {
842
+ transport = t;
843
+ }
844
+ function getTransport() {
845
+ return transport;
846
+ }
847
+ function setRedactionConfig(config) {
848
+ redactionConfig = config;
849
+ }
850
+ function getRedactionConfig() {
851
+ return redactionConfig;
852
+ }
853
+ function setSource(value) {
854
+ _source = value && value.length > 0 ? value : null;
855
+ }
856
+ function getLastTrace() {
857
+ return lastTrace;
858
+ }
859
+ function nowMonotonic() {
860
+ if (typeof performance !== "undefined" && typeof performance.now === "function") {
861
+ return performance.now();
862
+ }
863
+ return Date.now();
864
+ }
865
+ function elapsedMs(startMonotonic) {
866
+ return Math.max(0, Math.round(nowMonotonic() - startMonotonic));
867
+ }
868
+ function finalizeSpan(span, startMono, status = "completed", errorMessage) {
869
+ span.ended_at = nowIso();
870
+ span.duration_ms = elapsedMs(startMono);
871
+ span.status = status;
872
+ if (errorMessage !== void 0) {
873
+ span.error_message = errorMessage;
874
+ }
875
+ }
876
+ function redactSpanDict(raw, config) {
877
+ if (!config.enabled) return raw;
878
+ const out = {};
879
+ for (const [k, v] of Object.entries(raw)) {
880
+ if (SPAN_REDACTABLE_FIELDS.has(k)) {
881
+ out[k] = redactValue(v, config);
882
+ } else {
883
+ out[k] = v;
884
+ }
885
+ }
886
+ return out;
887
+ }
888
+ function redactTraceDict(raw, config) {
889
+ if (!config.enabled) return raw;
890
+ const out = {};
891
+ for (const [k, v] of Object.entries(raw)) {
892
+ if (TRACE_REDACTABLE_FIELDS.has(k)) {
893
+ out[k] = redactValue(v, config);
894
+ } else {
895
+ out[k] = v;
896
+ }
897
+ }
898
+ return out;
899
+ }
900
+ function buildTraceDict(state, rootSpan) {
901
+ const trace = {
902
+ trace_id: state.traceId,
903
+ // Wire-format field is `agent` (matches backend TracePayloadIn schema +
904
+ // sibling Python SDK). Was `agent_name` historically — the mismatch
905
+ // caused dev ingest to reject every TS-emitted trace with a 422
906
+ // until Phase 13 Option A dogfood surfaced it.
907
+ agent: state.agentName,
908
+ status: rootSpan.status,
909
+ started_at: rootSpan.started_at
910
+ };
911
+ if (rootSpan.ended_at) trace.ended_at = rootSpan.ended_at;
912
+ if (rootSpan.duration_ms !== void 0) trace.duration_ms = rootSpan.duration_ms;
913
+ if (rootSpan.error_message) trace.error_message = rootSpan.error_message;
914
+ if (state.success !== void 0) trace.success = state.success;
915
+ if (state.outcome !== void 0) trace.outcome = state.outcome;
916
+ if (state.threadId !== void 0) trace.thread_id = state.threadId;
917
+ if (state.userId !== void 0) trace.user_id = state.userId;
918
+ if (state.userMetadata && Object.keys(state.userMetadata).length > 0) {
919
+ trace.user_metadata = state.userMetadata;
920
+ }
921
+ const allSpans = [rootSpan, ...state.completedSpans];
922
+ const spans = allSpans.map((s) => {
923
+ const out2 = {};
924
+ for (const [k, v] of Object.entries(s)) {
925
+ if (v !== void 0 && v !== null) {
926
+ out2[k] = v;
927
+ }
928
+ }
929
+ return out2;
930
+ });
931
+ const config = redactionConfig;
932
+ const out = {
933
+ trace: redactTraceDict(trace, config),
934
+ spans: spans.map((s) => redactSpanDict(s, config))
935
+ };
936
+ const effectiveSource = state.sourceOverride || _source;
937
+ if (effectiveSource) {
938
+ out.resource = { "morse_ai.source": effectiveSource };
939
+ }
940
+ return out;
941
+ }
942
+ function sendTrace(entry) {
943
+ lastTrace = entry;
944
+ if (isLegacyTransport() || false) {
945
+ if (transport !== null) {
946
+ try {
947
+ transport.track({ traces: [entry] });
948
+ } catch {
949
+ }
950
+ }
951
+ return;
952
+ }
953
+ try {
954
+ emitTraceEntry(entry);
955
+ } catch {
956
+ }
957
+ }
958
+ function withDbCaptureContext(traceId, spanIdHex, fn) {
959
+ try {
960
+ return withOtelSpanContext(traceId, spanIdHex.slice(0, 16), fn);
961
+ } catch {
962
+ return fn();
963
+ }
964
+ }
965
+ function buildRunHandle(state) {
966
+ return {
967
+ setOutcome(success, outcome) {
968
+ state.success = success;
969
+ if (outcome !== void 0) state.outcome = outcome;
970
+ },
971
+ setError(message) {
972
+ state.errorMessage = message;
973
+ state.success = false;
974
+ },
975
+ _state: state
976
+ };
977
+ }
978
+ function startTrace(opts) {
979
+ let traceId;
980
+ if (opts.incomingTraceparent) {
981
+ const { extractTraceparent: extractTraceparent2 } = (init_propagation(), __toCommonJS(propagation_exports));
982
+ const ctx = extractTraceparent2(opts.incomingTraceparent);
983
+ if (ctx) {
984
+ traceId = ctx.traceId;
985
+ }
986
+ }
987
+ if (!traceId) traceId = generateTraceId();
988
+ const state = {
989
+ traceId,
990
+ agentName: opts.agentName,
991
+ spanStack: [],
992
+ completedSpans: []
993
+ };
994
+ if (opts.threadId !== void 0) state.threadId = opts.threadId;
995
+ if (opts.userId !== void 0) state.userId = opts.userId;
996
+ if (opts.userMetadata) {
997
+ state.userMetadata = Object.fromEntries(
998
+ Object.entries(opts.userMetadata).map(([k, v]) => [k, String(v)])
999
+ );
1000
+ }
1001
+ if (isValidInternalSource(opts.source)) {
1002
+ state.sourceOverride = opts.source;
1003
+ }
1004
+ const rootSpan = {
1005
+ trace_id: traceId,
1006
+ span_id: generateSpanId(),
1007
+ type: "agent",
1008
+ name: opts.agentName,
1009
+ started_at: nowIso(),
1010
+ status: "completed"
1011
+ };
1012
+ state.spanStack.push(rootSpan);
1013
+ return { state, rootSpan, startMono: nowMonotonic() };
1014
+ }
1015
+ function endTrace(state, rootSpan, startMono, threwError) {
1016
+ state.spanStack.pop();
1017
+ if (threwError !== void 0) {
1018
+ const msg = state.errorMessage ?? errToString(threwError);
1019
+ finalizeSpan(rootSpan, startMono, "failed", msg);
1020
+ if (state.success === void 0) state.success = false;
1021
+ } else if (state.errorMessage !== void 0) {
1022
+ finalizeSpan(rootSpan, startMono, "failed", state.errorMessage);
1023
+ } else {
1024
+ finalizeSpan(rootSpan, startMono);
1025
+ if (state.success === void 0) state.success = true;
1026
+ }
1027
+ const dict = buildTraceDict(state, rootSpan);
1028
+ sendTrace(dict);
1029
+ }
1030
+ function errToString(e) {
1031
+ if (e instanceof Error) return e.message;
1032
+ return String(e);
1033
+ }
1034
+ function runSync(opts, fn) {
1035
+ const { state, rootSpan, startMono } = startTrace(opts);
1036
+ const handle = buildRunHandle(state);
1037
+ const store = tryLoadAls();
1038
+ const runFn = () => withDbCaptureContext(state.traceId, rootSpan.span_id, () => fn(handle));
1039
+ if (store) {
1040
+ try {
1041
+ const result = store.run(state, runFn);
1042
+ endTrace(state, rootSpan, startMono, void 0);
1043
+ return result;
1044
+ } catch (err) {
1045
+ endTrace(state, rootSpan, startMono, err);
1046
+ throw err;
1047
+ }
1048
+ } else {
1049
+ const reset = setActiveTraceState(state);
1050
+ try {
1051
+ const result = runFn();
1052
+ endTrace(state, rootSpan, startMono, void 0);
1053
+ return result;
1054
+ } catch (err) {
1055
+ endTrace(state, rootSpan, startMono, err);
1056
+ throw err;
1057
+ } finally {
1058
+ reset();
1059
+ }
1060
+ }
1061
+ }
1062
+ async function runAsync(opts, fn) {
1063
+ const { state, rootSpan, startMono } = startTrace(opts);
1064
+ const handle = buildRunHandle(state);
1065
+ const store = tryLoadAls();
1066
+ const runFn = () => withDbCaptureContext(state.traceId, rootSpan.span_id, () => fn(handle));
1067
+ if (store) {
1068
+ try {
1069
+ const result = await store.run(state, runFn);
1070
+ endTrace(state, rootSpan, startMono, void 0);
1071
+ return result;
1072
+ } catch (err) {
1073
+ endTrace(state, rootSpan, startMono, err);
1074
+ throw err;
1075
+ }
1076
+ } else {
1077
+ const reset = setActiveTraceState(state);
1078
+ try {
1079
+ const result = await runFn();
1080
+ endTrace(state, rootSpan, startMono, void 0);
1081
+ return result;
1082
+ } catch (err) {
1083
+ endTrace(state, rootSpan, startMono, err);
1084
+ throw err;
1085
+ } finally {
1086
+ reset();
1087
+ }
1088
+ }
1089
+ }
1090
+ function setContext(dims) {
1091
+ const state = getActiveTraceState();
1092
+ if (state === null) return;
1093
+ if (state.userMetadata === void 0) state.userMetadata = {};
1094
+ for (const [k, v] of Object.entries(dims)) {
1095
+ state.userMetadata[k] = String(v);
1096
+ }
1097
+ }
1098
+ function startSpan(opts) {
1099
+ const state = getActiveTraceState();
1100
+ if (state === null) return null;
1101
+ const parent = state.spanStack[state.spanStack.length - 1];
1102
+ const span = {
1103
+ trace_id: state.traceId,
1104
+ span_id: generateSpanId(),
1105
+ type: opts.type ?? "custom",
1106
+ name: opts.name,
1107
+ parent_span_id: parent?.span_id,
1108
+ started_at: nowIso(),
1109
+ status: "completed",
1110
+ metadata: opts.metadata
1111
+ };
1112
+ const startMono = nowMonotonic();
1113
+ state.spanStack.push(span);
1114
+ return {
1115
+ span,
1116
+ end(error) {
1117
+ if (state.spanStack[state.spanStack.length - 1] === span) {
1118
+ state.spanStack.pop();
1119
+ }
1120
+ if (error !== void 0) {
1121
+ finalizeSpan(span, startMono, "failed", errToString(error));
1122
+ } else {
1123
+ finalizeSpan(span, startMono);
1124
+ }
1125
+ state.completedSpans.push(span);
1126
+ }
1127
+ };
1128
+ }
1129
+ function spanSync(opts, fn) {
1130
+ const handle = startSpan(opts);
1131
+ try {
1132
+ const result = handle ? withDbCaptureContext(handle.span.trace_id, handle.span.span_id, () => fn(handle)) : fn(handle);
1133
+ handle?.end();
1134
+ return result;
1135
+ } catch (err) {
1136
+ handle?.end(err);
1137
+ throw err;
1138
+ }
1139
+ }
1140
+ async function spanAsync(opts, fn) {
1141
+ const handle = startSpan(opts);
1142
+ try {
1143
+ const result = handle ? await withDbCaptureContext(handle.span.trace_id, handle.span.span_id, () => fn(handle)) : await fn(handle);
1144
+ handle?.end();
1145
+ return result;
1146
+ } catch (err) {
1147
+ handle?.end(err);
1148
+ throw err;
1149
+ }
1150
+ }
1151
+ function _resetForTesting() {
1152
+ browserState = null;
1153
+ lastTrace = null;
1154
+ redactionConfig = buildRedactionConfig();
1155
+ }
1156
+ var als, alsLoaded, browserState, transport, redactionConfig, _source, lastTrace, SPAN_REDACTABLE_FIELDS, TRACE_REDACTABLE_FIELDS;
1157
+ var init_tracing = __esm({
1158
+ "src/_internal/tracing.ts"() {
1159
+ init_env();
1160
+ init_otel_provider();
1161
+ init_redaction();
1162
+ init_spans();
1163
+ als = null;
1164
+ alsLoaded = false;
1165
+ browserState = null;
1166
+ transport = null;
1167
+ redactionConfig = buildRedactionConfig();
1168
+ _source = null;
1169
+ lastTrace = null;
1170
+ SPAN_REDACTABLE_FIELDS = /* @__PURE__ */ new Set([
1171
+ "name",
1172
+ "input_data",
1173
+ "output_data",
1174
+ "error_message",
1175
+ "metadata"
1176
+ ]);
1177
+ TRACE_REDACTABLE_FIELDS = /* @__PURE__ */ new Set(["agent", "outcome", "error_message"]);
1178
+ }
1179
+ });
1180
+
1181
+ // src/propagation.ts
1182
+ var propagation_exports = {};
1183
+ __export(propagation_exports, {
1184
+ W3C_FLAGS_SAMPLED: () => W3C_FLAGS_SAMPLED,
1185
+ W3C_TRACEPARENT_HEADER: () => exports.W3C_TRACEPARENT_HEADER,
1186
+ W3C_VERSION: () => W3C_VERSION,
1187
+ extractFromRequest: () => extractFromRequest,
1188
+ extractTraceparent: () => extractTraceparent,
1189
+ formatTraceparent: () => formatTraceparent,
1190
+ injectIntoRequestInit: () => injectIntoRequestInit,
1191
+ injectTraceparent: () => injectTraceparent
1192
+ });
1193
+ function formatTraceparent(traceId, spanId) {
1194
+ const tid = traceId.slice(0, TRACE_ID_LEN).padStart(TRACE_ID_LEN, "0").toLowerCase();
1195
+ const sid = spanId.slice(0, SPAN_ID_LEN).padStart(SPAN_ID_LEN, "0").toLowerCase();
1196
+ return `${W3C_VERSION}-${tid}-${sid}-${W3C_FLAGS_SAMPLED}`;
1197
+ }
1198
+ function injectTraceparent(headers) {
1199
+ const state = getActiveTraceState();
1200
+ if (state === null) return headers;
1201
+ const traceId = state.traceId;
1202
+ const span = state.spanStack.length > 0 ? state.spanStack[state.spanStack.length - 1] : state.completedSpans[state.completedSpans.length - 1];
1203
+ const rawSpanId = span?.span_id ?? traceId;
1204
+ const spanId = rawSpanId.slice(0, SPAN_ID_LEN);
1205
+ const value = formatTraceparent(traceId, spanId);
1206
+ setHeader(headers, exports.W3C_TRACEPARENT_HEADER, value);
1207
+ return headers;
1208
+ }
1209
+ function extractTraceparent(headers) {
1210
+ if (headers === null || headers === void 0) return null;
1211
+ const raw = typeof headers === "string" ? headers : getHeader(headers, exports.W3C_TRACEPARENT_HEADER);
1212
+ if (!raw) return null;
1213
+ const parts = raw.split("-");
1214
+ if (parts.length !== 4) return null;
1215
+ const [version, traceId, spanId] = parts;
1216
+ if (version !== W3C_VERSION) return null;
1217
+ if (traceId.length !== TRACE_ID_LEN) return null;
1218
+ if (spanId.length !== SPAN_ID_LEN) return null;
1219
+ if (!/^[0-9a-f]+$/.test(traceId)) return null;
1220
+ if (!/^[0-9a-f]+$/.test(spanId)) return null;
1221
+ if (/^0+$/.test(traceId)) return null;
1222
+ if (/^0+$/.test(spanId)) return null;
1223
+ return { traceId, parentSpanId: spanId };
1224
+ }
1225
+ function extractFromRequest(req) {
1226
+ return extractTraceparent(req.headers);
1227
+ }
1228
+ function injectIntoRequestInit(init) {
1229
+ const merged = new Headers(init?.headers ?? {});
1230
+ injectTraceparent(merged);
1231
+ return { ...init ?? {}, headers: merged };
1232
+ }
1233
+ function getHeader(headers, name) {
1234
+ if (headers instanceof Headers) {
1235
+ return headers.get(name);
1236
+ }
1237
+ const maybeGet = headers.get;
1238
+ if (typeof maybeGet === "function") {
1239
+ const v = maybeGet.call(headers, name);
1240
+ if (typeof v === "string") return v;
1241
+ if (v === null || v === void 0) return null;
1242
+ }
1243
+ const lower = name.toLowerCase();
1244
+ for (const [k, v] of Object.entries(headers)) {
1245
+ if (k.toLowerCase() === lower) {
1246
+ if (typeof v === "string") return v;
1247
+ if (Array.isArray(v) && v.length > 0 && typeof v[0] === "string") return v[0];
1248
+ return null;
1249
+ }
1250
+ }
1251
+ return null;
1252
+ }
1253
+ function setHeader(headers, name, value) {
1254
+ if (headers instanceof Headers) {
1255
+ headers.set(name, value);
1256
+ return;
1257
+ }
1258
+ const maybeSet = headers.set;
1259
+ if (typeof maybeSet === "function") {
1260
+ maybeSet.call(headers, name, value);
1261
+ return;
1262
+ }
1263
+ headers[name] = value;
1264
+ }
1265
+ exports.W3C_TRACEPARENT_HEADER = void 0; var W3C_VERSION, W3C_FLAGS_SAMPLED, TRACE_ID_LEN, SPAN_ID_LEN;
1266
+ var init_propagation = __esm({
1267
+ "src/propagation.ts"() {
1268
+ init_tracing();
1269
+ exports.W3C_TRACEPARENT_HEADER = "traceparent";
1270
+ W3C_VERSION = "00";
1271
+ W3C_FLAGS_SAMPLED = "01";
1272
+ TRACE_ID_LEN = 32;
1273
+ SPAN_ID_LEN = 16;
1274
+ }
1275
+ });
1276
+
1277
+ exports._resetForTesting = _resetForTesting;
1278
+ exports.buildRedactionConfig = buildRedactionConfig;
1279
+ exports.buildTraceEntry = buildTraceEntry;
1280
+ exports.extractTraceparent = extractTraceparent;
1281
+ exports.formatTraceparent = formatTraceparent;
1282
+ exports.generateSpanId = generateSpanId;
1283
+ exports.generateTraceId = generateTraceId;
1284
+ exports.getActiveTraceState = getActiveTraceState;
1285
+ exports.getApiKey = getApiKey;
1286
+ exports.getEndpoint = getEndpoint;
1287
+ exports.getEngine = getEngine;
1288
+ exports.getFlushIntervalSeconds = getFlushIntervalSeconds;
1289
+ exports.getInternalSource = getInternalSource;
1290
+ exports.getLastTrace = getLastTrace;
1291
+ exports.getMaxBatchSize = getMaxBatchSize;
1292
+ exports.getMaxFieldBytes = getMaxFieldBytes;
1293
+ exports.getMaxQueueSize = getMaxQueueSize;
1294
+ exports.getRedactionConfig = getRedactionConfig;
1295
+ exports.getSampleRate = getSampleRate;
1296
+ exports.getTransport = getTransport;
1297
+ exports.init_env = init_env;
1298
+ exports.init_otel_provider = init_otel_provider;
1299
+ exports.init_propagation = init_propagation;
1300
+ exports.init_redaction = init_redaction;
1301
+ exports.init_spans = init_spans;
1302
+ exports.init_tracing = init_tracing;
1303
+ exports.injectIntoRequestInit = injectIntoRequestInit;
1304
+ exports.injectTraceparent = injectTraceparent;
1305
+ exports.isAutoDetectDisabled = isAutoDetectDisabled;
1306
+ exports.isDbCaptureEnabled = isDbCaptureEnabled;
1307
+ exports.isDebug = isDebug;
1308
+ exports.isDisabled = isDisabled;
1309
+ exports.isTelemetryDisabled = isTelemetryDisabled;
1310
+ exports.isValidInternalSource = isValidInternalSource;
1311
+ exports.nowIso = nowIso;
1312
+ exports.redactValue = redactValue;
1313
+ exports.runAsync = runAsync;
1314
+ exports.runSync = runSync;
1315
+ exports.sendTrace = sendTrace;
1316
+ exports.setContext = setContext;
1317
+ exports.setRedactionConfig = setRedactionConfig;
1318
+ exports.setSource = setSource;
1319
+ exports.setTransport = setTransport;
1320
+ exports.spanAsync = spanAsync;
1321
+ exports.spanSync = spanSync;
1322
+ exports.startSpan = startSpan;
1323
+ //# sourceMappingURL=chunk-FJUNILZT.cjs.map
1324
+ //# sourceMappingURL=chunk-FJUNILZT.cjs.map