@warlock.js/ai-panoptic 5.30.0 → 5.32.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 (161) hide show
  1. package/CHANGELOG.md +25 -3
  2. package/README.md +2 -2
  3. package/cjs/index.cjs +38 -84
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/collector/collector.d.mts +3 -5
  6. package/esm/collector/collector.d.mts.map +1 -1
  7. package/esm/collector/content-capture.type.d.mts +4 -5
  8. package/esm/collector/content-capture.type.d.mts.map +1 -1
  9. package/esm/collector/extract-span-attributes.d.mts +1 -3
  10. package/esm/collector/extract-span-attributes.d.mts.map +1 -1
  11. package/esm/collector/extract-span-attributes.mjs +2 -4
  12. package/esm/collector/extract-span-attributes.mjs.map +1 -1
  13. package/esm/collector/index.d.mts +2 -1
  14. package/esm/collector/index.mjs +1 -1
  15. package/esm/collector/normalize-error.d.mts +1 -3
  16. package/esm/collector/normalize-error.d.mts.map +1 -1
  17. package/esm/collector/report-to-span.d.mts +1 -3
  18. package/esm/collector/report-to-span.d.mts.map +1 -1
  19. package/esm/collector/report-to-span.mjs.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/config/apply-panoptic-config.d.mts +2 -3
  23. package/esm/config/apply-panoptic-config.d.mts.map +1 -1
  24. package/esm/config/apply-panoptic-config.mjs.map +1 -1
  25. package/esm/config/index.d.mts +2 -1
  26. package/esm/config/index.mjs +1 -1
  27. package/esm/config/panoptic-config.type.d.mts +2 -4
  28. package/esm/config/panoptic-config.type.d.mts.map +1 -1
  29. package/esm/contracts/collector.contract.d.mts +1 -3
  30. package/esm/contracts/collector.contract.d.mts.map +1 -1
  31. package/esm/contracts/exporter.contract.d.mts +1 -3
  32. package/esm/contracts/exporter.contract.d.mts.map +1 -1
  33. package/esm/contracts/index.d.mts +2 -1
  34. package/esm/contracts/trace.type.d.mts +35 -20
  35. package/esm/contracts/trace.type.d.mts.map +1 -1
  36. package/esm/dashboard/dashboard.d.mts +1 -3
  37. package/esm/dashboard/dashboard.d.mts.map +1 -1
  38. package/esm/dashboard/dashboard.mjs +3 -2
  39. package/esm/dashboard/dashboard.mjs.map +1 -1
  40. package/esm/dashboard/dashboard.type.d.mts +9 -7
  41. package/esm/dashboard/dashboard.type.d.mts.map +1 -1
  42. package/esm/dashboard/index.d.mts +4 -1
  43. package/esm/dashboard/index.mjs +1 -1
  44. package/esm/dashboard/parse-query.d.mts +1 -1
  45. package/esm/dashboard/parse-query.mjs +1 -0
  46. package/esm/dashboard/parse-query.mjs.map +1 -1
  47. package/esm/dashboard/serve.d.mts +2 -1
  48. package/esm/dashboard/serve.mjs +1 -1
  49. package/esm/dashboard/serve.mjs.map +1 -1
  50. package/esm/dashboard/trace-filter.d.mts +44 -32
  51. package/esm/dashboard/trace-filter.d.mts.map +1 -1
  52. package/esm/dashboard/trace-filter.mjs +1 -1
  53. package/esm/dashboard/trace-filter.mjs.map +1 -1
  54. package/esm/dashboard/ui.html.mjs +5 -4
  55. package/esm/dashboard/ui.html.mjs.map +1 -1
  56. package/esm/evaluate/evaluate-system-prompt.d.mts +1 -3
  57. package/esm/evaluate/evaluate-system-prompt.d.mts.map +1 -1
  58. package/esm/evaluate/evaluate-system-prompt.mjs +3 -1
  59. package/esm/evaluate/evaluate-system-prompt.mjs.map +1 -1
  60. package/esm/evaluate/evaluate.type.d.mts +2 -4
  61. package/esm/evaluate/evaluate.type.d.mts.map +1 -1
  62. package/esm/evaluate/extract-last-system-prompt.d.mts +1 -3
  63. package/esm/evaluate/extract-last-system-prompt.d.mts.map +1 -1
  64. package/esm/evaluate/find-span-by-id.d.mts +1 -3
  65. package/esm/evaluate/find-span-by-id.d.mts.map +1 -1
  66. package/esm/evaluate/index.d.mts +2 -1
  67. package/esm/evaluate/index.mjs +1 -1
  68. package/esm/exporters/console/console-exporter.d.mts +2 -3
  69. package/esm/exporters/console/console-exporter.d.mts.map +1 -1
  70. package/esm/exporters/console/console-exporter.mjs +4 -3
  71. package/esm/exporters/console/console-exporter.mjs.map +1 -1
  72. package/esm/exporters/console/console-exporter.type.d.mts +2 -3
  73. package/esm/exporters/console/console-exporter.type.d.mts.map +1 -1
  74. package/esm/exporters/console/format-span-io.d.mts +2 -2
  75. package/esm/exporters/console/format-span-io.d.mts.map +1 -1
  76. package/esm/exporters/console/format-span-io.mjs.map +1 -1
  77. package/esm/exporters/console/format-span-line.d.mts +2 -2
  78. package/esm/exporters/console/format-span-line.d.mts.map +1 -1
  79. package/esm/exporters/console/format-span-line.mjs +2 -0
  80. package/esm/exporters/console/format-span-line.mjs.map +1 -1
  81. package/esm/exporters/console/index.d.mts +2 -1
  82. package/esm/exporters/console/index.mjs +5 -0
  83. package/esm/exporters/file/file-exporter.d.mts +2 -3
  84. package/esm/exporters/file/file-exporter.d.mts.map +1 -1
  85. package/esm/exporters/file/file-exporter.mjs.map +1 -1
  86. package/esm/exporters/file/file-exporter.type.d.mts +8 -5
  87. package/esm/exporters/file/file-exporter.type.d.mts.map +1 -1
  88. package/esm/exporters/file/index.d.mts +2 -1
  89. package/esm/exporters/index.d.mts +7 -1
  90. package/esm/exporters/index.mjs +3 -1
  91. package/esm/exporters/langfuse/index.d.mts +2 -1
  92. package/esm/exporters/langfuse/index.mjs +1 -1
  93. package/esm/exporters/langfuse/langfuse-exporter.d.mts +2 -3
  94. package/esm/exporters/langfuse/langfuse-exporter.d.mts.map +1 -1
  95. package/esm/exporters/langfuse/langfuse-exporter.mjs +4 -3
  96. package/esm/exporters/langfuse/langfuse-exporter.mjs.map +1 -1
  97. package/esm/exporters/langfuse/langfuse-exporter.type.d.mts +23 -17
  98. package/esm/exporters/langfuse/langfuse-exporter.type.d.mts.map +1 -1
  99. package/esm/exporters/otel/index.d.mts +2 -1
  100. package/esm/exporters/otel/index.mjs +1 -1
  101. package/esm/exporters/otel/otel-api.shim.type.d.mts +6 -7
  102. package/esm/exporters/otel/otel-api.shim.type.d.mts.map +1 -1
  103. package/esm/exporters/otel/otel-exporter.d.mts +2 -3
  104. package/esm/exporters/otel/otel-exporter.d.mts.map +1 -1
  105. package/esm/exporters/otel/otel-exporter.mjs +2 -1
  106. package/esm/exporters/otel/otel-exporter.mjs.map +1 -1
  107. package/esm/exporters/otel/otel-exporter.type.d.mts +1 -3
  108. package/esm/exporters/otel/otel-exporter.type.d.mts.map +1 -1
  109. package/esm/exporters/utils/gen-ai-attributes.d.mts +9 -7
  110. package/esm/exporters/utils/gen-ai-attributes.d.mts.map +1 -1
  111. package/esm/exporters/utils/index.d.mts +2 -1
  112. package/esm/exporters/utils/index.mjs +5 -0
  113. package/esm/exporters/utils/total-cost.d.mts +3 -7
  114. package/esm/exporters/utils/total-cost.d.mts.map +1 -1
  115. package/esm/exporters/utils/total-cost.mjs +5 -7
  116. package/esm/exporters/utils/total-cost.mjs.map +1 -1
  117. package/esm/exporters/utils/walk-spans.d.mts +2 -2
  118. package/esm/exporters/utils/walk-spans.d.mts.map +1 -1
  119. package/esm/index.d.mts +8 -0
  120. package/esm/panoptic/index.d.mts +2 -1
  121. package/esm/panoptic/index.mjs +1 -1
  122. package/esm/panoptic/panoptic-middleware.d.mts +1 -3
  123. package/esm/panoptic/panoptic-middleware.d.mts.map +1 -1
  124. package/esm/panoptic/panoptic-middleware.mjs.map +1 -1
  125. package/esm/panoptic/panoptic-target.type.d.mts +4 -5
  126. package/esm/panoptic/panoptic-target.type.d.mts.map +1 -1
  127. package/esm/panoptic/panoptic.d.mts +1 -3
  128. package/esm/panoptic/panoptic.d.mts.map +1 -1
  129. package/esm/panoptic/panoptic.mjs.map +1 -1
  130. package/esm/panoptic/panoptic.type.d.mts +8 -7
  131. package/esm/panoptic/panoptic.type.d.mts.map +1 -1
  132. package/esm/store/cache-trace-store.d.mts +4 -6
  133. package/esm/store/cache-trace-store.d.mts.map +1 -1
  134. package/esm/store/cache-trace-store.mjs +2 -4
  135. package/esm/store/cache-trace-store.mjs.map +1 -1
  136. package/esm/store/in-memory-trace-store.d.mts +2 -4
  137. package/esm/store/in-memory-trace-store.d.mts.map +1 -1
  138. package/esm/store/in-memory-trace-store.mjs +4 -5
  139. package/esm/store/in-memory-trace-store.mjs.map +1 -1
  140. package/esm/store/index.d.mts +2 -1
  141. package/esm/store/index.mjs +1 -1
  142. package/esm/store/match-trace.d.mts +1 -3
  143. package/esm/store/match-trace.d.mts.map +1 -1
  144. package/esm/store/sum-usage.d.mts +4 -30
  145. package/esm/store/sum-usage.d.mts.map +1 -1
  146. package/esm/store/sum-usage.mjs +6 -49
  147. package/esm/store/sum-usage.mjs.map +1 -1
  148. package/esm/store/trace-aggregate.type.d.mts +13 -14
  149. package/esm/store/trace-aggregate.type.d.mts.map +1 -1
  150. package/esm/store/trace-query.type.d.mts +5 -5
  151. package/esm/store/trace-query.type.d.mts.map +1 -1
  152. package/esm/store/trace-store.contract.d.mts +1 -3
  153. package/esm/store/trace-store.contract.d.mts.map +1 -1
  154. package/llms-full.txt +148 -117
  155. package/package.json +4 -4
  156. package/skills/evaluate-system-prompt/SKILL.md +21 -17
  157. package/skills/export-traces/SKILL.md +32 -24
  158. package/skills/index.md +3 -0
  159. package/skills/observe-with-panoptic/SKILL.md +18 -18
  160. package/skills/query-traces/SKILL.md +45 -33
  161. package/skills/use-local-dashboard/SKILL.md +33 -26
@@ -1,6 +1,5 @@
1
1
  import { CollectorContract } from "../contracts/collector.contract.mjs";
2
2
  import { ContentCaptureOptions } from "./content-capture.type.mjs";
3
-
4
3
  //#region ../../packages/ai-panoptic/src/collector/collector.d.ts
5
4
  /**
6
5
  * Notified when a registered exporter throws during `collect` / `flush` /
@@ -8,9 +7,9 @@ import { ContentCaptureOptions } from "./content-capture.type.mjs";
8
7
  * it) — this is purely a chance to surface it (route to your logger,
9
8
  * bump a metric). Receives the exporter's `name` and the thrown error.
10
9
  */
11
- type ExporterErrorHandler = (exporterName: string, error: unknown) => void;
10
+ export type ExporterErrorHandler = (exporterName: string, error: unknown) => void;
12
11
  /** Options for {@link createCollector}. */
13
- type CollectorOptions = ContentCaptureOptions & {
12
+ export type CollectorOptions = ContentCaptureOptions & {
14
13
  /**
15
14
  * Called when an exporter throws (and is isolated). Overrides the default
16
15
  * one-time `console.warn` per exporter — route the failure to your own
@@ -31,7 +30,6 @@ type CollectorOptions = ContentCaptureOptions & {
31
30
  * // on shutdown:
32
31
  * await collector.shutdown();
33
32
  */
34
- declare function createCollector(options?: CollectorOptions): CollectorContract;
33
+ export declare function createCollector(options?: CollectorOptions): CollectorContract;
35
34
  //#endregion
36
- export { CollectorOptions, ExporterErrorHandler, createCollector };
37
35
  //# sourceMappingURL=collector.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/collector.ts"],"mappings":";;;;;;AAcA;;;;KAAY,oBAAA,IAAwB,YAAA,UAAsB,KAAc;AAGxE;AAAA,KAAY,gBAAA,GAAmB,qBAAA;;;;;;;EAO7B,OAAA,GAAU,oBAAoB;AAAA;;;;;;;;AAyJkD;;;;;iBAAlE,eAAA,CAAgB,OAAA,GAAS,gBAAA,GAAwB,iBAAiB"}
1
+ {"version":3,"file":"collector.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/collector.ts"],"mappings":";;;;;;;;;YAcY,wBAAwB,sBAAsB;;YAG9C,mBAAmB;;;;;;;EAO7B,UAAU;;;;;;;;;;;;;;wBAyJI,gBAAgB,UAAS,mBAAwB"}
@@ -1,5 +1,4 @@
1
1
  import { ReportType } from "@warlock.js/ai";
2
-
3
2
  //#region ../../packages/ai-panoptic/src/collector/content-capture.type.d.ts
4
3
  /**
5
4
  * Masker applied to each captured content value before it lands on a
@@ -12,7 +11,7 @@ import { ReportType } from "@warlock.js/ai";
12
11
  * const redactContent: ContentRedactor = (value, { field }) =>
13
12
  * field === "input" ? "[redacted prompt]" : value;
14
13
  */
15
- type ContentRedactor = (value: unknown, meta: {
14
+ export type ContentRedactor = (value: unknown, meta: {
16
15
  name: string;
17
16
  type: ReportType;
18
17
  field: "input" | "output";
@@ -29,12 +28,13 @@ type ContentRedactor = (value: unknown, meta: {
29
28
  * OTel `gen_ai.prompt` / `gen_ai.completion`, and Langfuse
30
29
  * `input` / `output`.
31
30
  */
32
- type ContentCaptureOptions = {
31
+ export type ContentCaptureOptions = {
33
32
  /**
34
33
  * Copy the agent's first-trip prompt + final response, and each tool's
35
34
  * args + result, onto `span.input` / `span.output`. Default `false`.
36
35
  */
37
- captureContent?: boolean; /** Optional masker applied to every captured value before it is stored. */
36
+ captureContent?: boolean;
37
+ /** Optional masker applied to every captured value before it is stored. */
38
38
  redactContent?: ContentRedactor;
39
39
  /**
40
40
  * When `true`, emit the agent's complete `CapturedMessage[]` (every
@@ -48,5 +48,4 @@ type ContentCaptureOptions = {
48
48
  fullHistory?: boolean;
49
49
  };
50
50
  //#endregion
51
- export { ContentCaptureOptions, ContentRedactor };
52
51
  //# sourceMappingURL=content-capture.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-capture.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/content-capture.type.ts"],"mappings":";;;;;AAaA;;;;;;;;;KAAY,eAAA,IACV,KAAA,WACA,IAAA;EAAQ,IAAA;EAAc,IAAA,EAAM,UAAU;EAAE,KAAA;AAAA;;;;;;;;AAgC7B;;;;;KAjBD,qBAAA;;;;;EAKV,cAAA;EAEA,aAAA,GAAgB,eAAe;;;;;;;;;;EAU/B,WAAA;AAAA"}
1
+ {"version":3,"file":"content-capture.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/content-capture.type.ts"],"mappings":";;;;;;;;;;;;;YAaY,mBACV,gBACA;EAAQ;EAAc,MAAM;EAAY;;;;;;;;;;;;;;YAe9B;;;;;EAKV;;EAEA,gBAAgB;;;;;;;;;;EAUhB"}
@@ -1,5 +1,4 @@
1
1
  import { BaseReport } from "@warlock.js/ai";
2
-
3
2
  //#region ../../packages/ai-panoptic/src/collector/extract-span-attributes.d.ts
4
3
  /**
5
4
  * Build the free-form `TraceSpan.attributes` bag for one report node.
@@ -23,7 +22,6 @@ import { BaseReport } from "@warlock.js/ai";
23
22
  * const attributes = extractSpanAttributes(agentReport);
24
23
  * // { "agent.trips": 3, "agent.model.name": "gpt-4o", "agent.model.provider": "openai" }
25
24
  */
26
- declare function extractSpanAttributes(report: BaseReport): Record<string, unknown> | undefined;
25
+ export declare function extractSpanAttributes(report: BaseReport): Record<string, unknown> | undefined;
27
26
  //#endregion
28
- export { extractSpanAttributes };
29
27
  //# sourceMappingURL=extract-span-attributes.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract-span-attributes.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/extract-span-attributes.ts"],"mappings":";;;;;AAuDA;;;;;;;;AAAiE;;;;;;;;;;;;iBAAjD,qBAAA,CAAsB,MAAA,EAAQ,UAAA,GAAa,MAAM"}
1
+ {"version":3,"file":"extract-span-attributes.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/extract-span-attributes.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;wBAwDgB,sBAAsB,QAAQ,aAAa"}
@@ -39,10 +39,7 @@ function extractSpanAttributes(report) {
39
39
  case "orchestrator":
40
40
  addOrchestratorAttributes(attributes, extensions);
41
41
  break;
42
- case "tool":
43
- addToolAttributes(attributes, extensions);
44
- break;
45
- default: break;
42
+ case "tool": addToolAttributes(attributes, extensions);
46
43
  }
47
44
  if (Object.keys(attributes).length === 0) return;
48
45
  return attributes;
@@ -71,6 +68,7 @@ function addOrchestratorAttributes(attributes, extensions) {
71
68
  }
72
69
  function addToolAttributes(attributes, extensions) {
73
70
  if (extensions.tripIndex !== void 0) attributes["tool.tripIndex"] = extensions.tripIndex;
71
+ if (extensions.callId !== void 0) attributes["tool.callId"] = extensions.callId;
74
72
  if (extensions.recoveredFrom !== void 0) attributes["tool.recoveredFrom"] = extensions.recoveredFrom;
75
73
  }
76
74
 
@@ -1 +1 @@
1
- {"version":3,"file":"extract-span-attributes.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/extract-span-attributes.ts"],"sourcesContent":["import type { BaseReport } from \"@warlock.js/ai\";\n\n/**\n * Per-primitive `BaseReport` extension fields the collector surfaces as\n * span attributes. Declared as a structural superset (every field\n * optional) so a single reader can pull whatever the concrete report\n * carried without narrowing on `type` first — a `BaseReport` widened to\n * this shape exposes `undefined` for the fields its primitive doesn't\n * set, and the extractor simply skips those.\n *\n * Mirrors the public per-primitive report types in `@warlock.js/ai`\n * (`AgentReport`, `WorkflowReport`, `SupervisorReport`,\n * `OrchestratorReport`, `ToolCall`) — kept structural rather than a\n * union import so adding a new optional report field upstream is a\n * non-breaking read here.\n */\ntype ReportExtensions = {\n model?: { name?: string; provider?: string };\n trips?: unknown[];\n promptName?: string;\n promptVersion?: string;\n workflowName?: string;\n supervisorName?: string;\n signature?: string;\n terminatedBy?: string;\n iterations?: number;\n steps?: Record<string, unknown>;\n turns?: unknown[];\n turnIndex?: number;\n tripIndex?: number;\n recoveredFrom?: string;\n};\n\n/**\n * Build the free-form `TraceSpan.attributes` bag for one report node.\n *\n * The collector keeps the first-class span fields (identity, timing,\n * status, usage, error) on the span itself and routes everything\n * primitive-specific here — trip/step/iteration counts, the model\n * identity an agent ran against, the tool's originating trip index, a\n * supervisor's termination reason. Exporters forward this verbatim as\n * backend span attributes (OTel attributes, Langfuse metadata).\n *\n * Only populated keys are emitted; the function returns `undefined`\n * when the node carried no extra detail, so the optional\n * `TraceSpan.attributes` field stays absent rather than holding an\n * empty object (matches the contract's \"absent when empty\" note).\n *\n * Retry count is surfaced from the shared `BaseReport.attempts` for\n * every primitive so cost dashboards see the real call count.\n *\n * @example\n * const attributes = extractSpanAttributes(agentReport);\n * // { \"agent.trips\": 3, \"agent.model.name\": \"gpt-4o\", \"agent.model.provider\": \"openai\" }\n */\nexport function extractSpanAttributes(report: BaseReport): Record<string, unknown> | undefined {\n const extensions = report as BaseReport & ReportExtensions;\n const attributes: Record<string, unknown> = {};\n\n if (report.attempts !== undefined && report.attempts.length > 0) {\n attributes[\"retries\"] = report.attempts.length;\n }\n\n switch (report.type) {\n case \"agent\": {\n addAgentAttributes(attributes, extensions);\n break;\n }\n\n case \"workflow\": {\n addWorkflowAttributes(attributes, extensions);\n break;\n }\n\n case \"supervisor\":\n case \"team\": {\n // ai.team reuses the supervisor engine, so a team report carries the\n // same supervisorName / terminatedBy / iterations fields.\n addSupervisorAttributes(attributes, extensions);\n break;\n }\n\n case \"orchestrator\": {\n addOrchestratorAttributes(attributes, extensions);\n break;\n }\n\n case \"tool\": {\n addToolAttributes(attributes, extensions);\n break;\n }\n\n default: {\n break;\n }\n }\n\n if (Object.keys(attributes).length === 0) {\n return undefined;\n }\n\n return attributes;\n}\n\nfunction addAgentAttributes(attributes: Record<string, unknown>, extensions: ReportExtensions): void {\n if (Array.isArray(extensions.trips)) {\n attributes[\"agent.trips\"] = extensions.trips.length;\n }\n\n if (extensions.model?.name !== undefined) {\n attributes[\"agent.model.name\"] = extensions.model.name;\n }\n\n if (extensions.model?.provider !== undefined) {\n attributes[\"agent.model.provider\"] = extensions.model.provider;\n }\n\n // Prompt-version linkage (core `AgentReport.promptName` / `promptVersion`).\n // Present only when the agent ran against a *named* `ai.prompts` builder;\n // surfaced so the dashboard can group / filter runs by `name@version` and\n // attribute behavior shifts to a specific prompt revision.\n if (extensions.promptName !== undefined) {\n attributes[\"agent.promptName\"] = extensions.promptName;\n }\n\n if (extensions.promptVersion !== undefined) {\n attributes[\"agent.promptVersion\"] = extensions.promptVersion;\n }\n}\n\nfunction addWorkflowAttributes(attributes: Record<string, unknown>, extensions: ReportExtensions): void {\n if (extensions.workflowName !== undefined) {\n attributes[\"workflow.name\"] = extensions.workflowName;\n }\n\n if (extensions.signature !== undefined) {\n attributes[\"workflow.signature\"] = extensions.signature;\n }\n\n if (extensions.steps !== undefined) {\n attributes[\"workflow.steps\"] = Object.keys(extensions.steps).length;\n }\n}\n\nfunction addSupervisorAttributes(attributes: Record<string, unknown>, extensions: ReportExtensions): void {\n if (extensions.supervisorName !== undefined) {\n attributes[\"supervisor.name\"] = extensions.supervisorName;\n }\n\n if (extensions.terminatedBy !== undefined) {\n attributes[\"supervisor.terminatedBy\"] = extensions.terminatedBy;\n }\n\n if (extensions.iterations !== undefined) {\n attributes[\"supervisor.iterations\"] = extensions.iterations;\n }\n}\n\nfunction addOrchestratorAttributes(attributes: Record<string, unknown>, extensions: ReportExtensions): void {\n if (extensions.turnIndex !== undefined) {\n attributes[\"orchestrator.turnIndex\"] = extensions.turnIndex;\n }\n\n if (extensions.signature !== undefined) {\n attributes[\"orchestrator.signature\"] = extensions.signature;\n }\n\n if (Array.isArray(extensions.turns)) {\n attributes[\"orchestrator.turns\"] = extensions.turns.length;\n }\n}\n\nfunction addToolAttributes(attributes: Record<string, unknown>, extensions: ReportExtensions): void {\n if (extensions.tripIndex !== undefined) {\n attributes[\"tool.tripIndex\"] = extensions.tripIndex;\n }\n\n if (extensions.recoveredFrom !== undefined) {\n attributes[\"tool.recoveredFrom\"] = extensions.recoveredFrom;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuDA,SAAgB,sBAAsB,QAAyD;CAC7F,MAAM,aAAa;CACnB,MAAM,aAAsC,CAAC;CAE7C,IAAI,OAAO,aAAa,UAAa,OAAO,SAAS,SAAS,GAC5D,WAAW,aAAa,OAAO,SAAS;CAG1C,QAAQ,OAAO,MAAf;EACE,KAAK;GACH,mBAAmB,YAAY,UAAU;GACzC;EAGF,KAAK;GACH,sBAAsB,YAAY,UAAU;GAC5C;EAGF,KAAK;EACL,KAAK;GAGH,wBAAwB,YAAY,UAAU;GAC9C;EAGF,KAAK;GACH,0BAA0B,YAAY,UAAU;GAChD;EAGF,KAAK;GACH,kBAAkB,YAAY,UAAU;GACxC;EAGF,SACE;CAEJ;CAEA,IAAI,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,GACrC;CAGF,OAAO;AACT;AAEA,SAAS,mBAAmB,YAAqC,YAAoC;CACnG,IAAI,MAAM,QAAQ,WAAW,KAAK,GAChC,WAAW,iBAAiB,WAAW,MAAM;CAG/C,IAAI,WAAW,OAAO,SAAS,QAC7B,WAAW,sBAAsB,WAAW,MAAM;CAGpD,IAAI,WAAW,OAAO,aAAa,QACjC,WAAW,0BAA0B,WAAW,MAAM;CAOxD,IAAI,WAAW,eAAe,QAC5B,WAAW,sBAAsB,WAAW;CAG9C,IAAI,WAAW,kBAAkB,QAC/B,WAAW,yBAAyB,WAAW;AAEnD;AAEA,SAAS,sBAAsB,YAAqC,YAAoC;CACtG,IAAI,WAAW,iBAAiB,QAC9B,WAAW,mBAAmB,WAAW;CAG3C,IAAI,WAAW,cAAc,QAC3B,WAAW,wBAAwB,WAAW;CAGhD,IAAI,WAAW,UAAU,QACvB,WAAW,oBAAoB,OAAO,KAAK,WAAW,KAAK,CAAC,CAAC;AAEjE;AAEA,SAAS,wBAAwB,YAAqC,YAAoC;CACxG,IAAI,WAAW,mBAAmB,QAChC,WAAW,qBAAqB,WAAW;CAG7C,IAAI,WAAW,iBAAiB,QAC9B,WAAW,6BAA6B,WAAW;CAGrD,IAAI,WAAW,eAAe,QAC5B,WAAW,2BAA2B,WAAW;AAErD;AAEA,SAAS,0BAA0B,YAAqC,YAAoC;CAC1G,IAAI,WAAW,cAAc,QAC3B,WAAW,4BAA4B,WAAW;CAGpD,IAAI,WAAW,cAAc,QAC3B,WAAW,4BAA4B,WAAW;CAGpD,IAAI,MAAM,QAAQ,WAAW,KAAK,GAChC,WAAW,wBAAwB,WAAW,MAAM;AAExD;AAEA,SAAS,kBAAkB,YAAqC,YAAoC;CAClG,IAAI,WAAW,cAAc,QAC3B,WAAW,oBAAoB,WAAW;CAG5C,IAAI,WAAW,kBAAkB,QAC/B,WAAW,wBAAwB,WAAW;AAElD"}
1
+ {"version":3,"file":"extract-span-attributes.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/extract-span-attributes.ts"],"sourcesContent":["import type { BaseReport } from \"@warlock.js/ai\";\n\n/**\n * Per-primitive `BaseReport` extension fields the collector surfaces as\n * span attributes. Declared as a structural superset (every field\n * optional) so a single reader can pull whatever the concrete report\n * carried without narrowing on `type` first — a `BaseReport` widened to\n * this shape exposes `undefined` for the fields its primitive doesn't\n * set, and the extractor simply skips those.\n *\n * Mirrors the public per-primitive report types in `@warlock.js/ai`\n * (`AgentReport`, `WorkflowReport`, `SupervisorReport`,\n * `OrchestratorReport`, `ToolCall`) — kept structural rather than a\n * union import so adding a new optional report field upstream is a\n * non-breaking read here.\n */\ntype ReportExtensions = {\n model?: { name?: string; provider?: string };\n trips?: unknown[];\n promptName?: string;\n promptVersion?: string;\n workflowName?: string;\n supervisorName?: string;\n signature?: string;\n terminatedBy?: string;\n iterations?: number;\n steps?: Record<string, unknown>;\n turns?: unknown[];\n turnIndex?: number;\n tripIndex?: number;\n callId?: string;\n recoveredFrom?: string;\n};\n\n/**\n * Build the free-form `TraceSpan.attributes` bag for one report node.\n *\n * The collector keeps the first-class span fields (identity, timing,\n * status, usage, error) on the span itself and routes everything\n * primitive-specific here — trip/step/iteration counts, the model\n * identity an agent ran against, the tool's originating trip index, a\n * supervisor's termination reason. Exporters forward this verbatim as\n * backend span attributes (OTel attributes, Langfuse metadata).\n *\n * Only populated keys are emitted; the function returns `undefined`\n * when the node carried no extra detail, so the optional\n * `TraceSpan.attributes` field stays absent rather than holding an\n * empty object (matches the contract's \"absent when empty\" note).\n *\n * Retry count is surfaced from the shared `BaseReport.attempts` for\n * every primitive so cost dashboards see the real call count.\n *\n * @example\n * const attributes = extractSpanAttributes(agentReport);\n * // { \"agent.trips\": 3, \"agent.model.name\": \"gpt-4o\", \"agent.model.provider\": \"openai\" }\n */\nexport function extractSpanAttributes(report: BaseReport): Record<string, unknown> | undefined {\n const extensions = report as BaseReport & ReportExtensions;\n const attributes: Record<string, unknown> = {};\n\n if (report.attempts !== undefined && report.attempts.length > 0) {\n attributes[\"retries\"] = report.attempts.length;\n }\n\n switch (report.type) {\n case \"agent\": {\n addAgentAttributes(attributes, extensions);\n break;\n }\n\n case \"workflow\": {\n addWorkflowAttributes(attributes, extensions);\n break;\n }\n\n case \"supervisor\":\n case \"team\": {\n // ai.team reuses the supervisor engine, so a team report carries the\n // same supervisorName / terminatedBy / iterations fields.\n addSupervisorAttributes(attributes, extensions);\n break;\n }\n\n case \"orchestrator\": {\n addOrchestratorAttributes(attributes, extensions);\n break;\n }\n\n case \"tool\": {\n addToolAttributes(attributes, extensions);\n break;\n }\n\n default: {\n break;\n }\n }\n\n if (Object.keys(attributes).length === 0) {\n return undefined;\n }\n\n return attributes;\n}\n\nfunction addAgentAttributes(\n attributes: Record<string, unknown>,\n extensions: ReportExtensions,\n): void {\n if (Array.isArray(extensions.trips)) {\n attributes[\"agent.trips\"] = extensions.trips.length;\n }\n\n if (extensions.model?.name !== undefined) {\n attributes[\"agent.model.name\"] = extensions.model.name;\n }\n\n if (extensions.model?.provider !== undefined) {\n attributes[\"agent.model.provider\"] = extensions.model.provider;\n }\n\n // Prompt-version linkage (core `AgentReport.promptName` / `promptVersion`).\n // Present only when the agent ran against a *named* `ai.prompts` builder;\n // surfaced so the dashboard can group / filter runs by `name@version` and\n // attribute behavior shifts to a specific prompt revision.\n if (extensions.promptName !== undefined) {\n attributes[\"agent.promptName\"] = extensions.promptName;\n }\n\n if (extensions.promptVersion !== undefined) {\n attributes[\"agent.promptVersion\"] = extensions.promptVersion;\n }\n}\n\nfunction addWorkflowAttributes(\n attributes: Record<string, unknown>,\n extensions: ReportExtensions,\n): void {\n if (extensions.workflowName !== undefined) {\n attributes[\"workflow.name\"] = extensions.workflowName;\n }\n\n if (extensions.signature !== undefined) {\n attributes[\"workflow.signature\"] = extensions.signature;\n }\n\n if (extensions.steps !== undefined) {\n attributes[\"workflow.steps\"] = Object.keys(extensions.steps).length;\n }\n}\n\nfunction addSupervisorAttributes(\n attributes: Record<string, unknown>,\n extensions: ReportExtensions,\n): void {\n if (extensions.supervisorName !== undefined) {\n attributes[\"supervisor.name\"] = extensions.supervisorName;\n }\n\n if (extensions.terminatedBy !== undefined) {\n attributes[\"supervisor.terminatedBy\"] = extensions.terminatedBy;\n }\n\n if (extensions.iterations !== undefined) {\n attributes[\"supervisor.iterations\"] = extensions.iterations;\n }\n}\n\nfunction addOrchestratorAttributes(\n attributes: Record<string, unknown>,\n extensions: ReportExtensions,\n): void {\n if (extensions.turnIndex !== undefined) {\n attributes[\"orchestrator.turnIndex\"] = extensions.turnIndex;\n }\n\n if (extensions.signature !== undefined) {\n attributes[\"orchestrator.signature\"] = extensions.signature;\n }\n\n if (Array.isArray(extensions.turns)) {\n attributes[\"orchestrator.turns\"] = extensions.turns.length;\n }\n}\n\nfunction addToolAttributes(\n attributes: Record<string, unknown>,\n extensions: ReportExtensions,\n): void {\n if (extensions.tripIndex !== undefined) {\n attributes[\"tool.tripIndex\"] = extensions.tripIndex;\n }\n\n if (extensions.callId !== undefined) {\n attributes[\"tool.callId\"] = extensions.callId;\n }\n\n if (extensions.recoveredFrom !== undefined) {\n attributes[\"tool.recoveredFrom\"] = extensions.recoveredFrom;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwDA,SAAgB,sBAAsB,QAAyD;CAC7F,MAAM,aAAa;CACnB,MAAM,aAAsC,CAAC;CAE7C,IAAI,OAAO,aAAa,UAAa,OAAO,SAAS,SAAS,GAC5D,WAAW,aAAa,OAAO,SAAS;CAG1C,QAAQ,OAAO,MAAf;EACE,KAAK;GACH,mBAAmB,YAAY,UAAU;GACzC;EAGF,KAAK;GACH,sBAAsB,YAAY,UAAU;GAC5C;EAGF,KAAK;EACL,KAAK;GAGH,wBAAwB,YAAY,UAAU;GAC9C;EAGF,KAAK;GACH,0BAA0B,YAAY,UAAU;GAChD;EAGF,KAAK,QACH,kBAAkB,YAAY,UAAU;CAO5C;CAEA,IAAI,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,GACrC;CAGF,OAAO;AACT;AAEA,SAAS,mBACP,YACA,YACM;CACN,IAAI,MAAM,QAAQ,WAAW,KAAK,GAChC,WAAW,iBAAiB,WAAW,MAAM;CAG/C,IAAI,WAAW,OAAO,SAAS,QAC7B,WAAW,sBAAsB,WAAW,MAAM;CAGpD,IAAI,WAAW,OAAO,aAAa,QACjC,WAAW,0BAA0B,WAAW,MAAM;CAOxD,IAAI,WAAW,eAAe,QAC5B,WAAW,sBAAsB,WAAW;CAG9C,IAAI,WAAW,kBAAkB,QAC/B,WAAW,yBAAyB,WAAW;AAEnD;AAEA,SAAS,sBACP,YACA,YACM;CACN,IAAI,WAAW,iBAAiB,QAC9B,WAAW,mBAAmB,WAAW;CAG3C,IAAI,WAAW,cAAc,QAC3B,WAAW,wBAAwB,WAAW;CAGhD,IAAI,WAAW,UAAU,QACvB,WAAW,oBAAoB,OAAO,KAAK,WAAW,KAAK,CAAC,CAAC;AAEjE;AAEA,SAAS,wBACP,YACA,YACM;CACN,IAAI,WAAW,mBAAmB,QAChC,WAAW,qBAAqB,WAAW;CAG7C,IAAI,WAAW,iBAAiB,QAC9B,WAAW,6BAA6B,WAAW;CAGrD,IAAI,WAAW,eAAe,QAC5B,WAAW,2BAA2B,WAAW;AAErD;AAEA,SAAS,0BACP,YACA,YACM;CACN,IAAI,WAAW,cAAc,QAC3B,WAAW,4BAA4B,WAAW;CAGpD,IAAI,WAAW,cAAc,QAC3B,WAAW,4BAA4B,WAAW;CAGpD,IAAI,MAAM,QAAQ,WAAW,KAAK,GAChC,WAAW,wBAAwB,WAAW,MAAM;AAExD;AAEA,SAAS,kBACP,YACA,YACM;CACN,IAAI,WAAW,cAAc,QAC3B,WAAW,oBAAoB,WAAW;CAG5C,IAAI,WAAW,WAAW,QACxB,WAAW,iBAAiB,WAAW;CAGzC,IAAI,WAAW,kBAAkB,QAC/B,WAAW,wBAAwB,WAAW;AAElD"}
@@ -3,4 +3,5 @@ import { CollectorOptions, ExporterErrorHandler, createCollector } from "./colle
3
3
  import { reportToTrace } from "./report-to-trace.mjs";
4
4
  import { reportToSpan } from "./report-to-span.mjs";
5
5
  import { extractSpanAttributes } from "./extract-span-attributes.mjs";
6
- import { normalizeError } from "./normalize-error.mjs";
6
+ import { normalizeError } from "./normalize-error.mjs";
7
+ export { type CollectorOptions, type ContentCaptureOptions, type ContentRedactor, type ExporterErrorHandler, createCollector, extractSpanAttributes, normalizeError, reportToSpan, reportToTrace };
@@ -4,4 +4,4 @@ import { reportToSpan } from "./report-to-span.mjs";
4
4
  import { reportToTrace } from "./report-to-trace.mjs";
5
5
  import { createCollector } from "./collector.mjs";
6
6
 
7
- export { };
7
+ export { createCollector, extractSpanAttributes, normalizeError, reportToSpan, reportToTrace };
@@ -1,5 +1,4 @@
1
1
  import { TraceSpanError } from "../contracts/trace.type.mjs";
2
-
3
2
  //#region ../../packages/ai-panoptic/src/collector/normalize-error.d.ts
4
3
  /**
5
4
  * Project a captured execution error onto the structural
@@ -21,7 +20,6 @@ import { TraceSpanError } from "../contracts/trace.type.mjs";
21
20
  * const spanError = normalizeError(report.error);
22
21
  * // { type: "RATE_LIMIT", message: "429 Too Many Requests", stack: "..." }
23
22
  */
24
- declare function normalizeError(error: unknown): TraceSpanError | undefined;
23
+ export declare function normalizeError(error: unknown): TraceSpanError | undefined;
25
24
  //#endregion
26
- export { normalizeError };
27
25
  //# sourceMappingURL=normalize-error.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-error.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/normalize-error.ts"],"mappings":";;;;;AAuBA;;;;AAA8D;;;;;;;;;;;;;;iBAA9C,cAAA,CAAe,KAAA,YAAiB,cAAc"}
1
+ {"version":3,"file":"normalize-error.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/normalize-error.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;wBAuBgB,eAAe,iBAAiB"}
@@ -1,7 +1,6 @@
1
1
  import { TraceSpan } from "../contracts/trace.type.mjs";
2
2
  import { ContentCaptureOptions } from "./content-capture.type.mjs";
3
3
  import { BaseReport } from "@warlock.js/ai";
4
-
5
4
  //#region ../../packages/ai-panoptic/src/collector/report-to-span.d.ts
6
5
  /**
7
6
  * Project one {@link BaseReport} node — and its entire subtree — into a
@@ -32,7 +31,6 @@ import { BaseReport } from "@warlock.js/ai";
32
31
  * const root = reportToSpan(result.report);
33
32
  * console.log(root.spanId, root.traceId, root.children.length);
34
33
  */
35
- declare function reportToSpan(report: BaseReport, options?: ContentCaptureOptions): TraceSpan;
34
+ export declare function reportToSpan(report: BaseReport, options?: ContentCaptureOptions): TraceSpan;
36
35
  //#endregion
37
- export { reportToSpan };
38
36
  //# sourceMappingURL=report-to-span.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"report-to-span.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/report-to-span.ts"],"mappings":";;;;;;;AAmCA;;;;;;;;;;;;;;AAA4F;;;;;;;;;;;;;iBAA5E,YAAA,CAAa,MAAA,EAAQ,UAAA,EAAY,OAAA,GAAU,qBAAA,GAAwB,SAAA"}
1
+ {"version":3,"file":"report-to-span.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/report-to-span.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAmCgB,aAAa,QAAQ,YAAY,UAAU,wBAAwB"}
@@ -1 +1 @@
1
- {"version":3,"file":"report-to-span.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/report-to-span.ts"],"sourcesContent":["import type { BaseReport } from \"@warlock.js/ai\";\nimport type { TraceSpan } from \"../contracts/trace.type\";\nimport type { ContentCaptureOptions, ContentRedactor } from \"./content-capture.type\";\nimport { extractSpanAttributes } from \"./extract-span-attributes\";\nimport { normalizeError } from \"./normalize-error\";\n\n/**\n * Project one {@link BaseReport} node — and its entire subtree — into a\n * {@link TraceSpan}. Pure and recursive: identity, timing, status, and\n * the rolled-up `usage` map across 1:1 from the report; lineage maps\n * `runId → spanId`, `parentRunId → parentSpanId`, `rootRunId → traceId`;\n * children recurse in invocation order so the span tree mirrors the\n * report tree exactly.\n *\n * The error is normalized to the JSON-safe {@link\n * import(\"../contracts/trace.type\").TraceSpanError} shape only when the\n * node carried one (failed / cancelled). Primitive-specific detail that\n * has no first-class span field (trip / step / iteration counts, model\n * identity, tool trip index) is routed into the optional `attributes`\n * bag via {@link extractSpanAttributes}.\n *\n * When {@link ContentCaptureOptions.captureContent} is set, the raw\n * prompt/response (agents) and args/result (tools) are additionally\n * copied onto `span.input` / `span.output` — off by default because\n * payloads are large and often sensitive. A {@link ContentRedactor} can\n * mask each value first.\n *\n * No external lookup is needed — a `BaseReport` already carries\n * everything a span requires, so a collector can flatten a tree without\n * consulting any other source.\n *\n * @example\n * const root = reportToSpan(result.report);\n * console.log(root.spanId, root.traceId, root.children.length);\n */\nexport function reportToSpan(report: BaseReport, options?: ContentCaptureOptions): TraceSpan {\n const span: TraceSpan = {\n spanId: report.runId,\n traceId: report.rootRunId,\n name: report.name,\n type: report.type,\n status: report.status,\n startedAt: report.startedAt,\n endedAt: report.endedAt,\n duration: report.duration,\n usage: report.usage,\n children: report.children.map((child) => reportToSpan(child, options)),\n };\n\n if (report.parentRunId !== undefined) {\n span.parentSpanId = report.parentRunId;\n }\n\n if (report.sessionId !== undefined) {\n span.sessionId = report.sessionId;\n }\n\n if (report.version !== undefined) {\n span.version = report.version;\n }\n\n const error = normalizeError((report as { error?: unknown }).error);\n if (error !== undefined) {\n span.error = error;\n }\n\n const attributes = extractSpanAttributes(report);\n if (attributes !== undefined) {\n span.attributes = attributes;\n }\n\n if (options?.captureContent) {\n captureContent(span, report, options);\n }\n\n return span;\n}\n\n/** Per-primitive content fields read off a widened report node. */\ntype ContentReport = {\n input?: unknown;\n output?: unknown;\n systemPrompt?: string;\n trips?: Array<{ input?: unknown; output?: unknown }>;\n /**\n * The full assembled conversation an agent run captured when its\n * `captureMessages` option was set (core `AgentReport.messages`).\n * Present only on opted-in agent runs; absent otherwise.\n */\n messages?: unknown;\n};\n\n/**\n * Copy the node's raw content onto `span.input` / `span.output`.\n *\n * - Tools carry the call arguments + return value directly on the report\n * (`ToolCall.input` / `ToolCall.output`).\n * - Agents carry a `trips[]` history plus the resolved `systemPrompt`. The\n * input is emitted as a `[system, user]` chat array — so backends like\n * Langfuse render the full prompt as sent — or the bare user string when\n * there's no system prompt. The output is the last NON-EMPTY trip\n * `output` (the final response text); a failed / max-trips run can end on\n * a trip whose `output` is `\"\"` or tool-call-only, so we scan back for the\n * last one that carried text. Intermediate trips store a `\"[tool results]\"`\n * placeholder upstream.\n * - When {@link ContentCaptureOptions.fullHistory} is on AND the agent run\n * opted into `captureMessages` (so the report carries a `messages`\n * array), the *whole* `CapturedMessage[]` is emitted as `span.input`\n * instead of the `[system, user]` first-trip array — every role, every\n * trip. The output stays the last non-empty trip output. When `messages`\n * is absent the branch falls back to today's first-trip logic, so a run\n * that didn't opt in degrades gracefully.\n *\n * Each value is passed through the optional {@link ContentRedactor};\n * a redactor returning `undefined` drops the field. Under `fullHistory`\n * the redactor receives the full array as a single value.\n */\nfunction captureContent(\n span: TraceSpan,\n report: BaseReport,\n options: ContentCaptureOptions,\n): void {\n const node = report as BaseReport & ContentReport;\n const redact = options.redactContent;\n\n let input: unknown;\n let output: unknown;\n\n if (report.type === \"tool\") {\n input = node.input;\n output = node.output;\n } else if (\n options.fullHistory &&\n Array.isArray(node.messages) &&\n node.messages.length > 0\n ) {\n // Full-history capture: the entire assembled conversation as a single\n // input value. Output remains the agent's final response text.\n input = node.messages;\n output = Array.isArray(node.trips) ? lastNonEmptyOutput(node.trips) : undefined;\n } else if (Array.isArray(node.trips) && node.trips.length > 0) {\n const userInput = node.trips[0]?.input;\n // Emit a [system, user] chat array when the agent carried a system\n // prompt, so backends (Langfuse) render the full prompt as sent;\n // otherwise keep the bare user string.\n input =\n typeof node.systemPrompt === \"string\" && node.systemPrompt.length > 0\n ? [\n { role: \"system\", content: node.systemPrompt },\n { role: \"user\", content: userInput },\n ]\n : userInput;\n output = lastNonEmptyOutput(node.trips);\n }\n\n if (input !== undefined) {\n const value = redact ? redact(input, { name: span.name, type: span.type, field: \"input\" }) : input;\n if (value !== undefined) {\n span.input = value;\n }\n }\n\n if (output !== undefined) {\n const value = redact ? redact(output, { name: span.name, type: span.type, field: \"output\" }) : output;\n if (value !== undefined) {\n span.output = value;\n }\n }\n}\n\n/**\n * The last trip output that actually carries text — the agent's final\n * response on the happy path. A failed or max-trips run can end on a trip\n * whose `output` is `\"\"` or tool-call-only, so we scan backwards for the\n * last trip that produced text rather than blindly taking the final trip\n * (which would surface an empty string). Returns `undefined` when no trip\n * produced any output.\n */\nfunction lastNonEmptyOutput(trips: Array<{ output?: unknown }>): unknown {\n for (let i = trips.length - 1; i >= 0; i -= 1) {\n const out = trips[i]?.output;\n const hasText = typeof out === \"string\" ? out.length > 0 : out !== undefined;\n\n if (hasText) {\n return out;\n }\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,aAAa,QAAoB,SAA4C;CAC3F,MAAM,OAAkB;EACtB,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,MAAM,OAAO;EACb,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,OAAO,OAAO;EACd,UAAU,OAAO,SAAS,KAAK,UAAU,aAAa,OAAO,OAAO,CAAC;CACvE;CAEA,IAAI,OAAO,gBAAgB,QACzB,KAAK,eAAe,OAAO;CAG7B,IAAI,OAAO,cAAc,QACvB,KAAK,YAAY,OAAO;CAG1B,IAAI,OAAO,YAAY,QACrB,KAAK,UAAU,OAAO;CAGxB,MAAM,QAAQ,eAAgB,OAA+B,KAAK;CAClE,IAAI,UAAU,QACZ,KAAK,QAAQ;CAGf,MAAM,aAAa,sBAAsB,MAAM;CAC/C,IAAI,eAAe,QACjB,KAAK,aAAa;CAGpB,IAAI,SAAS,gBACX,eAAe,MAAM,QAAQ,OAAO;CAGtC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAS,eACP,MACA,QACA,SACM;CACN,MAAM,OAAO;CACb,MAAM,SAAS,QAAQ;CAEvB,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,SAAS,QAAQ;EAC1B,QAAQ,KAAK;EACb,SAAS,KAAK;CAChB,OAAO,IACL,QAAQ,eACR,MAAM,QAAQ,KAAK,QAAQ,KAC3B,KAAK,SAAS,SAAS,GACvB;EAGA,QAAQ,KAAK;EACb,SAAS,MAAM,QAAQ,KAAK,KAAK,IAAI,mBAAmB,KAAK,KAAK,IAAI;CACxE,OAAO,IAAI,MAAM,QAAQ,KAAK,KAAK,KAAK,KAAK,MAAM,SAAS,GAAG;EAC7D,MAAM,YAAY,KAAK,MAAM,EAAE,EAAE;EAIjC,QACE,OAAO,KAAK,iBAAiB,YAAY,KAAK,aAAa,SAAS,IAChE,CACE;GAAE,MAAM;GAAU,SAAS,KAAK;EAAa,GAC7C;GAAE,MAAM;GAAQ,SAAS;EAAU,CACrC,IACA;EACN,SAAS,mBAAmB,KAAK,KAAK;CACxC;CAEA,IAAI,UAAU,QAAW;EACvB,MAAM,QAAQ,SAAS,OAAO,OAAO;GAAE,MAAM,KAAK;GAAM,MAAM,KAAK;GAAM,OAAO;EAAQ,CAAC,IAAI;EAC7F,IAAI,UAAU,QACZ,KAAK,QAAQ;CAEjB;CAEA,IAAI,WAAW,QAAW;EACxB,MAAM,QAAQ,SAAS,OAAO,QAAQ;GAAE,MAAM,KAAK;GAAM,MAAM,KAAK;GAAM,OAAO;EAAS,CAAC,IAAI;EAC/F,IAAI,UAAU,QACZ,KAAK,SAAS;CAElB;AACF;;;;;;;;;AAUA,SAAS,mBAAmB,OAA6C;CACvE,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;EAC7C,MAAM,MAAM,MAAM,EAAE,EAAE;EAGtB,IAFgB,OAAO,QAAQ,WAAW,IAAI,SAAS,IAAI,QAAQ,QAGjE,OAAO;CAEX;AAGF"}
1
+ {"version":3,"file":"report-to-span.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/report-to-span.ts"],"sourcesContent":["import type { BaseReport } from \"@warlock.js/ai\";\nimport type { TraceSpan } from \"../contracts/trace.type\";\nimport type { ContentCaptureOptions } from \"./content-capture.type\";\nimport { extractSpanAttributes } from \"./extract-span-attributes\";\nimport { normalizeError } from \"./normalize-error\";\n\n/**\n * Project one {@link BaseReport} node — and its entire subtree — into a\n * {@link TraceSpan}. Pure and recursive: identity, timing, status, and\n * the rolled-up `usage` map across 1:1 from the report; lineage maps\n * `runId → spanId`, `parentRunId → parentSpanId`, `rootRunId → traceId`;\n * children recurse in invocation order so the span tree mirrors the\n * report tree exactly.\n *\n * The error is normalized to the JSON-safe {@link\n * import(\"../contracts/trace.type\").TraceSpanError} shape only when the\n * node carried one (failed / cancelled). Primitive-specific detail that\n * has no first-class span field (trip / step / iteration counts, model\n * identity, tool trip index) is routed into the optional `attributes`\n * bag via {@link extractSpanAttributes}.\n *\n * When {@link ContentCaptureOptions.captureContent} is set, the raw\n * prompt/response (agents) and args/result (tools) are additionally\n * copied onto `span.input` / `span.output` — off by default because\n * payloads are large and often sensitive. A {@link ContentRedactor} can\n * mask each value first.\n *\n * No external lookup is needed — a `BaseReport` already carries\n * everything a span requires, so a collector can flatten a tree without\n * consulting any other source.\n *\n * @example\n * const root = reportToSpan(result.report);\n * console.log(root.spanId, root.traceId, root.children.length);\n */\nexport function reportToSpan(report: BaseReport, options?: ContentCaptureOptions): TraceSpan {\n const span: TraceSpan = {\n spanId: report.runId,\n traceId: report.rootRunId,\n name: report.name,\n type: report.type,\n status: report.status,\n startedAt: report.startedAt,\n endedAt: report.endedAt,\n duration: report.duration,\n usage: report.usage,\n children: report.children.map((child) => reportToSpan(child, options)),\n };\n\n if (report.parentRunId !== undefined) {\n span.parentSpanId = report.parentRunId;\n }\n\n if (report.sessionId !== undefined) {\n span.sessionId = report.sessionId;\n }\n\n if (report.version !== undefined) {\n span.version = report.version;\n }\n\n const error = normalizeError((report as { error?: unknown }).error);\n if (error !== undefined) {\n span.error = error;\n }\n\n const attributes = extractSpanAttributes(report);\n if (attributes !== undefined) {\n span.attributes = attributes;\n }\n\n if (options?.captureContent) {\n captureContent(span, report, options);\n }\n\n return span;\n}\n\n/** Per-primitive content fields read off a widened report node. */\ntype ContentReport = {\n input?: unknown;\n output?: unknown;\n systemPrompt?: string;\n trips?: Array<{ input?: unknown; output?: unknown }>;\n /**\n * The full assembled conversation an agent run captured when its\n * `captureMessages` option was set (core `AgentReport.messages`).\n * Present only on opted-in agent runs; absent otherwise.\n */\n messages?: unknown;\n};\n\n/**\n * Copy the node's raw content onto `span.input` / `span.output`.\n *\n * - Tools carry the call arguments + return value directly on the report\n * (`ToolCall.input` / `ToolCall.output`).\n * - Agents carry a `trips[]` history plus the resolved `systemPrompt`. The\n * input is emitted as a `[system, user]` chat array — so backends like\n * Langfuse render the full prompt as sent — or the bare user string when\n * there's no system prompt. The output is the last NON-EMPTY trip\n * `output` (the final response text); a failed / max-trips run can end on\n * a trip whose `output` is `\"\"` or tool-call-only, so we scan back for the\n * last one that carried text. Intermediate trips store a `\"[tool results]\"`\n * placeholder upstream.\n * - When {@link ContentCaptureOptions.fullHistory} is on AND the agent run\n * opted into `captureMessages` (so the report carries a `messages`\n * array), the *whole* `CapturedMessage[]` is emitted as `span.input`\n * instead of the `[system, user]` first-trip array — every role, every\n * trip. The output stays the last non-empty trip output. When `messages`\n * is absent the branch falls back to today's first-trip logic, so a run\n * that didn't opt in degrades gracefully.\n *\n * Each value is passed through the optional {@link ContentRedactor};\n * a redactor returning `undefined` drops the field. Under `fullHistory`\n * the redactor receives the full array as a single value.\n */\nfunction captureContent(span: TraceSpan, report: BaseReport, options: ContentCaptureOptions): void {\n const node = report as BaseReport & ContentReport;\n const redact = options.redactContent;\n\n let input: unknown;\n let output: unknown;\n\n if (report.type === \"tool\") {\n input = node.input;\n output = node.output;\n } else if (options.fullHistory && Array.isArray(node.messages) && node.messages.length > 0) {\n // Full-history capture: the entire assembled conversation as a single\n // input value. Output remains the agent's final response text.\n input = node.messages;\n output = Array.isArray(node.trips) ? lastNonEmptyOutput(node.trips) : undefined;\n } else if (Array.isArray(node.trips) && node.trips.length > 0) {\n const userInput = node.trips[0]?.input;\n // Emit a [system, user] chat array when the agent carried a system\n // prompt, so backends (Langfuse) render the full prompt as sent;\n // otherwise keep the bare user string.\n input =\n typeof node.systemPrompt === \"string\" && node.systemPrompt.length > 0\n ? [\n { role: \"system\", content: node.systemPrompt },\n { role: \"user\", content: userInput },\n ]\n : userInput;\n output = lastNonEmptyOutput(node.trips);\n }\n\n if (input !== undefined) {\n const value = redact\n ? redact(input, { name: span.name, type: span.type, field: \"input\" })\n : input;\n if (value !== undefined) {\n span.input = value;\n }\n }\n\n if (output !== undefined) {\n const value = redact\n ? redact(output, { name: span.name, type: span.type, field: \"output\" })\n : output;\n if (value !== undefined) {\n span.output = value;\n }\n }\n}\n\n/**\n * The last trip output that actually carries text — the agent's final\n * response on the happy path. A failed or max-trips run can end on a trip\n * whose `output` is `\"\"` or tool-call-only, so we scan backwards for the\n * last trip that produced text rather than blindly taking the final trip\n * (which would surface an empty string). Returns `undefined` when no trip\n * produced any output.\n */\nfunction lastNonEmptyOutput(trips: Array<{ output?: unknown }>): unknown {\n for (let i = trips.length - 1; i >= 0; i -= 1) {\n const out = trips[i]?.output;\n const hasText = typeof out === \"string\" ? out.length > 0 : out !== undefined;\n\n if (hasText) {\n return out;\n }\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,aAAa,QAAoB,SAA4C;CAC3F,MAAM,OAAkB;EACtB,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,MAAM,OAAO;EACb,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,OAAO,OAAO;EACd,UAAU,OAAO,SAAS,KAAK,UAAU,aAAa,OAAO,OAAO,CAAC;CACvE;CAEA,IAAI,OAAO,gBAAgB,QACzB,KAAK,eAAe,OAAO;CAG7B,IAAI,OAAO,cAAc,QACvB,KAAK,YAAY,OAAO;CAG1B,IAAI,OAAO,YAAY,QACrB,KAAK,UAAU,OAAO;CAGxB,MAAM,QAAQ,eAAgB,OAA+B,KAAK;CAClE,IAAI,UAAU,QACZ,KAAK,QAAQ;CAGf,MAAM,aAAa,sBAAsB,MAAM;CAC/C,IAAI,eAAe,QACjB,KAAK,aAAa;CAGpB,IAAI,SAAS,gBACX,eAAe,MAAM,QAAQ,OAAO;CAGtC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAS,eAAe,MAAiB,QAAoB,SAAsC;CACjG,MAAM,OAAO;CACb,MAAM,SAAS,QAAQ;CAEvB,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,SAAS,QAAQ;EAC1B,QAAQ,KAAK;EACb,SAAS,KAAK;CAChB,OAAO,IAAI,QAAQ,eAAe,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,SAAS,GAAG;EAG1F,QAAQ,KAAK;EACb,SAAS,MAAM,QAAQ,KAAK,KAAK,IAAI,mBAAmB,KAAK,KAAK,IAAI;CACxE,OAAO,IAAI,MAAM,QAAQ,KAAK,KAAK,KAAK,KAAK,MAAM,SAAS,GAAG;EAC7D,MAAM,YAAY,KAAK,MAAM,EAAE,EAAE;EAIjC,QACE,OAAO,KAAK,iBAAiB,YAAY,KAAK,aAAa,SAAS,IAChE,CACE;GAAE,MAAM;GAAU,SAAS,KAAK;EAAa,GAC7C;GAAE,MAAM;GAAQ,SAAS;EAAU,CACrC,IACA;EACN,SAAS,mBAAmB,KAAK,KAAK;CACxC;CAEA,IAAI,UAAU,QAAW;EACvB,MAAM,QAAQ,SACV,OAAO,OAAO;GAAE,MAAM,KAAK;GAAM,MAAM,KAAK;GAAM,OAAO;EAAQ,CAAC,IAClE;EACJ,IAAI,UAAU,QACZ,KAAK,QAAQ;CAEjB;CAEA,IAAI,WAAW,QAAW;EACxB,MAAM,QAAQ,SACV,OAAO,QAAQ;GAAE,MAAM,KAAK;GAAM,MAAM,KAAK;GAAM,OAAO;EAAS,CAAC,IACpE;EACJ,IAAI,UAAU,QACZ,KAAK,SAAS;CAElB;AACF;;;;;;;;;AAUA,SAAS,mBAAmB,OAA6C;CACvE,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;EAC7C,MAAM,MAAM,MAAM,EAAE,EAAE;EAGtB,IAFgB,OAAO,QAAQ,WAAW,IAAI,SAAS,IAAI,QAAQ,QAGjE,OAAO;CAEX;AAGF"}
@@ -1,7 +1,6 @@
1
1
  import { Trace } from "../contracts/trace.type.mjs";
2
2
  import { ContentCaptureOptions } from "./content-capture.type.mjs";
3
3
  import { BaseReport } from "@warlock.js/ai";
4
-
5
4
  //#region ../../packages/ai-panoptic/src/collector/report-to-trace.d.ts
6
5
  /**
7
6
  * Project an outermost {@link BaseReport} (one whole `.execute()` /
@@ -33,7 +32,6 @@ import { BaseReport } from "@warlock.js/ai";
33
32
  * const trace = reportToTrace(result.report, result.error);
34
33
  * console.log(trace.traceId, trace.usage.total, trace.duration);
35
34
  */
36
- declare function reportToTrace(report: BaseReport, rootError?: unknown, options?: ContentCaptureOptions): Trace;
35
+ export declare function reportToTrace(report: BaseReport, rootError?: unknown, options?: ContentCaptureOptions): Trace;
37
36
  //#endregion
38
- export { reportToTrace };
39
37
  //# sourceMappingURL=report-to-trace.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"report-to-trace.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/report-to-trace.ts"],"mappings":";;;;;;;AAoCA;;;;;;;;;;;;;;;AAIQ;;;;;;;;;;;;;iBAJQ,aAAA,CACd,MAAA,EAAQ,UAAA,EACR,SAAA,YACA,OAAA,GAAU,qBAAA,GACT,KAAA"}
1
+ {"version":3,"file":"report-to-trace.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/collector/report-to-trace.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAoCgB,cACd,QAAQ,YACR,qBACA,UAAU,wBACT"}
@@ -1,5 +1,5 @@
1
+ import "../dashboard/dashboard.type.mjs";
1
2
  import { PanopticConfig } from "./panoptic-config.type.mjs";
2
-
3
3
  //#region ../../packages/ai-panoptic/src/config/apply-panoptic-config.d.ts
4
4
  /**
5
5
  * Read a {@link PanopticConfig} and wire panoptic onto the core observe
@@ -21,7 +21,6 @@ import { PanopticConfig } from "./panoptic-config.type.mjs";
21
21
  * one and a fresh store was created — primarily for tests; callers can
22
22
  * ignore it.
23
23
  */
24
- declare function applyPanopticConfig(config?: PanopticConfig): void;
24
+ export declare function applyPanopticConfig(config?: PanopticConfig): void;
25
25
  //#endregion
26
- export { applyPanopticConfig };
27
26
  //# sourceMappingURL=apply-panoptic-config.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apply-panoptic-config.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/config/apply-panoptic-config.ts"],"mappings":";;;;;AAiDA;;;;AAA2D;;;;;;;;;;;;;;iBAA3C,mBAAA,CAAoB,MAAuB,GAAd,cAAc"}
1
+ {"version":3,"file":"apply-panoptic-config.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/config/apply-panoptic-config.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;wBAiDgB,oBAAoB,SAAS"}
@@ -1 +1 @@
1
- {"version":3,"file":"apply-panoptic-config.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/config/apply-panoptic-config.ts"],"sourcesContent":["import type { ExecutionReport, Observer } from \"@warlock.js/ai\";\nimport { registerObserver, setObserveAll } from \"@warlock.js/ai\";\nimport { log } from \"@warlock.js/logger\";\nimport type { ExporterContract } from \"../contracts/exporter.contract\";\nimport { dashboard } from \"../dashboard/dashboard\";\nimport type { DashboardHandle, DashboardOptions } from \"../dashboard/dashboard.type\";\nimport { panoptic } from \"../panoptic/panoptic\";\nimport type { Panoptic } from \"../panoptic/panoptic.type\";\nimport { createCacheTraceStore } from \"../store/cache-trace-store\";\nimport type { CacheTraceStoreHandle } from \"../store/cache-trace-store\";\nimport { createInMemoryTraceStore } from \"../store/in-memory-trace-store\";\nimport type { TraceStoreContract } from \"../store/trace-store.contract\";\nimport type { PanopticConfig } from \"./panoptic-config.type\";\n\n/**\n * Module-level applied state. Applying panoptic config is idempotent:\n * the collector is registered as a core `Observer` exactly once, the\n * dashboard is started at most once, and repeat calls only refresh the\n * `observeAll` flag (the latest config wins) without double-registering.\n */\ntype AppliedState = {\n /** The single collector registered as a core `Observer`. */\n panopticInstance: Panoptic;\n /** The dashboard handle, once started. Started at most once. */\n dashboardHandle?: DashboardHandle;\n};\n\nlet applied: AppliedState | undefined;\n\n/**\n * Read a {@link PanopticConfig} and wire panoptic onto the core observe\n * seam — the bridge `ai.config({ panoptic })` resolves through. Builds a\n * collector via the EXISTING {@link panoptic} factory (reusing its\n * collection pipeline, not reinventing it), registers it once via core's\n * `registerObserver` (the subscriber's `collect(report)` structurally IS\n * an {@link Observer}, threaded through a thin wrapper), sets\n * `observeAll`, and — when `config.dashboard` is set — starts the\n * dashboard over the config's store (a store-shaped exporter, or a fresh\n * in-memory store panoptic registers when none was supplied).\n *\n * **Idempotent.** Safe to call on every `onConfigApplied` notification:\n * the observer is registered once, the dashboard started once. Repeat\n * calls update `observeAll` to the latest value but never double-register\n * or double-start. `undefined` config is a no-op (nothing wired).\n *\n * @returns the resolved store-shaped exporter when the dashboard needs\n * one and a fresh store was created — primarily for tests; callers can\n * ignore it.\n */\nexport function applyPanopticConfig(config?: PanopticConfig): void {\n if (config === undefined) {\n return;\n }\n\n // observeAll always tracks the latest config, even on a repeat call.\n setObserveAll(Boolean(config.observeAll));\n\n if (applied === undefined) {\n const exporters = [...(config.exporters ?? [])];\n let store = findStore(exporters);\n\n // Track a cache store separately so we can await its hydration before\n // the dashboard reads it — the in-memory store needs no warm-up.\n let cacheStore: CacheTraceStoreHandle | undefined;\n\n // The dashboard needs a queryable store. If none was supplied via\n // exporters but a dashboard is requested, create one and register it\n // as an exporter so the collector fills it. A configured `cache` picks\n // the durable cache-backed store; otherwise fall back to in-memory so\n // the dashboard works with no cache configured.\n if (store === undefined && config.dashboard) {\n if (config.cache !== undefined) {\n const onError =\n config.onError ??\n ((error: unknown) => log.error(\"ai-panoptic\", \"cacheStore\", error));\n\n cacheStore = createCacheTraceStore(config.cache, { onError });\n store = cacheStore;\n } else {\n store = createInMemoryTraceStore();\n }\n\n exporters.push(store as unknown as ExporterContract);\n }\n\n const panopticInstance = panoptic({\n exporters,\n captureContent: config.captureContent,\n fullHistory: config.fullHistory,\n });\n registerObserver(toObserver(panopticInstance));\n\n applied = { panopticInstance };\n\n if (config.dashboard && store !== undefined) {\n const resolvedStore = store;\n\n // Hydrate the cache mirror (if any) before serving, so a restart\n // surfaces previously-persisted traces immediately. A bare in-memory\n // store resolves the readyGate instantly.\n const readyGate =\n cacheStore !== undefined ? cacheStore.ready() : Promise.resolve();\n\n void readyGate\n .catch(() => {\n // Hydration is best-effort — never block the dashboard on it.\n })\n .then(() => startDashboard(resolvedStore, config.dashboard ?? {}))\n .then((handle) => {\n if (applied !== undefined) {\n applied.dashboardHandle = handle;\n }\n });\n }\n }\n}\n\n/**\n * Reset the applied state — internal, test-only. Closes any running\n * dashboard and forgets the registered collector so a fresh\n * `applyPanopticConfig` starts clean. NOT part of the public surface and\n * does NOT unregister from the core observer registry (use core's\n * `clearObservers` for that in tests).\n */\nexport async function resetAppliedPanopticConfig(): Promise<void> {\n const handle = applied?.dashboardHandle;\n applied = undefined;\n\n if (handle !== undefined) {\n await handle.close();\n }\n}\n\n/**\n * The currently-running dashboard handle, or `undefined` when no\n * dashboard is active. Internal, test-only — lets a spec await the\n * asynchronously-started dashboard. NOT part of the public surface.\n */\nexport function getActiveDashboardHandle(): DashboardHandle | undefined {\n return applied?.dashboardHandle;\n}\n\n/**\n * Wrap a {@link Panoptic} subscriber as a core {@link Observer}. The\n * subscriber already exposes `collect(report)` with a matching signature,\n * but the thin wrapper makes the structural adaptation explicit and keeps\n * the registered object a minimal `Observer` rather than the whole\n * subscriber surface.\n */\nfunction toObserver(instance: Panoptic): Observer {\n return {\n collect(report: ExecutionReport): Promise<void> {\n return instance.collect(report);\n },\n };\n}\n\n/**\n * Find the first exporter that satisfies the {@link TraceStoreContract}\n * read surface (`query` / `get` / `aggregate`) — the in-memory store\n * doubles as an exporter, so a store passed via `exporters` is reused for\n * the dashboard rather than creating a second one.\n */\nfunction findStore(exporters: ExporterContract[]): TraceStoreContract | undefined {\n for (const exporter of exporters) {\n const candidate = exporter as unknown as Partial<TraceStoreContract>;\n\n if (\n typeof candidate.query === \"function\" &&\n typeof candidate.get === \"function\" &&\n typeof candidate.aggregate === \"function\"\n ) {\n return candidate as TraceStoreContract;\n }\n }\n\n return undefined;\n}\n\n/** Start the dashboard, normalizing the `true | DashboardOptions` switch. */\nfunction startDashboard(\n store: TraceStoreContract,\n dashboardConfig: boolean | DashboardOptions,\n): Promise<DashboardHandle> {\n const options: DashboardOptions =\n typeof dashboardConfig === \"object\" ? dashboardConfig : {};\n\n return dashboard(store, options);\n}\n"],"mappings":";;;;;;;;AA2BA,IAAI;;;;;;;;;;;;;;;;;;;;;AAsBJ,SAAgB,oBAAoB,QAA+B;CACjE,IAAI,WAAW,QACb;CAIF,cAAc,QAAQ,OAAO,UAAU,CAAC;CAExC,IAAI,YAAY,QAAW;EACzB,MAAM,YAAY,CAAC,GAAI,OAAO,aAAa,CAAC,CAAE;EAC9C,IAAI,QAAQ,UAAU,SAAS;EAI/B,IAAI;EAOJ,IAAI,UAAU,UAAa,OAAO,WAAW;GAC3C,IAAI,OAAO,UAAU,QAAW;IAC9B,MAAM,UACJ,OAAO,aACL,UAAmB,IAAI,MAAM,eAAe,cAAc,KAAK;IAEnE,aAAa,sBAAsB,OAAO,OAAO,EAAE,QAAQ,CAAC;IAC5D,QAAQ;GACV,OACE,QAAQ,yBAAyB;GAGnC,UAAU,KAAK,KAAoC;EACrD;EAEA,MAAM,mBAAmB,SAAS;GAChC;GACA,gBAAgB,OAAO;GACvB,aAAa,OAAO;EACtB,CAAC;EACD,iBAAiB,WAAW,gBAAgB,CAAC;EAE7C,UAAU,EAAE,iBAAiB;EAE7B,IAAI,OAAO,aAAa,UAAU,QAAW;GAC3C,MAAM,gBAAgB;GAQtB,CAFE,eAAe,SAAY,WAAW,MAAM,IAAI,QAAQ,QAAQ,EAEpD,CACX,YAAY,CAEb,CAAC,CAAC,CACD,WAAW,eAAe,eAAe,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CACjE,MAAM,WAAW;IAChB,IAAI,YAAY,QACd,QAAQ,kBAAkB;GAE9B,CAAC;EACL;CACF;AACF;;;;;;;;AAkCA,SAAS,WAAW,UAA8B;CAChD,OAAO,EACL,QAAQ,QAAwC;EAC9C,OAAO,SAAS,QAAQ,MAAM;CAChC,EACF;AACF;;;;;;;AAQA,SAAS,UAAU,WAA+D;CAChF,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,YAAY;EAElB,IACE,OAAO,UAAU,UAAU,cAC3B,OAAO,UAAU,QAAQ,cACzB,OAAO,UAAU,cAAc,YAE/B,OAAO;CAEX;AAGF;;AAGA,SAAS,eACP,OACA,iBAC0B;CAI1B,OAAO,UAAU,OAFf,OAAO,oBAAoB,WAAW,kBAAkB,CAAC,CAE5B;AACjC"}
1
+ {"version":3,"file":"apply-panoptic-config.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/config/apply-panoptic-config.ts"],"sourcesContent":["import type { ExecutionReport, Observer } from \"@warlock.js/ai\";\nimport { registerObserver, setObserveAll } from \"@warlock.js/ai\";\nimport { log } from \"@warlock.js/logger\";\nimport type { ExporterContract } from \"../contracts/exporter.contract\";\nimport { dashboard } from \"../dashboard/dashboard\";\nimport type { DashboardHandle, DashboardOptions } from \"../dashboard/dashboard.type\";\nimport { panoptic } from \"../panoptic/panoptic\";\nimport type { Panoptic } from \"../panoptic/panoptic.type\";\nimport { createCacheTraceStore } from \"../store/cache-trace-store\";\nimport type { CacheTraceStoreHandle } from \"../store/cache-trace-store\";\nimport { createInMemoryTraceStore } from \"../store/in-memory-trace-store\";\nimport type { TraceStoreContract } from \"../store/trace-store.contract\";\nimport type { PanopticConfig } from \"./panoptic-config.type\";\n\n/**\n * Module-level applied state. Applying panoptic config is idempotent:\n * the collector is registered as a core `Observer` exactly once, the\n * dashboard is started at most once, and repeat calls only refresh the\n * `observeAll` flag (the latest config wins) without double-registering.\n */\ntype AppliedState = {\n /** The single collector registered as a core `Observer`. */\n panopticInstance: Panoptic;\n /** The dashboard handle, once started. Started at most once. */\n dashboardHandle?: DashboardHandle;\n};\n\nlet applied: AppliedState | undefined;\n\n/**\n * Read a {@link PanopticConfig} and wire panoptic onto the core observe\n * seam — the bridge `ai.config({ panoptic })` resolves through. Builds a\n * collector via the EXISTING {@link panoptic} factory (reusing its\n * collection pipeline, not reinventing it), registers it once via core's\n * `registerObserver` (the subscriber's `collect(report)` structurally IS\n * an {@link Observer}, threaded through a thin wrapper), sets\n * `observeAll`, and — when `config.dashboard` is set — starts the\n * dashboard over the config's store (a store-shaped exporter, or a fresh\n * in-memory store panoptic registers when none was supplied).\n *\n * **Idempotent.** Safe to call on every `onConfigApplied` notification:\n * the observer is registered once, the dashboard started once. Repeat\n * calls update `observeAll` to the latest value but never double-register\n * or double-start. `undefined` config is a no-op (nothing wired).\n *\n * @returns the resolved store-shaped exporter when the dashboard needs\n * one and a fresh store was created — primarily for tests; callers can\n * ignore it.\n */\nexport function applyPanopticConfig(config?: PanopticConfig): void {\n if (config === undefined) {\n return;\n }\n\n // observeAll always tracks the latest config, even on a repeat call.\n setObserveAll(Boolean(config.observeAll));\n\n if (applied === undefined) {\n const exporters = [...(config.exporters ?? [])];\n let store = findStore(exporters);\n\n // Track a cache store separately so we can await its hydration before\n // the dashboard reads it — the in-memory store needs no warm-up.\n let cacheStore: CacheTraceStoreHandle | undefined;\n\n // The dashboard needs a queryable store. If none was supplied via\n // exporters but a dashboard is requested, create one and register it\n // as an exporter so the collector fills it. A configured `cache` picks\n // the durable cache-backed store; otherwise fall back to in-memory so\n // the dashboard works with no cache configured.\n if (store === undefined && config.dashboard) {\n if (config.cache !== undefined) {\n const onError =\n config.onError ?? ((error: unknown) => log.error(\"ai-panoptic\", \"cacheStore\", error));\n\n cacheStore = createCacheTraceStore(config.cache, { onError });\n store = cacheStore;\n } else {\n store = createInMemoryTraceStore();\n }\n\n exporters.push(store as unknown as ExporterContract);\n }\n\n const panopticInstance = panoptic({\n exporters,\n captureContent: config.captureContent,\n fullHistory: config.fullHistory,\n });\n registerObserver(toObserver(panopticInstance));\n\n applied = { panopticInstance };\n\n if (config.dashboard && store !== undefined) {\n const resolvedStore = store;\n\n // Hydrate the cache mirror (if any) before serving, so a restart\n // surfaces previously-persisted traces immediately. A bare in-memory\n // store resolves the readyGate instantly.\n const readyGate = cacheStore !== undefined ? cacheStore.ready() : Promise.resolve();\n\n void readyGate\n .catch(() => {\n // Hydration is best-effort — never block the dashboard on it.\n })\n .then(() => startDashboard(resolvedStore, config.dashboard ?? {}))\n .then((handle) => {\n if (applied !== undefined) {\n applied.dashboardHandle = handle;\n }\n });\n }\n }\n}\n\n/**\n * Reset the applied state — internal, test-only. Closes any running\n * dashboard and forgets the registered collector so a fresh\n * `applyPanopticConfig` starts clean. NOT part of the public surface and\n * does NOT unregister from the core observer registry (use core's\n * `clearObservers` for that in tests).\n */\nexport async function resetAppliedPanopticConfig(): Promise<void> {\n const handle = applied?.dashboardHandle;\n applied = undefined;\n\n if (handle !== undefined) {\n await handle.close();\n }\n}\n\n/**\n * The currently-running dashboard handle, or `undefined` when no\n * dashboard is active. Internal, test-only — lets a spec await the\n * asynchronously-started dashboard. NOT part of the public surface.\n */\nexport function getActiveDashboardHandle(): DashboardHandle | undefined {\n return applied?.dashboardHandle;\n}\n\n/**\n * Wrap a {@link Panoptic} subscriber as a core {@link Observer}. The\n * subscriber already exposes `collect(report)` with a matching signature,\n * but the thin wrapper makes the structural adaptation explicit and keeps\n * the registered object a minimal `Observer` rather than the whole\n * subscriber surface.\n */\nfunction toObserver(instance: Panoptic): Observer {\n return {\n collect(report: ExecutionReport): Promise<void> {\n return instance.collect(report);\n },\n };\n}\n\n/**\n * Find the first exporter that satisfies the {@link TraceStoreContract}\n * read surface (`query` / `get` / `aggregate`) — the in-memory store\n * doubles as an exporter, so a store passed via `exporters` is reused for\n * the dashboard rather than creating a second one.\n */\nfunction findStore(exporters: ExporterContract[]): TraceStoreContract | undefined {\n for (const exporter of exporters) {\n const candidate = exporter as unknown as Partial<TraceStoreContract>;\n\n if (\n typeof candidate.query === \"function\" &&\n typeof candidate.get === \"function\" &&\n typeof candidate.aggregate === \"function\"\n ) {\n return candidate as TraceStoreContract;\n }\n }\n\n return undefined;\n}\n\n/** Start the dashboard, normalizing the `true | DashboardOptions` switch. */\nfunction startDashboard(\n store: TraceStoreContract,\n dashboardConfig: boolean | DashboardOptions,\n): Promise<DashboardHandle> {\n const options: DashboardOptions = typeof dashboardConfig === \"object\" ? dashboardConfig : {};\n\n return dashboard(store, options);\n}\n"],"mappings":";;;;;;;;AA2BA,IAAI;;;;;;;;;;;;;;;;;;;;;AAsBJ,SAAgB,oBAAoB,QAA+B;CACjE,IAAI,WAAW,QACb;CAIF,cAAc,QAAQ,OAAO,UAAU,CAAC;CAExC,IAAI,YAAY,QAAW;EACzB,MAAM,YAAY,CAAC,GAAI,OAAO,aAAa,CAAC,CAAE;EAC9C,IAAI,QAAQ,UAAU,SAAS;EAI/B,IAAI;EAOJ,IAAI,UAAU,UAAa,OAAO,WAAW;GAC3C,IAAI,OAAO,UAAU,QAAW;IAC9B,MAAM,UACJ,OAAO,aAAa,UAAmB,IAAI,MAAM,eAAe,cAAc,KAAK;IAErF,aAAa,sBAAsB,OAAO,OAAO,EAAE,QAAQ,CAAC;IAC5D,QAAQ;GACV,OACE,QAAQ,yBAAyB;GAGnC,UAAU,KAAK,KAAoC;EACrD;EAEA,MAAM,mBAAmB,SAAS;GAChC;GACA,gBAAgB,OAAO;GACvB,aAAa,OAAO;EACtB,CAAC;EACD,iBAAiB,WAAW,gBAAgB,CAAC;EAE7C,UAAU,EAAE,iBAAiB;EAE7B,IAAI,OAAO,aAAa,UAAU,QAAW;GAC3C,MAAM,gBAAgB;GAOtB,CAFkB,eAAe,SAAY,WAAW,MAAM,IAAI,QAAQ,QAAQ,EAEpE,CACX,YAAY,CAEb,CAAC,CAAC,CACD,WAAW,eAAe,eAAe,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CACjE,MAAM,WAAW;IAChB,IAAI,YAAY,QACd,QAAQ,kBAAkB;GAE9B,CAAC;EACL;CACF;AACF;;;;;;;;AAkCA,SAAS,WAAW,UAA8B;CAChD,OAAO,EACL,QAAQ,QAAwC;EAC9C,OAAO,SAAS,QAAQ,MAAM;CAChC,EACF;AACF;;;;;;;AAQA,SAAS,UAAU,WAA+D;CAChF,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,YAAY;EAElB,IACE,OAAO,UAAU,UAAU,cAC3B,OAAO,UAAU,QAAQ,cACzB,OAAO,UAAU,cAAc,YAE/B,OAAO;CAEX;AAGF;;AAGA,SAAS,eACP,OACA,iBAC0B;CAG1B,OAAO,UAAU,OAFiB,OAAO,oBAAoB,WAAW,kBAAkB,CAAC,CAE5D;AACjC"}
@@ -1,2 +1,3 @@
1
1
  import { PanopticConfig } from "./panoptic-config.type.mjs";
2
- import { applyPanopticConfig } from "./apply-panoptic-config.mjs";
2
+ import { applyPanopticConfig } from "./apply-panoptic-config.mjs";
3
+ export { type PanopticConfig, applyPanopticConfig };
@@ -1,3 +1,3 @@
1
1
  import { applyPanopticConfig } from "./apply-panoptic-config.mjs";
2
2
 
3
- export { };
3
+ export { applyPanopticConfig };
@@ -1,7 +1,6 @@
1
1
  import { ExporterContract } from "../contracts/exporter.contract.mjs";
2
2
  import { CacheDriverInput } from "../store/cache-trace-store.mjs";
3
3
  import { DashboardOptions } from "../dashboard/dashboard.type.mjs";
4
-
5
4
  //#region ../../packages/ai-panoptic/src/config/panoptic-config.type.d.ts
6
5
  /**
7
6
  * Declarative panoptic configuration, set once through the global
@@ -25,7 +24,7 @@ import { DashboardOptions } from "../dashboard/dashboard.type.mjs";
25
24
  * },
26
25
  * });
27
26
  */
28
- type PanopticConfig = {
27
+ export type PanopticConfig = {
29
28
  /**
30
29
  * Exporters the collector feeds (a store, OTel, Langfuse, …). A
31
30
  * {@link import("../store/in-memory-trace-store").createInMemoryTraceStore}
@@ -89,7 +88,6 @@ declare module "@warlock.js/ai" {
89
88
  /** Declarative panoptic observability config. See {@link PanopticConfig}. */
90
89
  panoptic?: PanopticConfig;
91
90
  }
92
- } //# sourceMappingURL=panoptic-config.type.d.ts.map
91
+ }
93
92
  //#endregion
94
- export { PanopticConfig };
95
93
  //# sourceMappingURL=panoptic-config.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"panoptic-config.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/config/panoptic-config.type.ts"],"mappings":";;;;;;;AA0BA;;;;;;;;;;;;;;;;;;;;KAAY,cAAA;EA0DV;;;;;;EAnDA,SAAA,GAAY,gBAAA;EA4De;;AAAA;;;;;;;;;;EA/C3B,KAAA,GAAQ,gBAAA;;;;;;;;EAQR,SAAA,aAAsB,gBAAA;;;;;;EAMtB,UAAA;;;;;;EAMA,cAAA;;;;;;EAMA,WAAA;;;;;;;;;;;EAWA,OAAA,IAAW,KAAA;AAAA;AAAA;EAAA,UAQD,QAAA;;IAER,QAAA,GAAW,cAAc;EAAA;AAAA"}
1
+ {"version":3,"file":"panoptic-config.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/config/panoptic-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;YA0BY;;;;;;;EAOV,YAAY;;;;;;;;;;;;;EAaZ,QAAQ;;;;;;;;EAQR,sBAAsB;;;;;;EAMtB;;;;;;EAMA;;;;;;EAMA;;;;;;;;;;;EAWA,WAAW;;;YAQD;;IAER,WAAW"}
@@ -1,7 +1,6 @@
1
1
  import { Trace } from "./trace.type.mjs";
2
2
  import { ExporterContract } from "./exporter.contract.mjs";
3
3
  import { BaseReport } from "@warlock.js/ai";
4
-
5
4
  //#region ../../packages/ai-panoptic/src/contracts/collector.contract.d.ts
6
5
  /**
7
6
  * Contract for the Panoptic collector — the source end of the
@@ -21,7 +20,7 @@ import { BaseReport } from "@warlock.js/ai";
21
20
  * // on shutdown:
22
21
  * await collector.shutdown();
23
22
  */
24
- interface CollectorContract {
23
+ export interface CollectorContract {
25
24
  /**
26
25
  * Register an exporter. Returns the collector for chaining. Duplicate
27
26
  * registration (same `ExporterContract.name`) is ignored.
@@ -59,5 +58,4 @@ interface CollectorContract {
59
58
  shutdown(): Promise<void>;
60
59
  }
61
60
  //#endregion
62
- export { CollectorContract };
63
61
  //# sourceMappingURL=collector.contract.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/contracts/collector.contract.ts"],"mappings":";;;;;;;AAsBA;;;;;;;;;;;;;;;;UAAiB,iBAAA;EAmBP;;;;EAdR,GAAA,CAAI,QAAA,EAAU,gBAAA;EAsBN;;;;;;;;AAYW;;;;EApBnB,OAAA,CAAQ,MAAA,EAAQ,UAAA,EAAY,SAAA,aAAsB,OAAA;;;;;;;EAQlD,OAAA,CAAQ,MAAA,EAAQ,UAAA,EAAY,SAAA,aAAsB,KAAA;;;;;EAMlD,KAAA,IAAS,OAAA;;;;;EAMT,QAAA,IAAY,OAAA;AAAA"}
1
+ {"version":3,"file":"collector.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/contracts/collector.contract.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;iBAsBiB;;;;;EAKf,IAAI,UAAU;;;;;;;;;;;;;EAcd,QAAQ,QAAQ,YAAY,sBAAsB;;;;;;;EAQlD,QAAQ,QAAQ,YAAY,sBAAsB;;;;;EAMlD,SAAS;;;;;EAMT,YAAY"}
@@ -1,5 +1,4 @@
1
1
  import { Trace, TraceSpan } from "./trace.type.mjs";
2
-
3
2
  //#region ../../packages/ai-panoptic/src/contracts/exporter.contract.d.ts
4
3
  /**
5
4
  * Contract every Panoptic exporter implements. An exporter is the sink
@@ -35,7 +34,7 @@ import { Trace, TraceSpan } from "./trace.type.mjs";
35
34
  * },
36
35
  * };
37
36
  */
38
- interface ExporterContract {
37
+ export interface ExporterContract {
39
38
  /**
40
39
  * Stable identifier for this exporter (e.g. `"otel"`, `"langfuse"`,
41
40
  * `"console"`). Used in logs and to de-duplicate exporters registered
@@ -72,5 +71,4 @@ interface ExporterContract {
72
71
  shutdown?(): void | Promise<void>;
73
72
  }
74
73
  //#endregion
75
- export { ExporterContract };
76
74
  //# sourceMappingURL=exporter.contract.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exporter.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/contracts/exporter.contract.ts"],"mappings":";;;;;AAoCA;;;;;;;;;;;;;;;;;;;;;;;;;AAsC6B;;;;;;;UAtCZ,gBAAA;;;;;;WAMN,IAAA;;;;;;EAOT,MAAA,CAAO,KAAA,EAAO,KAAA,UAAe,OAAA;;;;;;;;;;EAW7B,UAAA,EAAY,IAAA,EAAM,SAAA,UAAmB,OAAA;;;;;;EAOrC,KAAA,YAAiB,OAAA;;;;;;EAOjB,QAAA,YAAoB,OAAA;AAAA"}
1
+ {"version":3,"file":"exporter.contract.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/contracts/exporter.contract.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCiB;;;;;;WAMN;;;;;;EAOT,OAAO,OAAO,eAAe;;;;;;;;;;EAW7B,YAAY,MAAM,mBAAmB;;;;;;EAOrC,iBAAiB;;;;;;EAOjB,oBAAoB"}
@@ -1,3 +1,4 @@
1
1
  import { Trace, TraceSpan, TraceSpanError } from "./trace.type.mjs";
2
2
  import { ExporterContract } from "./exporter.contract.mjs";
3
- import { CollectorContract } from "./collector.contract.mjs";
3
+ import { CollectorContract } from "./collector.contract.mjs";
4
+ export type { CollectorContract, ExporterContract, Trace, TraceSpan, TraceSpanError };
@@ -1,5 +1,4 @@
1
1
  import { ReportStatus, ReportType, Usage } from "@warlock.js/ai";
2
-
3
2
  //#region ../../packages/ai-panoptic/src/contracts/trace.type.d.ts
4
3
  /**
5
4
  * A single node in a Panoptic trace tree, derived 1:1 from a core
@@ -31,7 +30,7 @@ import { ReportStatus, ReportType, Usage } from "@warlock.js/ai";
31
30
  * children: [],
32
31
  * };
33
32
  */
34
- type TraceSpan = {
33
+ export type TraceSpan = {
35
34
  /**
36
35
  * Stable id for this span. Mirrors `BaseReport.runId` — one span per
37
36
  * execution node.
@@ -54,19 +53,26 @@ type TraceSpan = {
54
53
  * Surfaces as a session/thread dimension in backends that model
55
54
  * conversations. Absent when the caller didn't supply one.
56
55
  */
57
- sessionId?: string; /** Executable identity — the tool/agent/workflow/supervisor name. */
56
+ sessionId?: string;
57
+ /** Executable identity — the tool/agent/workflow/supervisor name. */
58
58
  name: string;
59
59
  /**
60
60
  * Dev-curated version string mirrored from `BaseReport.version`.
61
61
  * Free-form; surfaced as a span attribute so dashboards can slice
62
62
  * runs of "agent X v2.1" from "v2.2". Absent when undeclared.
63
63
  */
64
- version?: string; /** Discriminator for the kind of executable that produced this span. */
65
- type: ReportType; /** Terminal status of this execution, mirrored from `BaseReport.status`. */
66
- status: ReportStatus; /** ISO-8601 wall-clock timestamp when execution began. */
67
- startedAt: string; /** ISO-8601 wall-clock timestamp when execution finished. */
68
- endedAt: string; /** Monotonic duration in milliseconds. */
69
- duration: number; /** Rolled-up usage for this node (own cost + sum of children). */
64
+ version?: string;
65
+ /** Discriminator for the kind of executable that produced this span. */
66
+ type: ReportType;
67
+ /** Terminal status of this execution, mirrored from `BaseReport.status`. */
68
+ status: ReportStatus;
69
+ /** ISO-8601 wall-clock timestamp when execution began. */
70
+ startedAt: string;
71
+ /** ISO-8601 wall-clock timestamp when execution finished. */
72
+ endedAt: string;
73
+ /** Monotonic duration in milliseconds. */
74
+ duration: number;
75
+ /** Rolled-up usage for this node (own cost + sum of children). */
70
76
  usage: Usage;
71
77
  /**
72
78
  * Normalized error description when `status` is `"failed"` /
@@ -110,9 +116,12 @@ type TraceSpan = {
110
116
  * Kept structural (not an `Error` instance) so it survives JSON
111
117
  * serialization to a backend collector unchanged.
112
118
  */
113
- type TraceSpanError = {
114
- /** Stable error identifier (typed framework error name when available). */type: string; /** Human-readable message — secret-scrubbed before storage (S4). */
115
- message: string; /** Optional captured stack trace, secret-scrubbed when present (S4). */
119
+ export type TraceSpanError = {
120
+ /** Stable error identifier (typed framework error name when available). */
121
+ type: string;
122
+ /** Human-readable message — secret-scrubbed before storage (S4). */
123
+ message: string;
124
+ /** Optional captured stack trace, secret-scrubbed when present (S4). */
116
125
  stack?: string;
117
126
  /**
118
127
  * Optional redacted view of the error's `cause` (S4) — a raw provider
@@ -128,13 +137,20 @@ type TraceSpanError = {
128
137
  * `Trace` corresponds to one outermost `BaseReport` (a single
129
138
  * `.execute()` / `.invoke()` call).
130
139
  */
131
- type Trace = {
132
- /** Trace id — equals the root span's `traceId` / `rootRunId`. */traceId: string; /** Session grouping id, when the originating run carried one. */
133
- sessionId?: string; /** Root span of this trace. */
134
- root: TraceSpan; /** Wall-clock start of the trace (root span `startedAt`). */
135
- startedAt: string; /** Wall-clock end of the trace (root span `endedAt`). */
136
- endedAt: string; /** Total trace duration in milliseconds (root span `duration`). */
137
- duration: number; /** Trace-wide usage rollup (root span `usage`). */
140
+ export type Trace = {
141
+ /** Trace id — equals the root span's `traceId` / `rootRunId`. */
142
+ traceId: string;
143
+ /** Session grouping id, when the originating run carried one. */
144
+ sessionId?: string;
145
+ /** Root span of this trace. */
146
+ root: TraceSpan;
147
+ /** Wall-clock start of the trace (root span `startedAt`). */
148
+ startedAt: string;
149
+ /** Wall-clock end of the trace (root span `endedAt`). */
150
+ endedAt: string;
151
+ /** Total trace duration in milliseconds (root span `duration`). */
152
+ duration: number;
153
+ /** Trace-wide usage rollup (root span `usage`). */
138
154
  usage: Usage;
139
155
  /**
140
156
  * Wire-format version of the source `BaseReport` shape, mirrored from
@@ -144,5 +160,4 @@ type Trace = {
144
160
  reportSchemaVersion?: number;
145
161
  };
146
162
  //#endregion
147
- export { Trace, TraceSpan, TraceSpanError };
148
163
  //# sourceMappingURL=trace.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trace.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/contracts/trace.type.ts"],"mappings":";;;;;AAgCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAAY,SAAA;EA2DG;;;;EAtDb,MAAA;EA0EmB;AAAA;AAQrB;;EA7EE,YAAA;EA6EwB;;;;;;EAtExB,OAAA;EA4FU;;;;;EAtFV,SAAA,WA4FA;EA1FA,IAAA;EA4FA;;;;;EAtFA,OAAA,WAkGmB;EAhGnB,IAAA,EAAM,UAAA;EAEN,MAAA,EAAQ,YAAA;EAER,SAAA;EAEA,OAAA;EAEA,QAAA;EAEA,KAAA,EAAO,KAAA;;;;;;EAMP,KAAA,GAAQ,cAAA;;;;;;;;;;EAUR,UAAA,GAAa,MAAA;;;;;;;;EAQb,KAAA;;;;;;EAMA,MAAA;;;;;;EAMA,QAAA,EAAU,SAAA;AAAA;;;;;;KAQA,cAAA;6EAEV,IAAA;EAEA,OAAA;EAEA,KAAA;;;;;;;EAOA,KAAA;AAAA;;;;;;;KASU,KAAA;mEAEV,OAAA;EAEA,SAAA;EAEA,IAAA,EAAM,SAAA;EAEN,SAAA;EAEA,OAAA;EAEA,QAAA;EAEA,KAAA,EAAO,KAAK;;;;;;EAMZ,mBAAA;AAAA"}
1
+ {"version":3,"file":"trace.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/contracts/trace.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgCY;;;;;EAKV;;;;;EAKA;;;;;;;EAOA;;;;;;EAMA;;EAEA;;;;;;EAMA;;EAEA,MAAM;;EAEN,QAAQ;;EAER;;EAEA;;EAEA;;EAEA,OAAO;;;;;;EAMP,QAAQ;;;;;;;;;;EAUR,aAAa;;;;;;;;EAQb;;;;;;EAMA;;;;;;EAMA,UAAU;;;;;;;YAQA;;EAEV;;EAEA;;EAEA;;;;;;;EAOA;;;;;;;;YASU;;EAEV;;EAEA;;EAEA,MAAM;;EAEN;;EAEA;;EAEA;;EAEA,OAAO;;;;;;EAMP"}
@@ -1,6 +1,5 @@
1
1
  import { TraceStoreContract } from "../store/trace-store.contract.mjs";
2
2
  import { DashboardHandle, DashboardOptions } from "./dashboard.type.mjs";
3
-
4
3
  //#region ../../packages/ai-panoptic/src/dashboard/dashboard.d.ts
5
4
  /**
6
5
  * Start the local Panoptic dashboard over a {@link TraceStoreContract} —
@@ -26,7 +25,6 @@ import { DashboardHandle, DashboardOptions } from "./dashboard.type.mjs";
26
25
  * // ...later:
27
26
  * await handle.close();
28
27
  */
29
- declare function dashboard(store: TraceStoreContract, options?: DashboardOptions): Promise<DashboardHandle>;
28
+ export declare function dashboard(store: TraceStoreContract, options?: DashboardOptions): Promise<DashboardHandle>;
30
29
  //#endregion
31
- export { dashboard };
32
30
  //# sourceMappingURL=dashboard.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/dashboard/dashboard.ts"],"mappings":";;;;;;AAiCA;;;;;;;;;;;;;;;;AAG0B;;;;;;iBAHV,SAAA,CACd,KAAA,EAAO,kBAAA,EACP,OAAA,GAAS,gBAAA,GACR,OAAA,CAAQ,eAAA"}
1
+ {"version":3,"file":"dashboard.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/dashboard/dashboard.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;wBAiCgB,UACd,OAAO,oBACP,UAAS,mBACR,QAAQ"}