@warlock.js/ai-panoptic 5.31.0 → 5.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/cjs/index.cjs +72 -67
  3. package/cjs/index.cjs.map +1 -1
  4. package/esm/collector/collector.d.mts +3 -5
  5. package/esm/collector/collector.d.mts.map +1 -1
  6. package/esm/collector/collector.mjs +2 -0
  7. package/esm/collector/collector.mjs.map +1 -1
  8. package/esm/collector/content-capture.type.d.mts +4 -5
  9. package/esm/collector/content-capture.type.d.mts.map +1 -1
  10. package/esm/collector/extract-span-attributes.d.mts +1 -3
  11. package/esm/collector/extract-span-attributes.d.mts.map +1 -1
  12. package/esm/collector/extract-span-attributes.mjs +30 -6
  13. package/esm/collector/extract-span-attributes.mjs.map +1 -1
  14. package/esm/collector/index.d.mts +3 -1
  15. package/esm/collector/index.mjs +2 -1
  16. package/esm/collector/normalize-error.d.mts +1 -3
  17. package/esm/collector/normalize-error.d.mts.map +1 -1
  18. package/esm/collector/report-to-span.d.mts +1 -3
  19. package/esm/collector/report-to-span.d.mts.map +1 -1
  20. package/esm/collector/report-to-trace.d.mts +1 -3
  21. package/esm/collector/report-to-trace.d.mts.map +1 -1
  22. package/esm/collector/trace-subscriptions.d.mts +14 -0
  23. package/esm/collector/trace-subscriptions.d.mts.map +1 -0
  24. package/esm/collector/trace-subscriptions.mjs +26 -0
  25. package/esm/collector/trace-subscriptions.mjs.map +1 -0
  26. package/esm/config/apply-panoptic-config.d.mts +2 -3
  27. package/esm/config/apply-panoptic-config.d.mts.map +1 -1
  28. package/esm/config/index.d.mts +2 -1
  29. package/esm/config/index.mjs +1 -1
  30. package/esm/config/panoptic-config.type.d.mts +2 -4
  31. package/esm/config/panoptic-config.type.d.mts.map +1 -1
  32. package/esm/contracts/collector.contract.d.mts +1 -3
  33. package/esm/contracts/collector.contract.d.mts.map +1 -1
  34. package/esm/contracts/exporter.contract.d.mts +1 -3
  35. package/esm/contracts/exporter.contract.d.mts.map +1 -1
  36. package/esm/contracts/index.d.mts +2 -1
  37. package/esm/contracts/trace.type.d.mts +37 -20
  38. package/esm/contracts/trace.type.d.mts.map +1 -1
  39. package/esm/dashboard/dashboard.d.mts +1 -3
  40. package/esm/dashboard/dashboard.d.mts.map +1 -1
  41. package/esm/dashboard/dashboard.mjs +3 -2
  42. package/esm/dashboard/dashboard.mjs.map +1 -1
  43. package/esm/dashboard/dashboard.type.d.mts +9 -7
  44. package/esm/dashboard/dashboard.type.d.mts.map +1 -1
  45. package/esm/dashboard/index.d.mts +4 -1
  46. package/esm/dashboard/index.mjs +1 -1
  47. package/esm/dashboard/parse-query.d.mts +1 -1
  48. package/esm/dashboard/serve.d.mts +2 -1
  49. package/esm/dashboard/serve.mjs +1 -1
  50. package/esm/dashboard/serve.mjs.map +1 -1
  51. package/esm/dashboard/trace-filter.d.mts +44 -32
  52. package/esm/dashboard/trace-filter.d.mts.map +1 -1
  53. package/esm/evaluate/evaluate-system-prompt.d.mts +1 -3
  54. package/esm/evaluate/evaluate-system-prompt.d.mts.map +1 -1
  55. package/esm/evaluate/evaluate-system-prompt.mjs +3 -1
  56. package/esm/evaluate/evaluate-system-prompt.mjs.map +1 -1
  57. package/esm/evaluate/evaluate.type.d.mts +2 -4
  58. package/esm/evaluate/evaluate.type.d.mts.map +1 -1
  59. package/esm/evaluate/extract-last-system-prompt.d.mts +1 -3
  60. package/esm/evaluate/extract-last-system-prompt.d.mts.map +1 -1
  61. package/esm/evaluate/find-span-by-id.d.mts +1 -3
  62. package/esm/evaluate/find-span-by-id.d.mts.map +1 -1
  63. package/esm/evaluate/index.d.mts +2 -1
  64. package/esm/evaluate/index.mjs +1 -1
  65. package/esm/exporters/console/console-exporter.d.mts +2 -3
  66. package/esm/exporters/console/console-exporter.d.mts.map +1 -1
  67. package/esm/exporters/console/console-exporter.type.d.mts +2 -3
  68. package/esm/exporters/console/console-exporter.type.d.mts.map +1 -1
  69. package/esm/exporters/console/format-span-io.d.mts +2 -2
  70. package/esm/exporters/console/format-span-io.d.mts.map +1 -1
  71. package/esm/exporters/console/format-span-line.d.mts +2 -2
  72. package/esm/exporters/console/format-span-line.d.mts.map +1 -1
  73. package/esm/exporters/console/index.d.mts +2 -1
  74. package/esm/exporters/console/index.mjs +1 -1
  75. package/esm/exporters/file/file-exporter.d.mts +2 -3
  76. package/esm/exporters/file/file-exporter.d.mts.map +1 -1
  77. package/esm/exporters/file/file-exporter.type.d.mts +8 -5
  78. package/esm/exporters/file/file-exporter.type.d.mts.map +1 -1
  79. package/esm/exporters/file/index.d.mts +2 -1
  80. package/esm/exporters/index.d.mts +7 -1
  81. package/esm/exporters/index.mjs +1 -1
  82. package/esm/exporters/langfuse/index.d.mts +2 -1
  83. package/esm/exporters/langfuse/index.mjs +1 -1
  84. package/esm/exporters/langfuse/langfuse-exporter.d.mts +2 -3
  85. package/esm/exporters/langfuse/langfuse-exporter.d.mts.map +1 -1
  86. package/esm/exporters/langfuse/langfuse-exporter.mjs +1 -1
  87. package/esm/exporters/langfuse/langfuse-exporter.mjs.map +1 -1
  88. package/esm/exporters/langfuse/langfuse-exporter.type.d.mts +23 -17
  89. package/esm/exporters/langfuse/langfuse-exporter.type.d.mts.map +1 -1
  90. package/esm/exporters/otel/index.d.mts +2 -1
  91. package/esm/exporters/otel/index.mjs +1 -1
  92. package/esm/exporters/otel/otel-api.shim.type.d.mts +6 -7
  93. package/esm/exporters/otel/otel-api.shim.type.d.mts.map +1 -1
  94. package/esm/exporters/otel/otel-exporter.d.mts +2 -3
  95. package/esm/exporters/otel/otel-exporter.d.mts.map +1 -1
  96. package/esm/exporters/otel/otel-exporter.type.d.mts +1 -3
  97. package/esm/exporters/otel/otel-exporter.type.d.mts.map +1 -1
  98. package/esm/exporters/utils/gen-ai-attributes.d.mts +9 -7
  99. package/esm/exporters/utils/gen-ai-attributes.d.mts.map +1 -1
  100. package/esm/exporters/utils/index.d.mts +2 -1
  101. package/esm/exporters/utils/index.mjs +1 -1
  102. package/esm/exporters/utils/total-cost.d.mts +1 -3
  103. package/esm/exporters/utils/total-cost.d.mts.map +1 -1
  104. package/esm/exporters/utils/walk-spans.d.mts +2 -2
  105. package/esm/exporters/utils/walk-spans.d.mts.map +1 -1
  106. package/esm/index.d.mts +10 -1
  107. package/esm/index.mjs +2 -1
  108. package/esm/panoptic/index.d.mts +2 -1
  109. package/esm/panoptic/index.mjs +1 -1
  110. package/esm/panoptic/panoptic-middleware.d.mts +1 -3
  111. package/esm/panoptic/panoptic-middleware.d.mts.map +1 -1
  112. package/esm/panoptic/panoptic-target.type.d.mts +4 -5
  113. package/esm/panoptic/panoptic-target.type.d.mts.map +1 -1
  114. package/esm/panoptic/panoptic.d.mts +1 -3
  115. package/esm/panoptic/panoptic.d.mts.map +1 -1
  116. package/esm/panoptic/panoptic.type.d.mts +8 -7
  117. package/esm/panoptic/panoptic.type.d.mts.map +1 -1
  118. package/esm/store/cache-trace-store.d.mts +4 -6
  119. package/esm/store/cache-trace-store.d.mts.map +1 -1
  120. package/esm/store/cache-trace-store.mjs +1 -4
  121. package/esm/store/cache-trace-store.mjs.map +1 -1
  122. package/esm/store/in-memory-trace-store.d.mts +2 -4
  123. package/esm/store/in-memory-trace-store.d.mts.map +1 -1
  124. package/esm/store/in-memory-trace-store.mjs +1 -4
  125. package/esm/store/in-memory-trace-store.mjs.map +1 -1
  126. package/esm/store/index.d.mts +2 -1
  127. package/esm/store/index.mjs +1 -1
  128. package/esm/store/match-trace.d.mts +1 -3
  129. package/esm/store/match-trace.d.mts.map +1 -1
  130. package/esm/store/match-trace.mjs +1 -0
  131. package/esm/store/match-trace.mjs.map +1 -1
  132. package/esm/store/sum-usage.d.mts +4 -30
  133. package/esm/store/sum-usage.d.mts.map +1 -1
  134. package/esm/store/sum-usage.mjs +6 -49
  135. package/esm/store/sum-usage.mjs.map +1 -1
  136. package/esm/store/trace-aggregate.type.d.mts +12 -9
  137. package/esm/store/trace-aggregate.type.d.mts.map +1 -1
  138. package/esm/store/trace-query.type.d.mts +7 -5
  139. package/esm/store/trace-query.type.d.mts.map +1 -1
  140. package/esm/store/trace-store.contract.d.mts +1 -3
  141. package/esm/store/trace-store.contract.d.mts.map +1 -1
  142. package/llms-full.txt +105 -0
  143. package/package.json +4 -4
  144. package/skills/observe-with-panoptic/SKILL.md +35 -0
  145. package/skills/query-traces/SKILL.md +49 -0
  146. package/skills/use-local-dashboard/SKILL.md +21 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,24 @@ All notable changes to `@warlock.js/ai-panoptic` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.33.0 - 2026-10-19
8
+
9
+ ### Added
10
+
11
+ - `subscribeTraces(listener)` and `TraceListener` for process-local adapters observing finalized traces from every built-in collector before exporter dispatch, with isolated listener failures and independent teardown.
12
+ - Optional `Trace.requestId` and exact `TraceQuery.requestId` filters for both in-memory and cache-backed query/aggregate APIs.
13
+ - Content-free retry-attempt timings, provider cache-hit and truncated-trip counts, agent compaction decisions and provider compaction-block counts on trace attributes, surfaced by the devtools AI panel.
14
+
15
+ ## 5.32.0 - 2026-10-18
16
+
17
+ ### Changed
18
+
19
+ - Pin the package development compiler to TypeScript 7.0.2 and use explicit Node types and source roots with supported module resolution.
20
+
21
+ ### Fixed
22
+
23
+ - Use the canonical usage rollup for trace aggregates, retaining hosted-tool counters and historical request fees alongside cache lifetime and mixed-provider cache semantics.
24
+
7
25
  ## 5.31.0 - 2026-10-18
8
26
 
9
27
  ### Fixed
package/cjs/index.cjs CHANGED
@@ -99,7 +99,16 @@ function pickString(value) {
99
99
  function extractSpanAttributes(report) {
100
100
  const extensions = report;
101
101
  const attributes = {};
102
- if (report.attempts !== void 0 && report.attempts.length > 0) attributes["retries"] = report.attempts.length;
102
+ if (report.attempts !== void 0 && report.attempts.length > 0) {
103
+ attributes["retries"] = report.attempts.length;
104
+ attributes["retry.attempts"] = report.attempts.map((attempt) => ({
105
+ index: attempt.index,
106
+ startedAt: attempt.startedAt,
107
+ endedAt: attempt.endedAt,
108
+ duration: attempt.duration,
109
+ status: attempt.status
110
+ }));
111
+ }
103
112
  switch (report.type) {
104
113
  case "agent":
105
114
  addAgentAttributes(attributes, extensions);
@@ -114,16 +123,31 @@ function extractSpanAttributes(report) {
114
123
  case "orchestrator":
115
124
  addOrchestratorAttributes(attributes, extensions);
116
125
  break;
117
- case "tool":
118
- addToolAttributes(attributes, extensions);
119
- break;
120
- default: break;
126
+ case "tool": addToolAttributes(attributes, extensions);
121
127
  }
122
128
  if (Object.keys(attributes).length === 0) return;
123
129
  return attributes;
124
130
  }
125
131
  function addAgentAttributes(attributes, extensions) {
126
- if (Array.isArray(extensions.trips)) attributes["agent.trips"] = extensions.trips.length;
132
+ if (Array.isArray(extensions.trips)) {
133
+ attributes["agent.trips"] = extensions.trips.length;
134
+ if (extensions.trips.some((trip) => trip.usage?.cachedTokens !== void 0)) attributes["agent.cacheHits"] = extensions.trips.filter((trip) => (trip.usage?.cachedTokens ?? 0) > 0).length;
135
+ const truncatedTrips = extensions.trips.filter((trip) => trip.finishReason === "length" || trip.finishReason === "context_exceeded").length;
136
+ if (truncatedTrips > 0) attributes["agent.truncatedTrips"] = truncatedTrips;
137
+ const providerCompactions = extensions.trips.reduce((count, trip) => count + (trip.blocks?.filter((block) => block.type === "compaction").length ?? 0), 0);
138
+ if (providerCompactions > 0) attributes["agent.providerCompactions"] = providerCompactions;
139
+ }
140
+ if (extensions.compactions?.length) attributes["agent.compactions"] = extensions.compactions.map((record) => ({
141
+ type: record.type,
142
+ tripIndex: record.tripIndex,
143
+ inputTokens: record.inputTokens,
144
+ counting: record.counting,
145
+ reason: record.reason,
146
+ ...record.compaction ? {
147
+ replacesFromIndex: record.compaction.replacesFromIndex,
148
+ replacesToIndex: record.compaction.replacesToIndex
149
+ } : {}
150
+ }));
127
151
  if (extensions.model?.name !== void 0) attributes["agent.model.name"] = extensions.model.name;
128
152
  if (extensions.model?.provider !== void 0) attributes["agent.model.provider"] = extensions.model.provider;
129
153
  if (extensions.promptName !== void 0) attributes["agent.promptName"] = extensions.promptName;
@@ -334,6 +358,30 @@ function reportToTrace(report, rootError, options) {
334
358
  return trace;
335
359
  }
336
360
 
361
+ //#endregion
362
+ //#region ../../packages/ai-panoptic/src/collector/trace-subscriptions.ts
363
+ const listeners = /* @__PURE__ */ new Set();
364
+ /**
365
+ * Subscribe to traces from every built-in collector in this process, including
366
+ * collectors created before subscribing. No replay or retention. Called before
367
+ * exporter dispatch, so adapters can read request-local context synchronously.
368
+ * Listener failures are isolated; async listeners are not awaited. The returned
369
+ * disposer removes only this subscription. Does not enable flow observation.
370
+ */
371
+ function subscribeTraces(listener) {
372
+ const subscription = (trace) => listener(trace);
373
+ listeners.add(subscription);
374
+ return () => {
375
+ listeners.delete(subscription);
376
+ };
377
+ }
378
+ /** Internal collector notification; pure toTrace projections never publish. */
379
+ function publishTrace(trace) {
380
+ for (const listener of listeners) try {
381
+ Promise.resolve(listener(trace)).catch(() => {});
382
+ } catch {}
383
+ }
384
+
337
385
  //#endregion
338
386
  //#region ../../packages/ai-panoptic/src/collector/collector.ts
339
387
  /**
@@ -385,6 +433,7 @@ var Collector = class {
385
433
  }
386
434
  async collect(report, rootError) {
387
435
  const trace = this.toTrace(report, rootError);
436
+ publishTrace(trace);
388
437
  await this.dispatch(trace);
389
438
  }
390
439
  async flush() {
@@ -475,6 +524,7 @@ function createCollector(options = {}) {
475
524
  */
476
525
  function matchTrace(trace, filter) {
477
526
  if (!filter) return true;
527
+ if (filter.requestId !== void 0 && trace.requestId !== filter.requestId) return false;
478
528
  if (filter.traceId !== void 0 && trace.traceId !== filter.traceId) return false;
479
529
  if (filter.sessionId !== void 0 && trace.sessionId !== filter.sessionId) return false;
480
530
  if (filter.status !== void 0 && !statusMatches(trace.root.status, filter.status)) return false;
@@ -502,48 +552,14 @@ function toEpoch(bound) {
502
552
 
503
553
  //#endregion
504
554
  //#region ../../packages/ai-panoptic/src/store/sum-usage.ts
505
- /**
506
- * Fold a child {@link Usage} into a running accumulator. Token channels
507
- * (`input` / `output` / `total`) always sum; the optional cache /
508
- * reasoning channels (`cachedTokens` / `cacheWriteTokens` /
509
- * `reasoningTokens`) sum only when at least one side reported them, so
510
- * a provider that never meters a channel doesn't fabricate a `0` for
511
- * it. The `cost` breakdown is merged with the core framework's
512
- * {@link accumulateCost}, keeping cost-rollup semantics identical to a
513
- * native report tree — an unpriced contributor never erases a priced
514
- * one.
515
- *
516
- * Pure: returns a fresh `Usage`, never mutates either argument. Seed an
517
- * aggregation with {@link emptyUsage}.
518
- *
519
- * @example
520
- * let total = emptyUsage();
521
- * for (const trace of traces) {
522
- * total = sumUsage(total, trace.usage);
523
- * }
524
- */
555
+ /** Return an independent all-channel usage rollup, preserving hosted-tool counters. */
525
556
  function sumUsage(accumulator, next) {
526
- const merged = {
527
- input: accumulator.input + next.input,
528
- output: accumulator.output + next.output,
529
- total: accumulator.total + next.total
530
- };
531
- const cachedTokens = sumOptional(accumulator.cachedTokens, next.cachedTokens);
532
- if (cachedTokens !== void 0) merged.cachedTokens = cachedTokens;
533
- const cacheWriteTokens = sumOptional(accumulator.cacheWriteTokens, next.cacheWriteTokens);
534
- if (cacheWriteTokens !== void 0) merged.cacheWriteTokens = cacheWriteTokens;
535
- const reasoningTokens = sumOptional(accumulator.reasoningTokens, next.reasoningTokens);
536
- if (reasoningTokens !== void 0) merged.reasoningTokens = reasoningTokens;
537
- const cost = (0, _warlock_js_ai.accumulateCost)(accumulator.cost, next.cost);
538
- if (cost !== void 0) merged.cost = cost;
557
+ const merged = emptyUsage();
558
+ (0, _warlock_js_ai.mergeUsage)(merged, accumulator);
559
+ (0, _warlock_js_ai.mergeUsage)(merged, next);
539
560
  return merged;
540
561
  }
541
- /**
542
- * A zero-valued {@link Usage} to seed an aggregation. Only the required
543
- * token channels are set; optional channels stay absent until a
544
- * contributor reports them, preserving the "never reported" vs
545
- * "reported as 0" distinction.
546
- */
562
+ /** Seed an aggregation without claiming any optional counter was reported. */
547
563
  function emptyUsage() {
548
564
  return {
549
565
  input: 0,
@@ -551,15 +567,6 @@ function emptyUsage() {
551
567
  total: 0
552
568
  };
553
569
  }
554
- /**
555
- * Add two optional token counts, treating either side's `undefined` as
556
- * zero — but return `undefined` when both are absent, so an unreported
557
- * channel stays unreported rather than collapsing to `0`.
558
- */
559
- function sumOptional(accumulator, next) {
560
- if (accumulator === void 0 && next === void 0) return;
561
- return (accumulator ?? 0) + (next ?? 0);
562
- }
563
570
 
564
571
  //#endregion
565
572
  //#region ../../packages/ai-panoptic/src/store/cache-trace-store.ts
@@ -785,10 +792,7 @@ var CacheTraceStore = class {
785
792
  case "incomplete":
786
793
  aggregate.failed += 1;
787
794
  break;
788
- case "cancelled":
789
- aggregate.cancelled += 1;
790
- break;
791
- default: break;
795
+ case "cancelled": aggregate.cancelled += 1;
792
796
  }
793
797
  }
794
798
  /**
@@ -941,10 +945,7 @@ var InMemoryTraceStore = class {
941
945
  case "incomplete":
942
946
  aggregate.failed += 1;
943
947
  break;
944
- case "cancelled":
945
- aggregate.cancelled += 1;
946
- break;
947
- default: break;
948
+ case "cancelled": aggregate.cancelled += 1;
948
949
  }
949
950
  }
950
951
  /**
@@ -1535,7 +1536,7 @@ function ownUsage(span) {
1535
1536
  * rolled-up subtree totals next to an own-usage `usage` block. Cost is
1536
1537
  * omitted for the same reason; Langfuse prices the own tokens itself.
1537
1538
  */
1538
- const LANGFUSE_METADATA_OMIT = new Set([
1539
+ const LANGFUSE_METADATA_OMIT = /* @__PURE__ */ new Set([
1539
1540
  GEN_AI_ATTRIBUTES.usageInputTokens,
1540
1541
  GEN_AI_ATTRIBUTES.usageOutputTokens,
1541
1542
  WARLOCK_ATTRIBUTES.totalTokens,
@@ -1935,7 +1936,9 @@ function panoptic(options = {}) {
1935
1936
  * the caller (the dashboard route) is expected to catch.
1936
1937
  */
1937
1938
  async function evaluateSystemPrompt(systemPrompt, config, instructionsOverride) {
1938
- return (0, _warlock_js_ai.judgePromptBody)(systemPrompt, typeof config.model === "function" ? await config.model() : config.model, instructionsOverride?.trim() || config.instructions);
1939
+ const model = typeof config.model === "function" ? await config.model() : config.model;
1940
+ const instructions = instructionsOverride?.trim() || config.instructions;
1941
+ return (0, _warlock_js_ai.judgePromptBody)(systemPrompt, model, instructions);
1939
1942
  }
1940
1943
 
1941
1944
  //#endregion
@@ -3524,7 +3527,7 @@ function encodeForInlineScript(value) {
3524
3527
  //#endregion
3525
3528
  //#region ../../packages/ai-panoptic/src/dashboard/serve.ts
3526
3529
  /** Hard cap on the evaluate route's request body — well beyond a real instructions string. */
3527
- const MAX_EVALUATE_BODY_BYTES = 64 * 1024;
3530
+ const MAX_EVALUATE_BODY_BYTES = 65536;
3528
3531
  /**
3529
3532
  * Security response headers added to every dashboard response (S4):
3530
3533
  * block MIME-sniffing, framing, referrer leakage, and lock the page's
@@ -3806,13 +3809,14 @@ function dashboard(store, options = {}) {
3806
3809
  const basePath = normalizeBasePath(options.basePath);
3807
3810
  if (!isLoopbackHost(host) && !options.authToken) return Promise.reject(/* @__PURE__ */ new Error(`Panoptic dashboard: binding to a non-loopback host ("${host}") requires an \`authToken\` (the dashboard exposes raw prompt content). Pass \`authToken\`, or bind to 127.0.0.1.`));
3808
3811
  const allowedHosts = (options.allowedHosts ?? defaultAllowedHosts(host)).map((h) => h.toLowerCase());
3809
- const server = (0, node_http.createServer)(createRequestHandler(store, {
3812
+ const handler = createRequestHandler(store, {
3810
3813
  basePath,
3811
3814
  title,
3812
3815
  authToken: options.authToken,
3813
3816
  allowedHosts,
3814
3817
  evaluate: options.evaluate
3815
- }));
3818
+ });
3819
+ const server = (0, node_http.createServer)(handler);
3816
3820
  return new Promise((resolve, reject) => {
3817
3821
  const onError = (error) => {
3818
3822
  server.off("error", onError);
@@ -4293,6 +4297,7 @@ exports.percentile = percentile;
4293
4297
  exports.reportToSpan = reportToSpan;
4294
4298
  exports.reportToTrace = reportToTrace;
4295
4299
  exports.rollupCost = rollupCost;
4300
+ exports.subscribeTraces = subscribeTraces;
4296
4301
  exports.sumUsage = sumUsage;
4297
4302
  exports.toGenAiAttributes = toGenAiAttributes;
4298
4303
  exports.totalCostUsd = totalCostUsd;