@kortyx/telemetry 0.11.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.12.0](https://github.com/kortyx-io/kortyx/compare/telemetry-v0.11.2...telemetry-v0.12.0) (2026-10-08)
4
+
5
+
6
+ ### Features
7
+
8
+ * **telemetry:** preserve complete private error diagnostics ([#290](https://github.com/kortyx-io/kortyx/issues/290)) ([e1c5a88](https://github.com/kortyx-io/kortyx/commit/e1c5a88c494016fd84a1af40579412fcfde31271))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @kortyx/hooks bumped to 0.31.0
16
+ * @kortyx/telemetry-contracts bumped to 0.15.0
17
+ * @kortyx/core bumped to 0.12.0
18
+
3
19
  ## [0.11.2](https://github.com/kortyx-io/kortyx/compare/telemetry-v0.11.1...telemetry-v0.11.2) (2026-10-07)
4
20
 
5
21
 
package/README.md CHANGED
@@ -48,8 +48,9 @@ available without enabling content capture.
48
48
 
49
49
  Delivery is best-effort and at-least-once while the process remains alive. The
50
50
  adapter batches events, retries transient failures, and exposes `flush()` for
51
- controlled shutdown. It has no durable outbox; applications that need durable
52
- delivery must own that outbox themselves. Telemetry failures never fail a
51
+ controlled shutdown. Ordinary events have no durable outbox; applications that
52
+ need durable event delivery must own that outbox themselves. Complete diagnostics
53
+ have a separate opt-in upload queue and optional Node spool. Telemetry failures never fail a
53
54
  workflow execution.
54
55
 
55
56
  `interrupt.expired` is intentionally API-derived from the durable `expiresAt`
@@ -67,3 +68,17 @@ values and resume capability tokens are never included in interrupt telemetry.
67
68
  `run.cancelled` records aborted active executions. Custom HTTP routes must forward
68
69
  `request.signal`; `createChatRouteHandler` forwards it automatically. Cancelling a
69
70
  `toSSE` response body also cancels its active execution source.
71
+
72
+ ## Complete error diagnostics
73
+
74
+ Set `diagnostics: { enabled: true }` on `createKortyxTelemetryAdapter` after
75
+ upgrading the API/Studio and granting `diagnostics:read` to the Studio reader.
76
+ Native capture retains large messages/stacks, causes, aggregate members, custom
77
+ fields, and private provider response evidence with credential redaction. Run
78
+ errors link to one diagnostic; native upload parts do not become timeline events.
79
+
80
+ Studio and `kortyx studio diagnostics get|download` retrieve complete content
81
+ without application chunk reconstruction. Capture and delivery limits are explicit,
82
+ and `flushDiagnostics(timeoutMs)` reports pending and dropped delivery. See the
83
+ [deployment and usage guide](../../docs/complete-error-diagnostics.md) for limits,
84
+ permissions, spool/retention operations, privacy policy, and rollout instructions.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import * as _kortyx_hooks from '@kortyx/hooks';
2
2
  import { KortyxTelemetryService, KortyxTelemetryConfig } from '@kortyx/hooks';
3
3
 
4
+ type DiagnosticDeliveryState = "pending" | "available" | "rejected" | "dropped" | "spool_failed";
5
+
4
6
  type CreateKortyxTelemetryAdapterOptions = {
5
7
  endpoint: string;
6
8
  apiKey: string;
@@ -8,6 +10,13 @@ type CreateKortyxTelemetryAdapterOptions = {
8
10
  service: KortyxTelemetryService;
9
11
  /** Optional replacement or suppression of captured error diagnostics. */
10
12
  error?: _kortyx_hooks.KortyxTraceErrorProjection;
13
+ /** Opt in to complete redacted diagnostics stored by Studio's diagnostic API. */
14
+ diagnostics?: {
15
+ enabled: boolean;
16
+ /** Optional secure persistent queue for Node process-restart recovery. */
17
+ spoolDirectory?: string;
18
+ maxQueueBytes?: number;
19
+ };
11
20
  captureContent?: KortyxTelemetryConfig["captureContent"] | undefined;
12
21
  metadata?: Record<string, unknown> | undefined;
13
22
  tags?: string[] | undefined;
@@ -17,8 +26,17 @@ type CreateKortyxTelemetryAdapterOptions = {
17
26
  };
18
27
  type KortyxTelemetryAdapter = KortyxTelemetryConfig & {
19
28
  flush: () => Promise<void>;
29
+ flushDiagnostics: (timeoutMs?: number) => Promise<{
30
+ timedOut: boolean;
31
+ pending: number;
32
+ pendingBytes: number;
33
+ dropped: number;
34
+ states: Record<string, DiagnosticDeliveryState>;
35
+ }>;
20
36
  getDroppedEventCount: () => number;
21
37
  getPermanentDeliveryFailureCount: () => number;
38
+ getDiagnosticDeliveryState: (id: string) => DiagnosticDeliveryState | undefined;
39
+ getDroppedDiagnosticCount: () => number;
22
40
  };
23
41
 
24
42
  /**
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ __export(index_exports, {
24
24
  module.exports = __toCommonJS(index_exports);
25
25
 
26
26
  // src/adapter.ts
27
- var import_node_crypto = require("crypto");
27
+ var import_node_crypto2 = require("crypto");
28
28
 
29
29
  // src/delivery.ts
30
30
  var TelemetryHttpError = class extends Error {
@@ -131,30 +131,338 @@ var createDelivery = (args) => {
131
131
  };
132
132
  };
133
133
 
134
- // src/event-mapper.ts
134
+ // src/diagnostics.ts
135
+ var import_node_crypto = require("crypto");
136
+ var import_promises = require("fs/promises");
137
+ var import_node_path = require("path");
135
138
  var import_errors = require("@kortyx/core/errors");
136
139
  var import_internal = require("@kortyx/hooks/internal");
140
+ var import_telemetry_contracts = require("@kortyx/telemetry-contracts");
141
+ function createDiagnosticDelivery(options) {
142
+ const enabled = options.diagnostics?.enabled === true;
143
+ const queue = /* @__PURE__ */ new Map();
144
+ const states = /* @__PURE__ */ new Map();
145
+ const captured = /* @__PURE__ */ new WeakMap();
146
+ let queuedBytes = 0;
147
+ let dropped = 0;
148
+ let retryAt = 0;
149
+ let timer;
150
+ let inFlight;
151
+ const writes = /* @__PURE__ */ new Set();
152
+ const spool = options.diagnostics?.spoolDirectory ? (0, import_node_path.join)(
153
+ options.diagnostics.spoolDirectory,
154
+ // A stable credential-scoped namespace without storing the API key or
155
+ // a fast credential hash on disk. Only derived when spooling is enabled.
156
+ (0, import_node_crypto.scryptSync)(
157
+ options.apiKey,
158
+ JSON.stringify([options.endpoint, options.environment]),
159
+ 24
160
+ ).toString("hex")
161
+ ) : void 0;
162
+ const state = (id, value) => {
163
+ states.set(id, value);
164
+ if (states.size > 1e3) states.delete(states.keys().next().value);
165
+ };
166
+ const maxBytes = options.diagnostics?.maxQueueBytes ?? 16 * 1024 * 1024;
167
+ const persist = async (entry) => {
168
+ if (!spool) return;
169
+ await (0, import_promises.mkdir)(spool, { recursive: true, mode: 448 });
170
+ const target = (0, import_node_path.join)(spool, `${entry.manifest.diagnosticId}.json`);
171
+ const temporary = `${target}.${(0, import_node_crypto.randomUUID)()}.tmp`;
172
+ await (0, import_promises.writeFile)(temporary, JSON.stringify(entry), { mode: 384 });
173
+ await (0, import_promises.rename)(temporary, target);
174
+ };
175
+ const schedule = () => {
176
+ if (!enabled || timer || inFlight || !queue.size) return;
177
+ timer = setTimeout(() => {
178
+ timer = void 0;
179
+ void flush();
180
+ }, options.flushIntervalMs ?? 250);
181
+ timer.unref?.();
182
+ };
183
+ const restored = (async () => {
184
+ if (!enabled || !spool) return;
185
+ try {
186
+ await (0, import_promises.mkdir)(spool, { recursive: true, mode: 448 });
187
+ for (const filename of (await (0, import_promises.readdir)(spool)).filter(
188
+ (name) => /^[a-f0-9-]{36}\.json$/.test(name)
189
+ )) {
190
+ try {
191
+ if ((await (0, import_promises.stat)((0, import_node_path.join)(spool, filename))).size > import_telemetry_contracts.DIAGNOSTIC_LIMITS.bytes + 64 * 1024)
192
+ throw new Error("Spool file exceeds budget");
193
+ const value = JSON.parse(
194
+ await (0, import_promises.readFile)((0, import_node_path.join)(spool, filename), "utf8")
195
+ );
196
+ const manifest = import_telemetry_contracts.DiagnosticManifestSchema.parse(value.manifest);
197
+ const bytes = Buffer.byteLength(value.content);
198
+ if (bytes !== manifest.byteLength || (0, import_node_crypto.createHash)("sha256").update(value.content).digest("hex") !== manifest.checksum)
199
+ throw new Error("Invalid spool content");
200
+ import_telemetry_contracts.DiagnosticContentSchema.parse(JSON.parse(value.content));
201
+ if (queuedBytes + bytes > maxBytes) {
202
+ state(manifest.diagnosticId, "dropped");
203
+ dropped++;
204
+ await (0, import_promises.unlink)((0, import_node_path.join)(spool, filename));
205
+ continue;
206
+ }
207
+ if (!queue.has(manifest.diagnosticId)) {
208
+ queue.set(manifest.diagnosticId, {
209
+ manifest,
210
+ content: value.content
211
+ });
212
+ queuedBytes += bytes;
213
+ state(manifest.diagnosticId, "pending");
214
+ }
215
+ } catch {
216
+ dropped++;
217
+ await (0, import_promises.unlink)((0, import_node_path.join)(spool, filename)).catch(() => void 0);
218
+ }
219
+ }
220
+ schedule();
221
+ } catch {
222
+ dropped++;
223
+ }
224
+ })();
225
+ const send = async (path, body) => {
226
+ const response = await (options.fetch ?? globalThis.fetch)(
227
+ `${options.endpoint.replace(/\/$/, "")}/v1/telemetry/diagnostics${path}?env=${encodeURIComponent(options.environment)}`,
228
+ {
229
+ method: "POST",
230
+ headers: {
231
+ authorization: `Bearer ${options.apiKey}`,
232
+ "content-type": "application/json"
233
+ },
234
+ body: JSON.stringify(body),
235
+ signal: AbortSignal.timeout(15e3)
236
+ }
237
+ );
238
+ if (!response.ok) {
239
+ const error = new Error("Diagnostic delivery failed.");
240
+ error.status = response.status;
241
+ if (response.status === 429) {
242
+ const hint = response.headers.get("retry-after");
243
+ const seconds = Number(hint);
244
+ const delay = hint && Number.isFinite(seconds) ? seconds * 1e3 : hint ? Date.parse(hint) - Date.now() : 5e3;
245
+ retryAt = Date.now() + Math.min(
246
+ 6e4,
247
+ Math.max(5e3, Number.isFinite(delay) ? delay : 5e3)
248
+ );
249
+ }
250
+ throw error;
251
+ }
252
+ return response;
253
+ };
254
+ const flush = async () => {
255
+ await restored;
256
+ await Promise.all([...writes]);
257
+ if (inFlight) {
258
+ await inFlight;
259
+ return;
260
+ }
261
+ if (timer) {
262
+ clearTimeout(timer);
263
+ timer = void 0;
264
+ }
265
+ const work = async () => {
266
+ if (Date.now() < retryAt) return;
267
+ for (const [id, entry] of [...queue]) {
268
+ try {
269
+ await send("", entry.manifest);
270
+ const bytes = Buffer.from(entry.content);
271
+ for (let index = 0; index < entry.manifest.partCount; index++)
272
+ await send(`/${id}/parts`, {
273
+ index,
274
+ data: bytes.subarray(
275
+ index * import_telemetry_contracts.DIAGNOSTIC_LIMITS.partBytes,
276
+ (index + 1) * import_telemetry_contracts.DIAGNOSTIC_LIMITS.partBytes
277
+ ).toString("base64")
278
+ });
279
+ const completed = await send(`/${id}/complete`, {});
280
+ const acknowledgement = await completed.json();
281
+ if (acknowledgement.state !== "available") {
282
+ const error = new Error(
283
+ "Diagnostic integrity verification failed."
284
+ );
285
+ error.status = 422;
286
+ throw error;
287
+ }
288
+ state(id, "available");
289
+ queue.delete(id);
290
+ queuedBytes -= entry.manifest.byteLength;
291
+ if (spool)
292
+ await (0, import_promises.unlink)((0, import_node_path.join)(spool, `${id}.json`)).catch(() => void 0);
293
+ } catch (error) {
294
+ const status = error.status;
295
+ if (status && status < 500 && status !== 429) {
296
+ state(id, "rejected");
297
+ queue.delete(id);
298
+ queuedBytes -= entry.manifest.byteLength;
299
+ dropped++;
300
+ if (spool)
301
+ await (0, import_promises.unlink)((0, import_node_path.join)(spool, `${id}.json`)).catch(() => void 0);
302
+ }
303
+ if (status === 429) break;
304
+ }
305
+ }
306
+ };
307
+ inFlight = work();
308
+ try {
309
+ await inFlight;
310
+ } finally {
311
+ inFlight = void 0;
312
+ }
313
+ if (queue.size) {
314
+ timer = setTimeout(
315
+ () => {
316
+ timer = void 0;
317
+ void flush();
318
+ },
319
+ Math.max(5e3, retryAt - Date.now())
320
+ );
321
+ timer.unref?.();
322
+ }
323
+ };
324
+ const capture = (error, context) => {
325
+ if (!enabled || (0, import_errors.isControlFlowError)(error)) return void 0;
326
+ const scope = JSON.stringify([
327
+ context.correlation?.runId,
328
+ context.correlation?.invocationId,
329
+ context.correlation?.branchId,
330
+ context.correlation?.attemptId
331
+ ]);
332
+ const object = error && typeof error === "object" ? error : void 0;
333
+ const existing = object ? captured.get(object)?.get(scope) : void 0;
334
+ if (existing)
335
+ return {
336
+ ...existing,
337
+ diagnosticDelivery: existing.diagnosticId ? states.get(existing.diagnosticId) ?? "pending" : void 0
338
+ };
339
+ const content = (0, import_internal.captureDiagnosticContent)(
340
+ error,
341
+ context.project ?? options.error
342
+ );
343
+ if (!content) return { diagnosticCapture: "suppressed", details: null };
344
+ const serialized = JSON.stringify(content);
345
+ const diagnosticId = (0, import_node_crypto.randomUUID)();
346
+ const manifest = import_telemetry_contracts.DiagnosticManifestSchema.parse({
347
+ schemaVersion: 1,
348
+ diagnosticId,
349
+ occurrenceId: (0, import_node_crypto.randomUUID)(),
350
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
351
+ environment: options.environment,
352
+ service: options.service,
353
+ correlation: import_telemetry_contracts.DiagnosticCorrelationSchema.parse(
354
+ Object.fromEntries(
355
+ Object.entries(context.correlation ?? {}).filter(
356
+ ([key]) => key !== "topologyHash"
357
+ )
358
+ )
359
+ ),
360
+ handled: context.handled,
361
+ severity: context.severity,
362
+ mechanism: context.mechanism,
363
+ summary: {
364
+ type: String(content.data.type ?? "Error").slice(0, 256),
365
+ message: (0, import_telemetry_contracts.summarizeDiagnostic)(content.data).message
366
+ },
367
+ captureStatus: content.capture.status,
368
+ byteLength: Buffer.byteLength(serialized),
369
+ checksum: (0, import_node_crypto.createHash)("sha256").update(serialized).digest("hex"),
370
+ partCount: Math.ceil(
371
+ Buffer.byteLength(serialized) / import_telemetry_contracts.DIAGNOSTIC_LIMITS.partBytes
372
+ )
373
+ });
374
+ if (queuedBytes + manifest.byteLength > maxBytes) {
375
+ state(diagnosticId, "dropped");
376
+ dropped++;
377
+ } else {
378
+ const entry = { manifest, content: serialized };
379
+ queue.set(diagnosticId, entry);
380
+ queuedBytes += manifest.byteLength;
381
+ state(diagnosticId, "pending");
382
+ const writing = persist(entry).catch(() => {
383
+ state(diagnosticId, "spool_failed");
384
+ }).finally(() => {
385
+ writes.delete(writing);
386
+ });
387
+ writes.add(writing);
388
+ schedule();
389
+ }
390
+ const result = {
391
+ diagnosticId,
392
+ diagnosticCapture: content.capture.status,
393
+ diagnosticDelivery: states.get(diagnosticId),
394
+ details: (0, import_telemetry_contracts.summarizeDiagnostic)(content.data)
395
+ };
396
+ if (object) {
397
+ const byScope = captured.get(object) ?? /* @__PURE__ */ new Map();
398
+ byScope.set(scope, result);
399
+ captured.set(object, byScope);
400
+ }
401
+ return result;
402
+ };
403
+ const flushWithDeadline = async (timeoutMs = 5e3) => {
404
+ let deadline;
405
+ let timedOut = false;
406
+ await Promise.race([
407
+ flush(),
408
+ new Promise((resolve) => {
409
+ deadline = setTimeout(
410
+ () => {
411
+ timedOut = true;
412
+ resolve();
413
+ },
414
+ Math.max(0, timeoutMs)
415
+ );
416
+ })
417
+ ]);
418
+ if (deadline) clearTimeout(deadline);
419
+ return {
420
+ timedOut,
421
+ pending: queue.size,
422
+ pendingBytes: queuedBytes,
423
+ dropped,
424
+ states: Object.fromEntries(states)
425
+ };
426
+ };
427
+ return {
428
+ capture,
429
+ flush,
430
+ flushWithDeadline,
431
+ getState: (id) => states.get(id),
432
+ getDroppedCount: () => dropped
433
+ };
434
+ }
435
+
436
+ // src/event-mapper.ts
437
+ var import_errors2 = require("@kortyx/core/errors");
438
+ var import_internal2 = require("@kortyx/hooks/internal");
439
+ var import_telemetry_contracts2 = require("@kortyx/telemetry-contracts");
137
440
  var stringValue = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
138
441
  var shouldCapture = (value, side) => {
139
442
  if (value === true) return true;
140
443
  return Boolean(value && typeof value === "object" && value[side]);
141
444
  };
142
- var asErrorPayload = (error, project) => {
143
- if ((0, import_errors.isControlFlowError)(error))
445
+ var asErrorPayload = (error, project, captured) => {
446
+ if ((0, import_errors2.isControlFlowError)(error))
144
447
  return {
145
- name: (0, import_errors.errorProperty)(error, "name"),
146
- code: (0, import_errors.errorProperty)(error, "code"),
448
+ name: (0, import_errors2.errorProperty)(error, "name"),
449
+ code: (0, import_errors2.errorProperty)(error, "code"),
147
450
  message: "Execution paused or cancelled.",
148
451
  controlFlow: true
149
452
  };
150
- const failure = (0, import_errors.serializeFailure)(error);
151
- const diagnostic = (0, import_internal.exceptionDiagnostics)(error, project);
453
+ const failure = (0, import_errors2.serializeFailure)(error);
454
+ const diagnostic = captured ? captured.details : (0, import_internal2.exceptionDiagnostics)(error, project);
455
+ const summary = diagnostic ? (0, import_telemetry_contracts2.summarizeDiagnostic)(diagnostic) : null;
456
+ const reference = captured ? Object.fromEntries(
457
+ Object.entries(captured).filter(([key]) => key !== "details")
458
+ ) : {};
152
459
  return {
153
460
  ...failure,
154
- name: diagnostic?.type ?? "Error",
155
- message: diagnostic?.message ?? failure.message,
156
- ...diagnostic?.stack ? { stack: diagnostic.stack } : {},
157
- ...diagnostic?.cause ? { cause: diagnostic.cause } : {}
461
+ name: summary?.type ?? "Error",
462
+ message: summary?.message ?? failure.message,
463
+ ...summary?.stack ? { stack: summary.stack } : {},
464
+ ...summary?.cause ? { cause: summary.cause } : {},
465
+ ...reference
158
466
  };
159
467
  };
160
468
  var correlationFrom = (attributes, active) => {
@@ -197,7 +505,7 @@ var createEventMapper = (args) => {
197
505
  ...input.context || args.metadata || args.tags ? {
198
506
  context: {
199
507
  ...args.tags ? { tags: args.tags } : {},
200
- ...args.metadata ? { metadata: (0, import_internal.safeTelemetryMetadata)(args.metadata) } : {},
508
+ ...args.metadata ? { metadata: (0, import_internal2.safeTelemetryMetadata)(args.metadata) } : {},
201
509
  ...input.context ?? {}
202
510
  }
203
511
  } : {},
@@ -211,7 +519,7 @@ var createEventMapper = (args) => {
211
519
  });
212
520
  const spanContext = (telemetry, attributes) => {
213
521
  const tags = [...args.tags ?? [], ...telemetry?.tags ?? []];
214
- const metadata = (0, import_internal.safeTelemetryMetadata)({
522
+ const metadata = (0, import_internal2.safeTelemetryMetadata)({
215
523
  ...args.metadata ?? {},
216
524
  ...telemetry?.metadata ?? {}
217
525
  });
@@ -227,7 +535,7 @@ var createEventMapper = (args) => {
227
535
  const telemetryPayload = (telemetry) => ({
228
536
  ...telemetry?.operation ? { operation: telemetry.operation } : {},
229
537
  ...telemetry?.tags?.length ? { tags: telemetry.tags } : {},
230
- ...telemetry?.metadata ? { metadata: (0, import_internal.safeTelemetryMetadata)(telemetry.metadata) } : {},
538
+ ...telemetry?.metadata ? { metadata: (0, import_internal2.safeTelemetryMetadata)(telemetry.metadata) } : {},
231
539
  ...telemetry?.prompt ? {
232
540
  prompt: {
233
541
  ...telemetry.prompt.name ? { name: telemetry.prompt.name } : {},
@@ -238,7 +546,11 @@ var createEventMapper = (args) => {
238
546
  } : {}
239
547
  });
240
548
  return {
241
- asErrorPayload: (error) => asErrorPayload(error, args.error),
549
+ asErrorPayload: (error, context) => asErrorPayload(
550
+ error,
551
+ context?.project ?? args.error,
552
+ context ? args.captureDiagnostic?.(error, context) : void 0
553
+ ),
242
554
  correlationFrom,
243
555
  createEvent,
244
556
  shouldCapture,
@@ -287,8 +599,8 @@ var createTopologyResolver = (args) => {
287
599
 
288
600
  // src/trace.ts
289
601
  var import_node_async_hooks = require("async_hooks");
290
- var import_errors2 = require("@kortyx/core/errors");
291
- var import_telemetry_contracts = require("@kortyx/telemetry-contracts");
602
+ var import_errors3 = require("@kortyx/core/errors");
603
+ var import_telemetry_contracts3 = require("@kortyx/telemetry-contracts");
292
604
  var providerPricing = (metadata) => {
293
605
  if (metadata?.providerId !== "openrouter") return void 0;
294
606
  const details = metadata.costDetails;
@@ -322,7 +634,7 @@ var createTraceAdapter = (args) => {
322
634
  correlation,
323
635
  span,
324
636
  ...parent ? { parentSpanId: parent.spanId } : {},
325
- payload: isTool ? import_telemetry_contracts.ToolObservationSchema.parse(attributes) : {
637
+ payload: isTool ? import_telemetry_contracts3.ToolObservationSchema.parse(attributes) : {
326
638
  name: startArgs.name,
327
639
  attributes: currentAttributes,
328
640
  telemetry: args.eventMapper.telemetryPayload(
@@ -354,7 +666,7 @@ var createTraceAdapter = (args) => {
354
666
  const telemetry = endArgs?.telemetry ?? startArgs.telemetry;
355
667
  const durationMs = Date.now() - startedAt;
356
668
  if (isTool) {
357
- const payload = import_telemetry_contracts.ToolObservationSchema.parse(endAttributes);
669
+ const payload = import_telemetry_contracts3.ToolObservationSchema.parse(endAttributes);
358
670
  const type = payload.observationKind === "reused" ? "tool.reused" : payload.observationKind === "waiting" ? "tool.waiting" : payload.suspended ? "tool.suspended" : payload.outcome === "denied" ? "tool.denied" : payload.outcome === "fault" ? "tool.failed" : payload.outcome === "cancelled" ? "tool.cancelled" : "tool.completed";
359
671
  args.enqueue(
360
672
  args.eventMapper.createEvent({
@@ -475,7 +787,7 @@ var createTraceAdapter = (args) => {
475
787
  end,
476
788
  fail: (error, endArgs) => {
477
789
  if (ended) return;
478
- if ((0, import_errors2.isSuspensionControlFlowError)(error)) {
790
+ if ((0, import_errors3.isSuspensionControlFlowError)(error)) {
479
791
  suspended = true;
480
792
  Object.assign(currentAttributes, {
481
793
  "kortyx.control_flow": true,
@@ -485,6 +797,12 @@ var createTraceAdapter = (args) => {
485
797
  return;
486
798
  }
487
799
  failed = true;
800
+ const errorPayload = args.eventMapper.asErrorPayload(error, {
801
+ correlation: { ...correlation, ...span },
802
+ handled: false,
803
+ severity: "error",
804
+ mechanism: "span"
805
+ });
488
806
  if (correlation) {
489
807
  args.enqueue(
490
808
  args.eventMapper.createEvent({
@@ -494,7 +812,7 @@ var createTraceAdapter = (args) => {
494
812
  ...parent ? { parentSpanId: parent.spanId } : {},
495
813
  payload: {
496
814
  name: startArgs.name,
497
- error: args.eventMapper.asErrorPayload(error),
815
+ error: errorPayload,
498
816
  handled: false,
499
817
  severity: "error",
500
818
  durationMs: Date.now() - startedAt
@@ -536,7 +854,19 @@ var createTraceAdapter = (args) => {
536
854
  reportError: (error, options = {}) => {
537
855
  try {
538
856
  const active = activeSpans.getStore();
539
- if (!active) return;
857
+ const payload = args.eventMapper.asErrorPayload(error, {
858
+ correlation: {
859
+ ...active?.correlation,
860
+ ...active ? { traceId: active.traceId, spanId: active.spanId } : {},
861
+ ...options.correlation
862
+ },
863
+ handled: true,
864
+ severity: options.severity === "warning" ? "warning" : "error",
865
+ mechanism: options.mechanism ?? "report",
866
+ project: options.error
867
+ });
868
+ if (!active)
869
+ return typeof payload.diagnosticId === "string" ? payload.diagnosticId : void 0;
540
870
  args.enqueue(
541
871
  args.eventMapper.createEvent({
542
872
  type: "error.reported",
@@ -545,7 +875,7 @@ var createTraceAdapter = (args) => {
545
875
  payload: {
546
876
  handled: true,
547
877
  severity: options.severity === "warning" ? "warning" : "error",
548
- error: args.eventMapper.asErrorPayload(error)
878
+ error: payload
549
879
  },
550
880
  context: args.eventMapper.spanContext(
551
881
  {
@@ -556,7 +886,9 @@ var createTraceAdapter = (args) => {
556
886
  )
557
887
  })
558
888
  );
889
+ return typeof payload.diagnosticId === "string" ? payload.diagnosticId : void 0;
559
890
  } catch {
891
+ return void 0;
560
892
  }
561
893
  }
562
894
  };
@@ -568,7 +900,7 @@ var DEFAULT_FLUSH_INTERVAL_MS = 250;
568
900
  var DEFAULT_MAX_QUEUE_SIZE = 1e3;
569
901
  var createId = () => {
570
902
  try {
571
- return (0, import_node_crypto.randomUUID)();
903
+ return (0, import_node_crypto2.randomUUID)();
572
904
  } catch {
573
905
  return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
574
906
  }
@@ -600,12 +932,14 @@ function createKortyxTelemetryAdapter(options) {
600
932
  await send("/v1/telemetry/events:batch", { events });
601
933
  }
602
934
  });
935
+ const diagnostics = createDiagnosticDelivery(options);
603
936
  const eventMapper = createEventMapper({
604
937
  environment: options.environment,
605
938
  service: options.service,
606
939
  ...options.metadata ? { metadata: options.metadata } : {},
607
940
  ...options.tags ? { tags: options.tags } : {},
608
941
  createId,
942
+ captureDiagnostic: diagnostics.capture,
609
943
  ...options.error ? { error: options.error } : {}
610
944
  });
611
945
  const topology = createTopologyResolver({
@@ -638,7 +972,13 @@ function createKortyxTelemetryAdapter(options) {
638
972
  ...options.captureContent ? { captureContent: options.captureContent } : {},
639
973
  ...options.metadata ? { metadata: options.metadata } : {},
640
974
  ...options.tags ? { tags: options.tags } : {},
641
- flush: delivery.flush,
975
+ flush: async () => {
976
+ await delivery.flush();
977
+ await diagnostics.flush();
978
+ },
979
+ flushDiagnostics: diagnostics.flushWithDeadline,
980
+ getDiagnosticDeliveryState: diagnostics.getState,
981
+ getDroppedDiagnosticCount: diagnostics.getDroppedCount,
642
982
  getDroppedEventCount: delivery.getDroppedEventCount,
643
983
  getPermanentDeliveryFailureCount: delivery.getPermanentDeliveryFailureCount
644
984
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/delivery.ts","../src/event-mapper.ts","../src/topology.ts","../src/trace.ts"],"sourcesContent":["export { createKortyxTelemetryAdapter } from \"./adapter\";\nexport type {\n CreateKortyxTelemetryAdapterOptions,\n KortyxTelemetryAdapter,\n} from \"./types\";\n","import { randomUUID } from \"node:crypto\";\nimport type {\n EnsureWorkflowTopologyResponse,\n KortyxTelemetryEvent,\n} from \"@kortyx/hooks\";\nimport { createDelivery, TelemetryHttpError } from \"./delivery\";\nimport { createEventMapper } from \"./event-mapper\";\nimport { createTopologyResolver } from \"./topology\";\nimport { createTraceAdapter } from \"./trace\";\nimport type {\n CreateKortyxTelemetryAdapterOptions,\n KortyxTelemetryAdapter,\n} from \"./types\";\n\nexport type {\n CreateKortyxTelemetryAdapterOptions,\n KortyxTelemetryAdapter,\n} from \"./types\";\n\nconst DEFAULT_FLUSH_INTERVAL_MS = 250;\nconst DEFAULT_MAX_QUEUE_SIZE = 1_000;\n\nconst createId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nconst endpointFor = (endpoint: string, path: string): string =>\n `${endpoint.replace(/\\/$/, \"\")}${path}`;\n\n/**\n * Creates the optional Kortyx Studio HTTP adapter. Execution paths only enqueue\n * telemetry; delivery remains best-effort and cannot fail a workflow.\n */\nexport function createKortyxTelemetryAdapter(\n options: CreateKortyxTelemetryAdapterOptions,\n): KortyxTelemetryAdapter {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n \"createKortyxTelemetryAdapter requires a fetch implementation.\",\n );\n }\n\n const send = async (path: string, body: unknown): Promise<Response> => {\n const response = await fetchImpl(endpointFor(options.endpoint, path), {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${options.apiKey}`,\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new TelemetryHttpError(response.status);\n return response;\n };\n\n const delivery = createDelivery({\n maxQueueSize: options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE,\n flushIntervalMs: options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,\n send: async (events) => {\n await send(\"/v1/telemetry/events:batch\", { events });\n },\n });\n const eventMapper = createEventMapper({\n environment: options.environment,\n service: options.service,\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.tags ? { tags: options.tags } : {}),\n createId,\n ...(options.error ? { error: options.error } : {}),\n });\n const topology = createTopologyResolver({\n ensure: async (snapshot) => {\n const response = await send(\n \"/v1/telemetry/workflow-revisions:ensure\",\n snapshot,\n );\n return (await response.json()) as EnsureWorkflowTopologyResponse;\n },\n });\n const trace = createTraceAdapter({\n ...(options.captureContent\n ? { captureContent: options.captureContent }\n : {}),\n createId,\n enqueue: delivery.enqueue,\n eventMapper,\n });\n const emit = async (events: KortyxTelemetryEvent[]): Promise<void> => {\n for (const event of events) delivery.enqueue(event);\n };\n\n return {\n trace,\n reporter: {\n ensureWorkflowTopology: topology.ensureWorkflowTopology,\n emit,\n getWorkflowRevisionId: topology.getWorkflowRevisionId,\n },\n environment: options.environment,\n service: options.service,\n ...(options.captureContent\n ? { captureContent: options.captureContent }\n : {}),\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.tags ? { tags: options.tags } : {}),\n flush: delivery.flush,\n getDroppedEventCount: delivery.getDroppedEventCount,\n getPermanentDeliveryFailureCount: delivery.getPermanentDeliveryFailureCount,\n };\n}\n","import type { KortyxTelemetryEvent } from \"@kortyx/hooks\";\n\nexport class TelemetryHttpError extends Error {\n constructor(readonly status: number) {\n super(`Kortyx telemetry request failed (${status}).`);\n }\n}\n\nexport const createDelivery = (args: {\n maxQueueSize: number;\n flushIntervalMs: number;\n send: (events: KortyxTelemetryEvent[]) => Promise<void>;\n}) => {\n const queue: KortyxTelemetryEvent[] = [];\n let dropped = 0;\n let permanentFailures = 0;\n let retryAttempt = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let inFlight: Promise<{ retryDelay: number | null }> | undefined;\n const sendBatch = async (events: KortyxTelemetryEvent[]): Promise<void> => {\n try {\n await args.send(events);\n } catch (error) {\n const status =\n error instanceof TelemetryHttpError ? error.status : undefined;\n // One invalid event (or an oversized request) must not discard the other\n // lifecycle facts in the same flush. Event IDs make a later retry safe.\n if (\n events.length > 1 &&\n (status === 400 || status === 413 || status === 422)\n ) {\n const middle = Math.floor(events.length / 2);\n await sendBatch(events.slice(0, middle));\n await sendBatch(events.slice(middle));\n return;\n }\n if (\n events.length === 1 &&\n status !== undefined &&\n status !== 429 &&\n status < 500\n ) {\n permanentFailures += 1;\n return;\n }\n throw error;\n }\n };\n const schedule = (delay = args.flushIntervalMs) => {\n if (timer || inFlight || queue.length === 0) return;\n timer = setTimeout(() => {\n timer = undefined;\n void flush();\n }, delay);\n if (typeof timer === \"object\" && \"unref\" in timer) timer.unref?.();\n };\n const flush = async (): Promise<void> => {\n while (true) {\n if (inFlight) {\n const result = await inFlight;\n if (result.retryDelay !== null) return;\n continue;\n }\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n if (queue.length === 0) return;\n const events = queue.splice(0);\n const current = (async (): Promise<{ retryDelay: number | null }> => {\n try {\n await sendBatch(events);\n retryAttempt = 0;\n return { retryDelay: null };\n } catch (error) {\n const status =\n error instanceof TelemetryHttpError ? error.status : undefined;\n if (status !== undefined && status !== 429 && status < 500) {\n permanentFailures += events.length;\n return { retryDelay: null };\n }\n const overflow = Math.max(\n 0,\n queue.length + events.length - args.maxQueueSize,\n );\n if (overflow) {\n dropped += overflow;\n events.splice(0, overflow);\n }\n queue.unshift(...events);\n retryAttempt += 1;\n const backoff = Math.min(30_000, 250 * 2 ** (retryAttempt - 1));\n return {\n retryDelay: Math.floor(backoff * (0.5 + Math.random() * 0.5)),\n };\n }\n })();\n inFlight = current;\n const result = await current;\n if (inFlight === current) inFlight = undefined;\n if (result.retryDelay !== null) {\n schedule(result.retryDelay);\n return;\n }\n }\n };\n return {\n enqueue: (event: KortyxTelemetryEvent) => {\n if (queue.length >= args.maxQueueSize) {\n queue.shift();\n dropped += 1;\n }\n queue.push(event);\n schedule();\n },\n flush,\n getDroppedEventCount: () => dropped,\n getPermanentDeliveryFailureCount: () => permanentFailures,\n };\n};\n","import {\n errorProperty,\n isControlFlowError,\n serializeFailure,\n} from \"@kortyx/core/errors\";\nimport type {\n KortyxTelemetryConfig,\n KortyxTelemetryEvent,\n KortyxTelemetryEventType,\n ReasonTraceAttributes,\n ReasonTraceSpanStartArgs,\n} from \"@kortyx/hooks\";\nimport {\n exceptionDiagnostics,\n safeTelemetryMetadata,\n} from \"@kortyx/hooks/internal\";\nimport type { ActiveSpan, SpanContext } from \"./types\";\n\nconst stringValue = (value: unknown): string | undefined =>\n typeof value === \"string\" && value.length > 0 ? value : undefined;\n\nconst shouldCapture = (\n value: KortyxTelemetryConfig[\"captureContent\"] | undefined,\n side: \"input\" | \"output\",\n): boolean => {\n if (value === true) return true;\n return Boolean(value && typeof value === \"object\" && value[side]);\n};\n\nconst asErrorPayload = (\n error: unknown,\n project?: import(\"@kortyx/hooks\").KortyxTraceErrorProjection,\n): Record<string, unknown> => {\n if (isControlFlowError(error))\n return {\n name: errorProperty(error, \"name\"),\n code: errorProperty(error, \"code\"),\n message: \"Execution paused or cancelled.\",\n controlFlow: true,\n };\n const failure = serializeFailure(error);\n const diagnostic = exceptionDiagnostics(error, project);\n return {\n ...failure,\n name: diagnostic?.type ?? \"Error\",\n message: diagnostic?.message ?? failure.message,\n ...(diagnostic?.stack ? { stack: diagnostic.stack } : {}),\n ...(diagnostic?.cause ? { cause: diagnostic.cause } : {}),\n };\n};\n\nconst correlationFrom = (\n attributes: ReasonTraceAttributes | undefined,\n active: ActiveSpan | undefined,\n): KortyxTelemetryEvent[\"correlation\"] | undefined => {\n const source = attributes ?? {};\n const runId = stringValue(source.runId) ?? active?.correlation.runId;\n const workflowId =\n stringValue(source.workflowId) ?? active?.correlation.workflowId;\n if (!runId || !workflowId) return undefined;\n\n const sameWorkflow = workflowId === active?.correlation.workflowId;\n const sessionId =\n stringValue(source.sessionId) ?? active?.correlation.sessionId;\n const workflowRevisionId =\n stringValue(source.workflowRevisionId) ??\n (sameWorkflow ? active?.correlation.workflowRevisionId : undefined);\n const topologyHash =\n stringValue(source.topologyHash) ??\n (sameWorkflow ? active?.correlation.topologyHash : undefined);\n const nodeId =\n stringValue(source.nodeId) ??\n (sameWorkflow ? active?.correlation.nodeId : undefined);\n return {\n runId,\n workflowId,\n ...Object.fromEntries(\n [\"invocationId\", \"parentInvocationId\", \"branchId\"].flatMap((key) => {\n const value =\n stringValue(source[key]) ??\n active?.correlation[key as \"invocationId\"];\n return value ? [[key, value]] : [];\n }),\n ),\n ...(sessionId ? { sessionId } : {}),\n ...(workflowRevisionId ? { workflowRevisionId } : {}),\n ...(topologyHash ? { topologyHash } : {}),\n ...(nodeId ? { nodeId } : {}),\n };\n};\n\nexport const createEventMapper = (args: {\n environment: string;\n service: KortyxTelemetryEvent[\"service\"];\n metadata?: Record<string, unknown> | undefined;\n tags?: string[] | undefined;\n createId: () => string;\n error?: import(\"@kortyx/hooks\").KortyxTraceErrorProjection;\n}) => {\n const createEvent = (input: {\n type: KortyxTelemetryEventType;\n correlation: KortyxTelemetryEvent[\"correlation\"];\n span?: SpanContext | undefined;\n parentSpanId?: string | undefined;\n payload: Record<string, unknown>;\n context?: KortyxTelemetryEvent[\"context\"] | undefined;\n }): KortyxTelemetryEvent => ({\n schemaVersion: 1,\n eventId: args.createId(),\n occurredAt: new Date().toISOString(),\n environment: args.environment,\n service: args.service,\n correlation: {\n ...input.correlation,\n ...(input.span\n ? { traceId: input.span.traceId, spanId: input.span.spanId }\n : {}),\n ...(input.parentSpanId ? { parentSpanId: input.parentSpanId } : {}),\n },\n ...(input.context || args.metadata || args.tags\n ? {\n context: {\n ...(args.tags ? { tags: args.tags } : {}),\n ...(args.metadata\n ? { metadata: safeTelemetryMetadata(args.metadata) }\n : {}),\n ...(input.context ?? {}),\n },\n }\n : {}),\n type: input.type,\n payload: {\n ...input.payload,\n ...(input.correlation.invocationId\n ? { invocationId: input.correlation.invocationId }\n : {}),\n ...(input.correlation.parentInvocationId\n ? { parentInvocationId: input.correlation.parentInvocationId }\n : {}),\n ...(input.correlation.branchId\n ? { branchId: input.correlation.branchId }\n : {}),\n },\n });\n\n const spanContext = (\n telemetry: ReasonTraceSpanStartArgs[\"telemetry\"] | undefined,\n attributes: ReasonTraceAttributes,\n ): KortyxTelemetryEvent[\"context\"] | undefined => {\n const tags = [...(args.tags ?? []), ...(telemetry?.tags ?? [])];\n const metadata = safeTelemetryMetadata({\n ...(args.metadata ?? {}),\n ...(telemetry?.metadata ?? {}),\n });\n const userId = stringValue(attributes.userId);\n const tenantId = stringValue(attributes.tenantId);\n return userId || tenantId || tags.length || Object.keys(metadata).length\n ? {\n ...(userId ? { userId } : {}),\n ...(tenantId ? { tenantId } : {}),\n ...(tags.length ? { tags } : {}),\n ...(Object.keys(metadata).length ? { metadata } : {}),\n }\n : undefined;\n };\n\n const telemetryPayload = (\n telemetry: ReasonTraceSpanStartArgs[\"telemetry\"] | undefined,\n ): Record<string, unknown> => ({\n ...(telemetry?.operation ? { operation: telemetry.operation } : {}),\n ...(telemetry?.tags?.length ? { tags: telemetry.tags } : {}),\n ...(telemetry?.metadata\n ? { metadata: safeTelemetryMetadata(telemetry.metadata) }\n : {}),\n ...(telemetry?.prompt\n ? {\n prompt: {\n ...(telemetry.prompt.name ? { name: telemetry.prompt.name } : {}),\n ...(telemetry.prompt.version !== undefined\n ? { version: telemetry.prompt.version }\n : {}),\n ...(telemetry.prompt.type ? { type: telemetry.prompt.type } : {}),\n ...(telemetry.prompt.source\n ? { source: telemetry.prompt.source }\n : {}),\n },\n }\n : {}),\n });\n\n return {\n asErrorPayload: (error: unknown) => asErrorPayload(error, args.error),\n correlationFrom,\n createEvent,\n shouldCapture,\n spanContext,\n stringValue,\n telemetryPayload,\n };\n};\n","import type {\n EnsureWorkflowTopologyRequest,\n EnsureWorkflowTopologyResponse,\n} from \"@kortyx/hooks\";\n\ntype TopologyKey = {\n environment: string;\n workflowId: string;\n topologyHash: string;\n};\n\nconst keyFor = ({ environment, workflowId, topologyHash }: TopologyKey) =>\n `${environment}:${workflowId}:${topologyHash}`;\n\n/** Caches successful topology ensures and coalesces concurrent requests. */\nexport const createTopologyResolver = (args: {\n ensure: (\n snapshot: EnsureWorkflowTopologyRequest,\n ) => Promise<EnsureWorkflowTopologyResponse>;\n}) => {\n const revisions = new Map<string, string>();\n const pending = new Map<string, Promise<EnsureWorkflowTopologyResponse>>();\n\n const ensureWorkflowTopology = (\n snapshot: EnsureWorkflowTopologyRequest,\n ): Promise<EnsureWorkflowTopologyResponse> => {\n const key = keyFor({\n environment: snapshot.environment,\n workflowId: snapshot.workflow.id,\n topologyHash: snapshot.workflow.topologyHash,\n });\n const revision = revisions.get(key);\n if (revision) {\n return Promise.resolve({ workflowRevisionId: revision, created: false });\n }\n\n const existing = pending.get(key);\n if (existing) return existing;\n\n const request = args\n .ensure(snapshot)\n .then((result) => {\n if (!result.workflowRevisionId) {\n throw new Error(\n \"Telemetry API returned an invalid workflow revision.\",\n );\n }\n revisions.set(key, result.workflowRevisionId);\n return result;\n })\n .finally(() => {\n pending.delete(key);\n });\n pending.set(key, request);\n return request;\n };\n\n return {\n ensureWorkflowTopology,\n getWorkflowRevisionId: (args: TopologyKey) => revisions.get(keyFor(args)),\n };\n};\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { isSuspensionControlFlowError } from \"@kortyx/core/errors\";\nimport type {\n KortyxTelemetryConfig,\n KortyxTelemetryEvent,\n ReasonTraceAdapter,\n ReasonTraceSpan,\n ReasonTraceSpanEndArgs,\n ReasonTraceSpanStartArgs,\n} from \"@kortyx/hooks\";\nimport { ToolObservationSchema } from \"@kortyx/telemetry-contracts\";\nimport type { createEventMapper } from \"./event-mapper\";\nimport type { ActiveSpan, SpanContext } from \"./types\";\n\nconst providerPricing = (\n metadata: ReasonTraceSpanEndArgs[\"providerMetadata\"],\n): Record<string, unknown> | undefined => {\n if (metadata?.providerId !== \"openrouter\") return undefined;\n const details = metadata.costDetails;\n const upstreamCost =\n details && typeof details === \"object\" && !Array.isArray(details)\n ? (details as Record<string, unknown>).upstreamInferenceCost\n : undefined;\n const cost = metadata.isByok === true ? upstreamCost : metadata.cost;\n if (typeof cost !== \"number\" || !Number.isFinite(cost) || cost < 0)\n return undefined;\n return {\n source: \"provider\",\n currency: \"USD\",\n actualCostMicros: Math.round(cost * 1_000_000),\n };\n};\n\n/** Maps generic SDK trace calls to Kortyx Studio's span and generation facts. */\nexport const createTraceAdapter = (args: {\n captureContent?: KortyxTelemetryConfig[\"captureContent\"] | undefined;\n createId: () => string;\n enqueue: (event: KortyxTelemetryEvent) => void;\n eventMapper: ReturnType<typeof createEventMapper>;\n}): ReasonTraceAdapter => {\n const activeSpans = new AsyncLocalStorage<ActiveSpan>();\n\n const createSpan = (\n startArgs: ReasonTraceSpanStartArgs,\n ): { span: ReasonTraceSpan; active?: ActiveSpan | undefined } => {\n const parent = activeSpans.getStore();\n const span: SpanContext = {\n traceId: parent?.traceId ?? args.createId(),\n spanId: args.createId(),\n };\n const attributes = { ...(startArgs.attributes ?? {}) };\n const currentAttributes = { ...attributes };\n const correlation = args.eventMapper.correlationFrom(attributes, parent);\n const startedAt = Date.now();\n\n const isTool = startArgs.name === \"kortyx.tool\";\n if (correlation && (!isTool || attributes.executed === true)) {\n args.enqueue(\n args.eventMapper.createEvent({\n type: isTool ? \"tool.started\" : \"span.started\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: isTool\n ? ToolObservationSchema.parse(attributes)\n : {\n name: startArgs.name,\n attributes: currentAttributes,\n telemetry: args.eventMapper.telemetryPayload(\n startArgs.telemetry,\n ),\n ...(args.eventMapper.shouldCapture(\n startArgs.telemetry?.captureContent ?? args.captureContent,\n \"input\",\n )\n ? { input: startArgs.telemetry?.input }\n : {}),\n },\n context: args.eventMapper.spanContext(\n startArgs.telemetry,\n currentAttributes,\n ),\n }),\n );\n }\n\n let ended = false;\n let failed = false;\n let suspended = false;\n const end = (endArgs?: ReasonTraceSpanEndArgs): void => {\n if (ended) return;\n ended = true;\n if (!correlation) return;\n\n const endAttributes = {\n ...currentAttributes,\n ...(endArgs?.attributes ?? {}),\n };\n const telemetry = endArgs?.telemetry ?? startArgs.telemetry;\n const durationMs = Date.now() - startedAt;\n if (isTool) {\n const payload = ToolObservationSchema.parse(endAttributes);\n const type =\n payload.observationKind === \"reused\"\n ? \"tool.reused\"\n : payload.observationKind === \"waiting\"\n ? \"tool.waiting\"\n : payload.suspended\n ? \"tool.suspended\"\n : payload.outcome === \"denied\"\n ? \"tool.denied\"\n : payload.outcome === \"fault\"\n ? \"tool.failed\"\n : payload.outcome === \"cancelled\"\n ? \"tool.cancelled\"\n : \"tool.completed\";\n args.enqueue(\n args.eventMapper.createEvent({\n type,\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload,\n }),\n );\n return;\n }\n\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"span.ended\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: {\n name: startArgs.name,\n attributes: endAttributes,\n durationMs,\n telemetry: args.eventMapper.telemetryPayload(telemetry),\n ...(args.eventMapper.shouldCapture(\n endArgs?.telemetry?.captureContent ??\n startArgs.telemetry?.captureContent ??\n args.captureContent,\n \"output\",\n )\n ? { output: endArgs?.telemetry?.output }\n : {}),\n },\n context: args.eventMapper.spanContext(telemetry, endAttributes),\n }),\n );\n\n if (startArgs.name !== \"runReasonEngine\" || suspended) return;\n const ttftMs = nonnegativeNumber(endAttributes.ttftMs);\n const streamDurationMs = nonnegativeNumber(\n endAttributes.streamDurationMs,\n );\n const timeToLastTokenMs = nonnegativeNumber(\n endAttributes.timeToLastTokenMs,\n );\n const pricing = providerPricing(endArgs?.providerMetadata);\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"generation.completed\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: {\n outcome: failed ? \"failed\" : \"completed\",\n provider:\n args.eventMapper.stringValue(attributes.providerId) ?? \"unknown\",\n model:\n args.eventMapper.stringValue(attributes.modelId) ?? \"unknown\",\n durationMs,\n ...(ttftMs !== undefined ? { ttftMs } : {}),\n ...(streamDurationMs !== undefined ? { streamDurationMs } : {}),\n ...(timeToLastTokenMs !== undefined\n ? {\n postStreamDurationMs: Math.max(\n 0,\n durationMs - timeToLastTokenMs,\n ),\n }\n : {}),\n ...(endArgs?.usage\n ? {\n usage: failed\n ? Object.fromEntries(\n Object.entries(endArgs.usage).filter(\n ([key, value]) =>\n ([\n \"input\",\n \"output\",\n \"total\",\n \"reasoning\",\n \"cacheRead\",\n \"cacheWrite\",\n \"cacheWrite1h\",\n ].includes(key) &&\n typeof value === \"number\" &&\n Number.isFinite(value)) ||\n ([\n \"outputIncludesReasoning\",\n \"inputIncludesCacheRead\",\n \"inputIncludesCacheWrite\",\n ].includes(key) &&\n typeof value === \"boolean\"),\n ),\n )\n : endArgs.usage,\n }\n : {}),\n ...(endArgs?.finishReason\n ? { finishReason: endArgs.finishReason }\n : {}),\n ...(endArgs?.warnings ? { warnings: endArgs.warnings } : {}),\n ...(pricing ? { pricing } : {}),\n ...(endArgs?.providerMetadata && !failed\n ? { providerMetadata: endArgs.providerMetadata }\n : {}),\n },\n context: args.eventMapper.spanContext(telemetry, currentAttributes),\n }),\n );\n };\n\n const traceSpan: ReasonTraceSpan = {\n setAttributes: (nextAttributes) => {\n Object.assign(currentAttributes, nextAttributes);\n },\n addEvent: (name, eventAttributes = {}) => {\n if (\n !correlation ||\n activeSpans.getStore()?.name === \"kortyx.tool\" ||\n startArgs.name === \"kortyx.tool\"\n )\n return;\n const type =\n name === \"useReason.tool-call.start\"\n ? \"tool.started\"\n : name === \"useReason.tool-call.complete\"\n ? \"tool.completed\"\n : name === \"useReason.tool-call.error\"\n ? \"tool.failed\"\n : name === \"useReason.output.emitted\"\n ? \"output.emitted\"\n : name === \"useReason.output.invalidated\"\n ? \"output.invalidated\"\n : undefined;\n if (!type) return;\n const payload =\n type === \"output.emitted\"\n ? {\n ...Object.fromEntries(\n Object.entries(eventAttributes).filter(\n ([key]) => key !== \"data\",\n ),\n ),\n ...(args.eventMapper.shouldCapture(\n startArgs.telemetry?.captureContent ?? args.captureContent,\n \"output\",\n ) && \"data\" in eventAttributes\n ? { data: eventAttributes.data }\n : {}),\n }\n : eventAttributes;\n args.enqueue(\n args.eventMapper.createEvent({\n type,\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload,\n }),\n );\n },\n end,\n fail: (error, endArgs) => {\n if (ended) return;\n if (isSuspensionControlFlowError(error)) {\n suspended = true;\n Object.assign(currentAttributes, {\n \"kortyx.control_flow\": true,\n \"kortyx.suspended\": true,\n });\n end(endArgs);\n return;\n }\n failed = true;\n if (correlation) {\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"span.failed\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: {\n name: startArgs.name,\n error: args.eventMapper.asErrorPayload(error),\n handled: false,\n severity: \"error\",\n durationMs: Date.now() - startedAt,\n },\n }),\n );\n }\n end(endArgs);\n },\n };\n\n return {\n span: traceSpan,\n ...(correlation\n ? { active: { ...span, name: startArgs.name, correlation } }\n : {}),\n };\n };\n\n return {\n startSpan: (startArgs) => createSpan(startArgs).span,\n withSpan: async (startArgs, fn) => {\n const created = createSpan(startArgs);\n const run = async (): Promise<Awaited<ReturnType<typeof fn>>> => {\n try {\n const result = await fn(created.span);\n created.span.end?.();\n return result;\n } catch (error) {\n try {\n created.span.fail?.(error);\n } catch {\n /* Preserve the callback failure. */\n }\n throw error;\n }\n };\n return created.active ? activeSpans.run(created.active, run) : run();\n },\n getActiveContext: () => {\n const active = activeSpans.getStore();\n return active\n ? { traceId: active.traceId, spanId: active.spanId }\n : undefined;\n },\n reportError: (error, options = {}) => {\n try {\n const active = activeSpans.getStore();\n if (!active) return;\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"error.reported\",\n correlation: active.correlation,\n span: active,\n payload: {\n handled: true,\n severity: options.severity === \"warning\" ? \"warning\" : \"error\",\n error: args.eventMapper.asErrorPayload(error),\n },\n context: args.eventMapper.spanContext(\n {\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.tags ? { tags: options.tags } : {}),\n },\n {},\n ),\n }),\n );\n } catch {\n // Error reporting is an observer and cannot change execution.\n }\n },\n };\n};\n\nconst nonnegativeNumber = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? value\n : undefined;\n"],"mappings":"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","names":["result","args","import_errors"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/delivery.ts","../src/diagnostics.ts","../src/event-mapper.ts","../src/topology.ts","../src/trace.ts"],"sourcesContent":["export { createKortyxTelemetryAdapter } from \"./adapter\";\nexport type {\n CreateKortyxTelemetryAdapterOptions,\n KortyxTelemetryAdapter,\n} from \"./types\";\n","import { randomUUID } from \"node:crypto\";\nimport type {\n EnsureWorkflowTopologyResponse,\n KortyxTelemetryEvent,\n} from \"@kortyx/hooks\";\nimport { createDelivery, TelemetryHttpError } from \"./delivery\";\nimport { createDiagnosticDelivery } from \"./diagnostics\";\nimport { createEventMapper } from \"./event-mapper\";\nimport { createTopologyResolver } from \"./topology\";\nimport { createTraceAdapter } from \"./trace\";\nimport type {\n CreateKortyxTelemetryAdapterOptions,\n KortyxTelemetryAdapter,\n} from \"./types\";\n\nexport type {\n CreateKortyxTelemetryAdapterOptions,\n KortyxTelemetryAdapter,\n} from \"./types\";\n\nconst DEFAULT_FLUSH_INTERVAL_MS = 250;\nconst DEFAULT_MAX_QUEUE_SIZE = 1_000;\n\nconst createId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nconst endpointFor = (endpoint: string, path: string): string =>\n `${endpoint.replace(/\\/$/, \"\")}${path}`;\n\n/**\n * Creates the optional Kortyx Studio HTTP adapter. Execution paths only enqueue\n * telemetry; delivery remains best-effort and cannot fail a workflow.\n */\nexport function createKortyxTelemetryAdapter(\n options: CreateKortyxTelemetryAdapterOptions,\n): KortyxTelemetryAdapter {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n \"createKortyxTelemetryAdapter requires a fetch implementation.\",\n );\n }\n\n const send = async (path: string, body: unknown): Promise<Response> => {\n const response = await fetchImpl(endpointFor(options.endpoint, path), {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${options.apiKey}`,\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new TelemetryHttpError(response.status);\n return response;\n };\n\n const delivery = createDelivery({\n maxQueueSize: options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE,\n flushIntervalMs: options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,\n send: async (events) => {\n await send(\"/v1/telemetry/events:batch\", { events });\n },\n });\n const diagnostics = createDiagnosticDelivery(options);\n const eventMapper = createEventMapper({\n environment: options.environment,\n service: options.service,\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.tags ? { tags: options.tags } : {}),\n createId,\n captureDiagnostic: diagnostics.capture,\n ...(options.error ? { error: options.error } : {}),\n });\n const topology = createTopologyResolver({\n ensure: async (snapshot) => {\n const response = await send(\n \"/v1/telemetry/workflow-revisions:ensure\",\n snapshot,\n );\n return (await response.json()) as EnsureWorkflowTopologyResponse;\n },\n });\n const trace = createTraceAdapter({\n ...(options.captureContent\n ? { captureContent: options.captureContent }\n : {}),\n createId,\n enqueue: delivery.enqueue,\n eventMapper,\n });\n const emit = async (events: KortyxTelemetryEvent[]): Promise<void> => {\n for (const event of events) delivery.enqueue(event);\n };\n\n return {\n trace,\n reporter: {\n ensureWorkflowTopology: topology.ensureWorkflowTopology,\n emit,\n getWorkflowRevisionId: topology.getWorkflowRevisionId,\n },\n environment: options.environment,\n service: options.service,\n ...(options.captureContent\n ? { captureContent: options.captureContent }\n : {}),\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.tags ? { tags: options.tags } : {}),\n flush: async () => {\n await delivery.flush();\n await diagnostics.flush();\n },\n flushDiagnostics: diagnostics.flushWithDeadline,\n getDiagnosticDeliveryState: diagnostics.getState,\n getDroppedDiagnosticCount: diagnostics.getDroppedCount,\n getDroppedEventCount: delivery.getDroppedEventCount,\n getPermanentDeliveryFailureCount: delivery.getPermanentDeliveryFailureCount,\n };\n}\n","import type { KortyxTelemetryEvent } from \"@kortyx/hooks\";\n\nexport class TelemetryHttpError extends Error {\n constructor(readonly status: number) {\n super(`Kortyx telemetry request failed (${status}).`);\n }\n}\n\nexport const createDelivery = (args: {\n maxQueueSize: number;\n flushIntervalMs: number;\n send: (events: KortyxTelemetryEvent[]) => Promise<void>;\n}) => {\n const queue: KortyxTelemetryEvent[] = [];\n let dropped = 0;\n let permanentFailures = 0;\n let retryAttempt = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let inFlight: Promise<{ retryDelay: number | null }> | undefined;\n const sendBatch = async (events: KortyxTelemetryEvent[]): Promise<void> => {\n try {\n await args.send(events);\n } catch (error) {\n const status =\n error instanceof TelemetryHttpError ? error.status : undefined;\n // One invalid event (or an oversized request) must not discard the other\n // lifecycle facts in the same flush. Event IDs make a later retry safe.\n if (\n events.length > 1 &&\n (status === 400 || status === 413 || status === 422)\n ) {\n const middle = Math.floor(events.length / 2);\n await sendBatch(events.slice(0, middle));\n await sendBatch(events.slice(middle));\n return;\n }\n if (\n events.length === 1 &&\n status !== undefined &&\n status !== 429 &&\n status < 500\n ) {\n permanentFailures += 1;\n return;\n }\n throw error;\n }\n };\n const schedule = (delay = args.flushIntervalMs) => {\n if (timer || inFlight || queue.length === 0) return;\n timer = setTimeout(() => {\n timer = undefined;\n void flush();\n }, delay);\n if (typeof timer === \"object\" && \"unref\" in timer) timer.unref?.();\n };\n const flush = async (): Promise<void> => {\n while (true) {\n if (inFlight) {\n const result = await inFlight;\n if (result.retryDelay !== null) return;\n continue;\n }\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n if (queue.length === 0) return;\n const events = queue.splice(0);\n const current = (async (): Promise<{ retryDelay: number | null }> => {\n try {\n await sendBatch(events);\n retryAttempt = 0;\n return { retryDelay: null };\n } catch (error) {\n const status =\n error instanceof TelemetryHttpError ? error.status : undefined;\n if (status !== undefined && status !== 429 && status < 500) {\n permanentFailures += events.length;\n return { retryDelay: null };\n }\n const overflow = Math.max(\n 0,\n queue.length + events.length - args.maxQueueSize,\n );\n if (overflow) {\n dropped += overflow;\n events.splice(0, overflow);\n }\n queue.unshift(...events);\n retryAttempt += 1;\n const backoff = Math.min(30_000, 250 * 2 ** (retryAttempt - 1));\n return {\n retryDelay: Math.floor(backoff * (0.5 + Math.random() * 0.5)),\n };\n }\n })();\n inFlight = current;\n const result = await current;\n if (inFlight === current) inFlight = undefined;\n if (result.retryDelay !== null) {\n schedule(result.retryDelay);\n return;\n }\n }\n };\n return {\n enqueue: (event: KortyxTelemetryEvent) => {\n if (queue.length >= args.maxQueueSize) {\n queue.shift();\n dropped += 1;\n }\n queue.push(event);\n schedule();\n },\n flush,\n getDroppedEventCount: () => dropped,\n getPermanentDeliveryFailureCount: () => permanentFailures,\n };\n};\n","import { createHash, randomUUID, scryptSync } from \"node:crypto\";\nimport {\n mkdir,\n readdir,\n readFile,\n rename,\n stat,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { isControlFlowError } from \"@kortyx/core/errors\";\nimport type { KortyxTraceErrorProjection } from \"@kortyx/hooks\";\nimport { captureDiagnosticContent } from \"@kortyx/hooks/internal\";\nimport {\n DIAGNOSTIC_LIMITS,\n DiagnosticContentSchema,\n DiagnosticCorrelationSchema,\n type DiagnosticManifest,\n DiagnosticManifestSchema,\n summarizeDiagnostic,\n} from \"@kortyx/telemetry-contracts\";\nimport type { CreateKortyxTelemetryAdapterOptions } from \"./types\";\n\nexport type DiagnosticDeliveryState =\n | \"pending\"\n | \"available\"\n | \"rejected\"\n | \"dropped\"\n | \"spool_failed\";\nexport type DiagnosticCaptureContext = {\n correlation?: DiagnosticManifest[\"correlation\"] | undefined;\n handled: boolean;\n severity: \"warning\" | \"error\";\n mechanism: DiagnosticManifest[\"mechanism\"];\n project?: KortyxTraceErrorProjection | undefined;\n};\ntype Entry = { manifest: DiagnosticManifest; content: string };\n\n/** Independent diagnostic transport. It never changes application execution. */\nexport function createDiagnosticDelivery(\n options: CreateKortyxTelemetryAdapterOptions,\n) {\n const enabled = options.diagnostics?.enabled === true;\n const queue = new Map<string, Entry>();\n const states = new Map<string, DiagnosticDeliveryState>();\n type CaptureResult = {\n diagnosticId?: string;\n diagnosticCapture: string;\n diagnosticDelivery?: DiagnosticDeliveryState | undefined;\n details: Record<string, unknown> | null;\n };\n const captured = new WeakMap<object, Map<string, CaptureResult>>();\n let queuedBytes = 0;\n let dropped = 0;\n let retryAt = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let inFlight: Promise<void> | undefined;\n const writes = new Set<Promise<void>>();\n const spool = options.diagnostics?.spoolDirectory\n ? join(\n options.diagnostics.spoolDirectory,\n // A stable credential-scoped namespace without storing the API key or\n // a fast credential hash on disk. Only derived when spooling is enabled.\n scryptSync(\n options.apiKey,\n JSON.stringify([options.endpoint, options.environment]),\n 24,\n ).toString(\"hex\"),\n )\n : undefined;\n const state = (id: string, value: DiagnosticDeliveryState) => {\n states.set(id, value);\n if (states.size > 1000) states.delete(states.keys().next().value as string);\n };\n const maxBytes = options.diagnostics?.maxQueueBytes ?? 16 * 1024 * 1024;\n const persist = async (entry: Entry) => {\n if (!spool) return;\n await mkdir(spool, { recursive: true, mode: 0o700 });\n const target = join(spool, `${entry.manifest.diagnosticId}.json`);\n const temporary = `${target}.${randomUUID()}.tmp`;\n await writeFile(temporary, JSON.stringify(entry), { mode: 0o600 });\n await rename(temporary, target);\n };\n const schedule = () => {\n if (!enabled || timer || inFlight || !queue.size) return;\n timer = setTimeout(() => {\n timer = undefined;\n void flush();\n }, options.flushIntervalMs ?? 250);\n timer.unref?.();\n };\n const restored = (async () => {\n if (!enabled || !spool) return;\n try {\n await mkdir(spool, { recursive: true, mode: 0o700 });\n for (const filename of (await readdir(spool)).filter((name) =>\n /^[a-f0-9-]{36}\\.json$/.test(name),\n )) {\n try {\n if (\n (await stat(join(spool, filename))).size >\n DIAGNOSTIC_LIMITS.bytes + 64 * 1024\n )\n throw new Error(\"Spool file exceeds budget\");\n const value = JSON.parse(\n await readFile(join(spool, filename), \"utf8\"),\n ) as Entry;\n const manifest = DiagnosticManifestSchema.parse(value.manifest);\n const bytes = Buffer.byteLength(value.content);\n if (\n bytes !== manifest.byteLength ||\n createHash(\"sha256\").update(value.content).digest(\"hex\") !==\n manifest.checksum\n )\n throw new Error(\"Invalid spool content\");\n DiagnosticContentSchema.parse(JSON.parse(value.content));\n if (queuedBytes + bytes > maxBytes) {\n state(manifest.diagnosticId, \"dropped\");\n dropped++;\n await unlink(join(spool, filename));\n continue;\n }\n if (!queue.has(manifest.diagnosticId)) {\n queue.set(manifest.diagnosticId, {\n manifest,\n content: value.content,\n });\n queuedBytes += bytes;\n state(manifest.diagnosticId, \"pending\");\n }\n } catch {\n dropped++;\n await unlink(join(spool, filename)).catch(() => undefined);\n }\n }\n schedule();\n } catch {\n dropped++;\n }\n })();\n const send = async (path: string, body: unknown) => {\n const response = await (options.fetch ?? globalThis.fetch)(\n `${options.endpoint.replace(/\\/$/, \"\")}/v1/telemetry/diagnostics${path}?env=${encodeURIComponent(options.environment)}`,\n {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${options.apiKey}`,\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(15_000),\n },\n );\n if (!response.ok) {\n const error = new Error(\"Diagnostic delivery failed.\") as Error & {\n status: number;\n };\n error.status = response.status;\n if (response.status === 429) {\n const hint = response.headers.get(\"retry-after\");\n const seconds = Number(hint);\n const delay =\n hint && Number.isFinite(seconds)\n ? seconds * 1000\n : hint\n ? Date.parse(hint) - Date.now()\n : 5000;\n retryAt =\n Date.now() +\n Math.min(\n 60_000,\n Math.max(5000, Number.isFinite(delay) ? delay : 5000),\n );\n }\n throw error;\n }\n return response;\n };\n const flush = async () => {\n await restored;\n await Promise.all([...writes]);\n if (inFlight) {\n await inFlight;\n return;\n }\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n const work = async () => {\n if (Date.now() < retryAt) return;\n for (const [id, entry] of [...queue]) {\n try {\n await send(\"\", entry.manifest);\n const bytes = Buffer.from(entry.content);\n for (let index = 0; index < entry.manifest.partCount; index++)\n await send(`/${id}/parts`, {\n index,\n data: bytes\n .subarray(\n index * DIAGNOSTIC_LIMITS.partBytes,\n (index + 1) * DIAGNOSTIC_LIMITS.partBytes,\n )\n .toString(\"base64\"),\n });\n const completed = await send(`/${id}/complete`, {});\n const acknowledgement = (await completed.json()) as {\n state?: string;\n };\n if (acknowledgement.state !== \"available\") {\n const error = new Error(\n \"Diagnostic integrity verification failed.\",\n ) as Error & { status: number };\n error.status = 422;\n throw error;\n }\n state(id, \"available\");\n queue.delete(id);\n queuedBytes -= entry.manifest.byteLength;\n if (spool)\n await unlink(join(spool, `${id}.json`)).catch(() => undefined);\n } catch (error) {\n const status = (error as { status?: number }).status;\n if (status && status < 500 && status !== 429) {\n state(id, \"rejected\");\n queue.delete(id);\n queuedBytes -= entry.manifest.byteLength;\n dropped++;\n if (spool)\n await unlink(join(spool, `${id}.json`)).catch(() => undefined);\n }\n // Transient failures retain redacted bytes for a later flush or restart.\n if (status === 429) break;\n }\n }\n };\n inFlight = work();\n try {\n await inFlight;\n } finally {\n inFlight = undefined;\n }\n if (queue.size) {\n timer = setTimeout(\n () => {\n timer = undefined;\n void flush();\n },\n Math.max(5000, retryAt - Date.now()),\n );\n timer.unref?.();\n }\n };\n const capture = (error: unknown, context: DiagnosticCaptureContext) => {\n if (!enabled || isControlFlowError(error)) return undefined;\n const scope = JSON.stringify([\n context.correlation?.runId,\n context.correlation?.invocationId,\n context.correlation?.branchId,\n context.correlation?.attemptId,\n ]);\n const object =\n error && typeof error === \"object\" ? (error as object) : undefined;\n const existing = object ? captured.get(object)?.get(scope) : undefined;\n if (existing)\n return {\n ...existing,\n diagnosticDelivery: existing.diagnosticId\n ? (states.get(existing.diagnosticId) ?? \"pending\")\n : undefined,\n };\n const content = captureDiagnosticContent(\n error,\n context.project ?? options.error,\n );\n if (!content) return { diagnosticCapture: \"suppressed\", details: null };\n const serialized = JSON.stringify(content);\n const diagnosticId = randomUUID();\n const manifest = DiagnosticManifestSchema.parse({\n schemaVersion: 1,\n diagnosticId,\n occurrenceId: randomUUID(),\n occurredAt: new Date().toISOString(),\n environment: options.environment,\n service: options.service,\n correlation: DiagnosticCorrelationSchema.parse(\n Object.fromEntries(\n Object.entries(context.correlation ?? {}).filter(\n ([key]) => key !== \"topologyHash\",\n ),\n ),\n ),\n handled: context.handled,\n severity: context.severity,\n mechanism: context.mechanism,\n summary: {\n type: String(content.data.type ?? \"Error\").slice(0, 256),\n message: summarizeDiagnostic(content.data).message,\n },\n captureStatus: content.capture.status,\n byteLength: Buffer.byteLength(serialized),\n checksum: createHash(\"sha256\").update(serialized).digest(\"hex\"),\n partCount: Math.ceil(\n Buffer.byteLength(serialized) / DIAGNOSTIC_LIMITS.partBytes,\n ),\n });\n if (queuedBytes + manifest.byteLength > maxBytes) {\n state(diagnosticId, \"dropped\");\n dropped++;\n } else {\n const entry = { manifest, content: serialized };\n queue.set(diagnosticId, entry);\n queuedBytes += manifest.byteLength;\n state(diagnosticId, \"pending\");\n const writing = persist(entry)\n .catch(() => {\n state(diagnosticId, \"spool_failed\");\n })\n .finally(() => {\n writes.delete(writing);\n });\n writes.add(writing);\n schedule();\n }\n const result = {\n diagnosticId,\n diagnosticCapture: content.capture.status,\n diagnosticDelivery: states.get(diagnosticId),\n details: summarizeDiagnostic(content.data),\n };\n if (object) {\n const byScope = captured.get(object) ?? new Map<string, CaptureResult>();\n byScope.set(scope, result);\n captured.set(object, byScope);\n }\n return result;\n };\n const flushWithDeadline = async (timeoutMs = 5000) => {\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let timedOut = false;\n await Promise.race([\n flush(),\n new Promise<void>((resolve) => {\n deadline = setTimeout(\n () => {\n timedOut = true;\n resolve();\n },\n Math.max(0, timeoutMs),\n );\n }),\n ]);\n if (deadline) clearTimeout(deadline);\n return {\n timedOut,\n pending: queue.size,\n pendingBytes: queuedBytes,\n dropped,\n states: Object.fromEntries(states),\n };\n };\n return {\n capture,\n flush,\n flushWithDeadline,\n getState: (id: string) => states.get(id),\n getDroppedCount: () => dropped,\n };\n}\n","import {\n errorProperty,\n isControlFlowError,\n serializeFailure,\n} from \"@kortyx/core/errors\";\nimport type {\n KortyxTelemetryConfig,\n KortyxTelemetryEvent,\n KortyxTelemetryEventType,\n ReasonTraceAttributes,\n ReasonTraceSpanStartArgs,\n} from \"@kortyx/hooks\";\nimport {\n exceptionDiagnostics,\n safeTelemetryMetadata,\n} from \"@kortyx/hooks/internal\";\nimport { summarizeDiagnostic } from \"@kortyx/telemetry-contracts\";\nimport type {\n createDiagnosticDelivery,\n DiagnosticCaptureContext,\n} from \"./diagnostics\";\nimport type { ActiveSpan, SpanContext } from \"./types\";\n\nconst stringValue = (value: unknown): string | undefined =>\n typeof value === \"string\" && value.length > 0 ? value : undefined;\n\nconst shouldCapture = (\n value: KortyxTelemetryConfig[\"captureContent\"] | undefined,\n side: \"input\" | \"output\",\n): boolean => {\n if (value === true) return true;\n return Boolean(value && typeof value === \"object\" && value[side]);\n};\n\nconst asErrorPayload = (\n error: unknown,\n project?: import(\"@kortyx/hooks\").KortyxTraceErrorProjection,\n captured?: ReturnType<ReturnType<typeof createDiagnosticDelivery>[\"capture\"]>,\n): Record<string, unknown> => {\n if (isControlFlowError(error))\n return {\n name: errorProperty(error, \"name\"),\n code: errorProperty(error, \"code\"),\n message: \"Execution paused or cancelled.\",\n controlFlow: true,\n };\n const failure = serializeFailure(error);\n const diagnostic = captured\n ? captured.details\n : exceptionDiagnostics(error, project);\n const summary = diagnostic ? summarizeDiagnostic(diagnostic) : null;\n const reference = captured\n ? Object.fromEntries(\n Object.entries(captured).filter(([key]) => key !== \"details\"),\n )\n : {};\n return {\n ...failure,\n name: summary?.type ?? \"Error\",\n message: summary?.message ?? failure.message,\n ...(summary?.stack ? { stack: summary.stack } : {}),\n ...(summary?.cause ? { cause: summary.cause } : {}),\n ...reference,\n };\n};\n\nconst correlationFrom = (\n attributes: ReasonTraceAttributes | undefined,\n active: ActiveSpan | undefined,\n): KortyxTelemetryEvent[\"correlation\"] | undefined => {\n const source = attributes ?? {};\n const runId = stringValue(source.runId) ?? active?.correlation.runId;\n const workflowId =\n stringValue(source.workflowId) ?? active?.correlation.workflowId;\n if (!runId || !workflowId) return undefined;\n\n const sameWorkflow = workflowId === active?.correlation.workflowId;\n const sessionId =\n stringValue(source.sessionId) ?? active?.correlation.sessionId;\n const workflowRevisionId =\n stringValue(source.workflowRevisionId) ??\n (sameWorkflow ? active?.correlation.workflowRevisionId : undefined);\n const topologyHash =\n stringValue(source.topologyHash) ??\n (sameWorkflow ? active?.correlation.topologyHash : undefined);\n const nodeId =\n stringValue(source.nodeId) ??\n (sameWorkflow ? active?.correlation.nodeId : undefined);\n return {\n runId,\n workflowId,\n ...Object.fromEntries(\n [\"invocationId\", \"parentInvocationId\", \"branchId\"].flatMap((key) => {\n const value =\n stringValue(source[key]) ??\n active?.correlation[key as \"invocationId\"];\n return value ? [[key, value]] : [];\n }),\n ),\n ...(sessionId ? { sessionId } : {}),\n ...(workflowRevisionId ? { workflowRevisionId } : {}),\n ...(topologyHash ? { topologyHash } : {}),\n ...(nodeId ? { nodeId } : {}),\n };\n};\n\nexport const createEventMapper = (args: {\n environment: string;\n service: KortyxTelemetryEvent[\"service\"];\n metadata?: Record<string, unknown> | undefined;\n tags?: string[] | undefined;\n createId: () => string;\n error?: import(\"@kortyx/hooks\").KortyxTraceErrorProjection;\n captureDiagnostic?: ReturnType<typeof createDiagnosticDelivery>[\"capture\"];\n}) => {\n const createEvent = (input: {\n type: KortyxTelemetryEventType;\n correlation: KortyxTelemetryEvent[\"correlation\"];\n span?: SpanContext | undefined;\n parentSpanId?: string | undefined;\n payload: Record<string, unknown>;\n context?: KortyxTelemetryEvent[\"context\"] | undefined;\n }): KortyxTelemetryEvent => ({\n schemaVersion: 1,\n eventId: args.createId(),\n occurredAt: new Date().toISOString(),\n environment: args.environment,\n service: args.service,\n correlation: {\n ...input.correlation,\n ...(input.span\n ? { traceId: input.span.traceId, spanId: input.span.spanId }\n : {}),\n ...(input.parentSpanId ? { parentSpanId: input.parentSpanId } : {}),\n },\n ...(input.context || args.metadata || args.tags\n ? {\n context: {\n ...(args.tags ? { tags: args.tags } : {}),\n ...(args.metadata\n ? { metadata: safeTelemetryMetadata(args.metadata) }\n : {}),\n ...(input.context ?? {}),\n },\n }\n : {}),\n type: input.type,\n payload: {\n ...input.payload,\n ...(input.correlation.invocationId\n ? { invocationId: input.correlation.invocationId }\n : {}),\n ...(input.correlation.parentInvocationId\n ? { parentInvocationId: input.correlation.parentInvocationId }\n : {}),\n ...(input.correlation.branchId\n ? { branchId: input.correlation.branchId }\n : {}),\n },\n });\n\n const spanContext = (\n telemetry: ReasonTraceSpanStartArgs[\"telemetry\"] | undefined,\n attributes: ReasonTraceAttributes,\n ): KortyxTelemetryEvent[\"context\"] | undefined => {\n const tags = [...(args.tags ?? []), ...(telemetry?.tags ?? [])];\n const metadata = safeTelemetryMetadata({\n ...(args.metadata ?? {}),\n ...(telemetry?.metadata ?? {}),\n });\n const userId = stringValue(attributes.userId);\n const tenantId = stringValue(attributes.tenantId);\n return userId || tenantId || tags.length || Object.keys(metadata).length\n ? {\n ...(userId ? { userId } : {}),\n ...(tenantId ? { tenantId } : {}),\n ...(tags.length ? { tags } : {}),\n ...(Object.keys(metadata).length ? { metadata } : {}),\n }\n : undefined;\n };\n\n const telemetryPayload = (\n telemetry: ReasonTraceSpanStartArgs[\"telemetry\"] | undefined,\n ): Record<string, unknown> => ({\n ...(telemetry?.operation ? { operation: telemetry.operation } : {}),\n ...(telemetry?.tags?.length ? { tags: telemetry.tags } : {}),\n ...(telemetry?.metadata\n ? { metadata: safeTelemetryMetadata(telemetry.metadata) }\n : {}),\n ...(telemetry?.prompt\n ? {\n prompt: {\n ...(telemetry.prompt.name ? { name: telemetry.prompt.name } : {}),\n ...(telemetry.prompt.version !== undefined\n ? { version: telemetry.prompt.version }\n : {}),\n ...(telemetry.prompt.type ? { type: telemetry.prompt.type } : {}),\n ...(telemetry.prompt.source\n ? { source: telemetry.prompt.source }\n : {}),\n },\n }\n : {}),\n });\n\n return {\n asErrorPayload: (error: unknown, context?: DiagnosticCaptureContext) =>\n asErrorPayload(\n error,\n context?.project ?? args.error,\n context ? args.captureDiagnostic?.(error, context) : undefined,\n ),\n correlationFrom,\n createEvent,\n shouldCapture,\n spanContext,\n stringValue,\n telemetryPayload,\n };\n};\n","import type {\n EnsureWorkflowTopologyRequest,\n EnsureWorkflowTopologyResponse,\n} from \"@kortyx/hooks\";\n\ntype TopologyKey = {\n environment: string;\n workflowId: string;\n topologyHash: string;\n};\n\nconst keyFor = ({ environment, workflowId, topologyHash }: TopologyKey) =>\n `${environment}:${workflowId}:${topologyHash}`;\n\n/** Caches successful topology ensures and coalesces concurrent requests. */\nexport const createTopologyResolver = (args: {\n ensure: (\n snapshot: EnsureWorkflowTopologyRequest,\n ) => Promise<EnsureWorkflowTopologyResponse>;\n}) => {\n const revisions = new Map<string, string>();\n const pending = new Map<string, Promise<EnsureWorkflowTopologyResponse>>();\n\n const ensureWorkflowTopology = (\n snapshot: EnsureWorkflowTopologyRequest,\n ): Promise<EnsureWorkflowTopologyResponse> => {\n const key = keyFor({\n environment: snapshot.environment,\n workflowId: snapshot.workflow.id,\n topologyHash: snapshot.workflow.topologyHash,\n });\n const revision = revisions.get(key);\n if (revision) {\n return Promise.resolve({ workflowRevisionId: revision, created: false });\n }\n\n const existing = pending.get(key);\n if (existing) return existing;\n\n const request = args\n .ensure(snapshot)\n .then((result) => {\n if (!result.workflowRevisionId) {\n throw new Error(\n \"Telemetry API returned an invalid workflow revision.\",\n );\n }\n revisions.set(key, result.workflowRevisionId);\n return result;\n })\n .finally(() => {\n pending.delete(key);\n });\n pending.set(key, request);\n return request;\n };\n\n return {\n ensureWorkflowTopology,\n getWorkflowRevisionId: (args: TopologyKey) => revisions.get(keyFor(args)),\n };\n};\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { isSuspensionControlFlowError } from \"@kortyx/core/errors\";\nimport type {\n KortyxTelemetryConfig,\n KortyxTelemetryEvent,\n ReasonTraceAdapter,\n ReasonTraceSpan,\n ReasonTraceSpanEndArgs,\n ReasonTraceSpanStartArgs,\n} from \"@kortyx/hooks\";\nimport { ToolObservationSchema } from \"@kortyx/telemetry-contracts\";\nimport type { createEventMapper } from \"./event-mapper\";\nimport type { ActiveSpan, SpanContext } from \"./types\";\n\nconst providerPricing = (\n metadata: ReasonTraceSpanEndArgs[\"providerMetadata\"],\n): Record<string, unknown> | undefined => {\n if (metadata?.providerId !== \"openrouter\") return undefined;\n const details = metadata.costDetails;\n const upstreamCost =\n details && typeof details === \"object\" && !Array.isArray(details)\n ? (details as Record<string, unknown>).upstreamInferenceCost\n : undefined;\n const cost = metadata.isByok === true ? upstreamCost : metadata.cost;\n if (typeof cost !== \"number\" || !Number.isFinite(cost) || cost < 0)\n return undefined;\n return {\n source: \"provider\",\n currency: \"USD\",\n actualCostMicros: Math.round(cost * 1_000_000),\n };\n};\n\n/** Maps generic SDK trace calls to Kortyx Studio's span and generation facts. */\nexport const createTraceAdapter = (args: {\n captureContent?: KortyxTelemetryConfig[\"captureContent\"] | undefined;\n createId: () => string;\n enqueue: (event: KortyxTelemetryEvent) => void;\n eventMapper: ReturnType<typeof createEventMapper>;\n}): ReasonTraceAdapter => {\n const activeSpans = new AsyncLocalStorage<ActiveSpan>();\n\n const createSpan = (\n startArgs: ReasonTraceSpanStartArgs,\n ): { span: ReasonTraceSpan; active?: ActiveSpan | undefined } => {\n const parent = activeSpans.getStore();\n const span: SpanContext = {\n traceId: parent?.traceId ?? args.createId(),\n spanId: args.createId(),\n };\n const attributes = { ...(startArgs.attributes ?? {}) };\n const currentAttributes = { ...attributes };\n const correlation = args.eventMapper.correlationFrom(attributes, parent);\n const startedAt = Date.now();\n\n const isTool = startArgs.name === \"kortyx.tool\";\n if (correlation && (!isTool || attributes.executed === true)) {\n args.enqueue(\n args.eventMapper.createEvent({\n type: isTool ? \"tool.started\" : \"span.started\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: isTool\n ? ToolObservationSchema.parse(attributes)\n : {\n name: startArgs.name,\n attributes: currentAttributes,\n telemetry: args.eventMapper.telemetryPayload(\n startArgs.telemetry,\n ),\n ...(args.eventMapper.shouldCapture(\n startArgs.telemetry?.captureContent ?? args.captureContent,\n \"input\",\n )\n ? { input: startArgs.telemetry?.input }\n : {}),\n },\n context: args.eventMapper.spanContext(\n startArgs.telemetry,\n currentAttributes,\n ),\n }),\n );\n }\n\n let ended = false;\n let failed = false;\n let suspended = false;\n const end = (endArgs?: ReasonTraceSpanEndArgs): void => {\n if (ended) return;\n ended = true;\n if (!correlation) return;\n\n const endAttributes = {\n ...currentAttributes,\n ...(endArgs?.attributes ?? {}),\n };\n const telemetry = endArgs?.telemetry ?? startArgs.telemetry;\n const durationMs = Date.now() - startedAt;\n if (isTool) {\n const payload = ToolObservationSchema.parse(endAttributes);\n const type =\n payload.observationKind === \"reused\"\n ? \"tool.reused\"\n : payload.observationKind === \"waiting\"\n ? \"tool.waiting\"\n : payload.suspended\n ? \"tool.suspended\"\n : payload.outcome === \"denied\"\n ? \"tool.denied\"\n : payload.outcome === \"fault\"\n ? \"tool.failed\"\n : payload.outcome === \"cancelled\"\n ? \"tool.cancelled\"\n : \"tool.completed\";\n args.enqueue(\n args.eventMapper.createEvent({\n type,\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload,\n }),\n );\n return;\n }\n\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"span.ended\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: {\n name: startArgs.name,\n attributes: endAttributes,\n durationMs,\n telemetry: args.eventMapper.telemetryPayload(telemetry),\n ...(args.eventMapper.shouldCapture(\n endArgs?.telemetry?.captureContent ??\n startArgs.telemetry?.captureContent ??\n args.captureContent,\n \"output\",\n )\n ? { output: endArgs?.telemetry?.output }\n : {}),\n },\n context: args.eventMapper.spanContext(telemetry, endAttributes),\n }),\n );\n\n if (startArgs.name !== \"runReasonEngine\" || suspended) return;\n const ttftMs = nonnegativeNumber(endAttributes.ttftMs);\n const streamDurationMs = nonnegativeNumber(\n endAttributes.streamDurationMs,\n );\n const timeToLastTokenMs = nonnegativeNumber(\n endAttributes.timeToLastTokenMs,\n );\n const pricing = providerPricing(endArgs?.providerMetadata);\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"generation.completed\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: {\n outcome: failed ? \"failed\" : \"completed\",\n provider:\n args.eventMapper.stringValue(attributes.providerId) ?? \"unknown\",\n model:\n args.eventMapper.stringValue(attributes.modelId) ?? \"unknown\",\n durationMs,\n ...(ttftMs !== undefined ? { ttftMs } : {}),\n ...(streamDurationMs !== undefined ? { streamDurationMs } : {}),\n ...(timeToLastTokenMs !== undefined\n ? {\n postStreamDurationMs: Math.max(\n 0,\n durationMs - timeToLastTokenMs,\n ),\n }\n : {}),\n ...(endArgs?.usage\n ? {\n usage: failed\n ? Object.fromEntries(\n Object.entries(endArgs.usage).filter(\n ([key, value]) =>\n ([\n \"input\",\n \"output\",\n \"total\",\n \"reasoning\",\n \"cacheRead\",\n \"cacheWrite\",\n \"cacheWrite1h\",\n ].includes(key) &&\n typeof value === \"number\" &&\n Number.isFinite(value)) ||\n ([\n \"outputIncludesReasoning\",\n \"inputIncludesCacheRead\",\n \"inputIncludesCacheWrite\",\n ].includes(key) &&\n typeof value === \"boolean\"),\n ),\n )\n : endArgs.usage,\n }\n : {}),\n ...(endArgs?.finishReason\n ? { finishReason: endArgs.finishReason }\n : {}),\n ...(endArgs?.warnings ? { warnings: endArgs.warnings } : {}),\n ...(pricing ? { pricing } : {}),\n ...(endArgs?.providerMetadata && !failed\n ? { providerMetadata: endArgs.providerMetadata }\n : {}),\n },\n context: args.eventMapper.spanContext(telemetry, currentAttributes),\n }),\n );\n };\n\n const traceSpan: ReasonTraceSpan = {\n setAttributes: (nextAttributes) => {\n Object.assign(currentAttributes, nextAttributes);\n },\n addEvent: (name, eventAttributes = {}) => {\n if (\n !correlation ||\n activeSpans.getStore()?.name === \"kortyx.tool\" ||\n startArgs.name === \"kortyx.tool\"\n )\n return;\n const type =\n name === \"useReason.tool-call.start\"\n ? \"tool.started\"\n : name === \"useReason.tool-call.complete\"\n ? \"tool.completed\"\n : name === \"useReason.tool-call.error\"\n ? \"tool.failed\"\n : name === \"useReason.output.emitted\"\n ? \"output.emitted\"\n : name === \"useReason.output.invalidated\"\n ? \"output.invalidated\"\n : undefined;\n if (!type) return;\n const payload =\n type === \"output.emitted\"\n ? {\n ...Object.fromEntries(\n Object.entries(eventAttributes).filter(\n ([key]) => key !== \"data\",\n ),\n ),\n ...(args.eventMapper.shouldCapture(\n startArgs.telemetry?.captureContent ?? args.captureContent,\n \"output\",\n ) && \"data\" in eventAttributes\n ? { data: eventAttributes.data }\n : {}),\n }\n : eventAttributes;\n args.enqueue(\n args.eventMapper.createEvent({\n type,\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload,\n }),\n );\n },\n end,\n fail: (error, endArgs) => {\n if (ended) return;\n if (isSuspensionControlFlowError(error)) {\n suspended = true;\n Object.assign(currentAttributes, {\n \"kortyx.control_flow\": true,\n \"kortyx.suspended\": true,\n });\n end(endArgs);\n return;\n }\n failed = true;\n const errorPayload = args.eventMapper.asErrorPayload(error, {\n correlation: { ...correlation, ...span },\n handled: false,\n severity: \"error\",\n mechanism: \"span\",\n });\n if (correlation) {\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"span.failed\",\n correlation,\n span,\n ...(parent ? { parentSpanId: parent.spanId } : {}),\n payload: {\n name: startArgs.name,\n error: errorPayload,\n handled: false,\n severity: \"error\",\n durationMs: Date.now() - startedAt,\n },\n }),\n );\n }\n end(endArgs);\n },\n };\n\n return {\n span: traceSpan,\n ...(correlation\n ? { active: { ...span, name: startArgs.name, correlation } }\n : {}),\n };\n };\n\n return {\n startSpan: (startArgs) => createSpan(startArgs).span,\n withSpan: async (startArgs, fn) => {\n const created = createSpan(startArgs);\n const run = async (): Promise<Awaited<ReturnType<typeof fn>>> => {\n try {\n const result = await fn(created.span);\n created.span.end?.();\n return result;\n } catch (error) {\n try {\n created.span.fail?.(error);\n } catch {\n /* Preserve the callback failure. */\n }\n throw error;\n }\n };\n return created.active ? activeSpans.run(created.active, run) : run();\n },\n getActiveContext: () => {\n const active = activeSpans.getStore();\n return active\n ? { traceId: active.traceId, spanId: active.spanId }\n : undefined;\n },\n reportError: (error, options = {}) => {\n try {\n const active = activeSpans.getStore();\n const payload = args.eventMapper.asErrorPayload(error, {\n correlation: {\n ...active?.correlation,\n ...(active\n ? { traceId: active.traceId, spanId: active.spanId }\n : {}),\n ...options.correlation,\n },\n handled: true,\n severity: options.severity === \"warning\" ? \"warning\" : \"error\",\n mechanism: options.mechanism ?? \"report\",\n project: options.error,\n });\n if (!active)\n return typeof payload.diagnosticId === \"string\"\n ? payload.diagnosticId\n : undefined;\n args.enqueue(\n args.eventMapper.createEvent({\n type: \"error.reported\",\n correlation: active.correlation,\n span: active,\n payload: {\n handled: true,\n severity: options.severity === \"warning\" ? \"warning\" : \"error\",\n error: payload,\n },\n context: args.eventMapper.spanContext(\n {\n ...(options.metadata ? { metadata: options.metadata } : {}),\n ...(options.tags ? { tags: options.tags } : {}),\n },\n {},\n ),\n }),\n );\n return typeof payload.diagnosticId === \"string\"\n ? payload.diagnosticId\n : undefined;\n } catch {\n // Error reporting is an observer and cannot change execution.\n return undefined;\n }\n },\n };\n};\n\nconst nonnegativeNumber = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? value\n : undefined;\n"],"mappings":"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","names":["import_node_crypto","result","import_errors","import_internal","import_telemetry_contracts","args","import_errors","import_telemetry_contracts"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kortyx/telemetry",
3
- "version": "0.11.2",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "description": "Kortyx Studio telemetry HTTP adapter.",
6
6
  "license": "Apache-2.0",
@@ -18,9 +18,9 @@
18
18
  "CHANGELOG.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@kortyx/hooks": "0.30.2",
22
- "@kortyx/telemetry-contracts": "0.14.0",
23
- "@kortyx/core": "0.11.0"
21
+ "@kortyx/hooks": "0.31.0",
22
+ "@kortyx/telemetry-contracts": "0.15.0",
23
+ "@kortyx/core": "0.12.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "tsup": "^8.5.1",