@warlock.js/ai-panoptic 5.31.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 (135) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/cjs/index.cjs +16 -65
  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/content-capture.type.d.mts +4 -5
  7. package/esm/collector/content-capture.type.d.mts.map +1 -1
  8. package/esm/collector/extract-span-attributes.d.mts +1 -3
  9. package/esm/collector/extract-span-attributes.d.mts.map +1 -1
  10. package/esm/collector/extract-span-attributes.mjs +1 -4
  11. package/esm/collector/extract-span-attributes.mjs.map +1 -1
  12. package/esm/collector/index.d.mts +2 -1
  13. package/esm/collector/index.mjs +1 -1
  14. package/esm/collector/normalize-error.d.mts +1 -3
  15. package/esm/collector/normalize-error.d.mts.map +1 -1
  16. package/esm/collector/report-to-span.d.mts +1 -3
  17. package/esm/collector/report-to-span.d.mts.map +1 -1
  18. package/esm/collector/report-to-trace.d.mts +1 -3
  19. package/esm/collector/report-to-trace.d.mts.map +1 -1
  20. package/esm/config/apply-panoptic-config.d.mts +2 -3
  21. package/esm/config/apply-panoptic-config.d.mts.map +1 -1
  22. package/esm/config/index.d.mts +2 -1
  23. package/esm/config/index.mjs +1 -1
  24. package/esm/config/panoptic-config.type.d.mts +2 -4
  25. package/esm/config/panoptic-config.type.d.mts.map +1 -1
  26. package/esm/contracts/collector.contract.d.mts +1 -3
  27. package/esm/contracts/collector.contract.d.mts.map +1 -1
  28. package/esm/contracts/exporter.contract.d.mts +1 -3
  29. package/esm/contracts/exporter.contract.d.mts.map +1 -1
  30. package/esm/contracts/index.d.mts +2 -1
  31. package/esm/contracts/trace.type.d.mts +35 -20
  32. package/esm/contracts/trace.type.d.mts.map +1 -1
  33. package/esm/dashboard/dashboard.d.mts +1 -3
  34. package/esm/dashboard/dashboard.d.mts.map +1 -1
  35. package/esm/dashboard/dashboard.mjs +3 -2
  36. package/esm/dashboard/dashboard.mjs.map +1 -1
  37. package/esm/dashboard/dashboard.type.d.mts +9 -7
  38. package/esm/dashboard/dashboard.type.d.mts.map +1 -1
  39. package/esm/dashboard/index.d.mts +4 -1
  40. package/esm/dashboard/index.mjs +1 -1
  41. package/esm/dashboard/parse-query.d.mts +1 -1
  42. package/esm/dashboard/serve.d.mts +2 -1
  43. package/esm/dashboard/serve.mjs +1 -1
  44. package/esm/dashboard/serve.mjs.map +1 -1
  45. package/esm/dashboard/trace-filter.d.mts +44 -32
  46. package/esm/dashboard/trace-filter.d.mts.map +1 -1
  47. package/esm/evaluate/evaluate-system-prompt.d.mts +1 -3
  48. package/esm/evaluate/evaluate-system-prompt.d.mts.map +1 -1
  49. package/esm/evaluate/evaluate-system-prompt.mjs +3 -1
  50. package/esm/evaluate/evaluate-system-prompt.mjs.map +1 -1
  51. package/esm/evaluate/evaluate.type.d.mts +2 -4
  52. package/esm/evaluate/evaluate.type.d.mts.map +1 -1
  53. package/esm/evaluate/extract-last-system-prompt.d.mts +1 -3
  54. package/esm/evaluate/extract-last-system-prompt.d.mts.map +1 -1
  55. package/esm/evaluate/find-span-by-id.d.mts +1 -3
  56. package/esm/evaluate/find-span-by-id.d.mts.map +1 -1
  57. package/esm/evaluate/index.d.mts +2 -1
  58. package/esm/evaluate/index.mjs +1 -1
  59. package/esm/exporters/console/console-exporter.d.mts +2 -3
  60. package/esm/exporters/console/console-exporter.d.mts.map +1 -1
  61. package/esm/exporters/console/console-exporter.type.d.mts +2 -3
  62. package/esm/exporters/console/console-exporter.type.d.mts.map +1 -1
  63. package/esm/exporters/console/format-span-io.d.mts +2 -2
  64. package/esm/exporters/console/format-span-io.d.mts.map +1 -1
  65. package/esm/exporters/console/format-span-line.d.mts +2 -2
  66. package/esm/exporters/console/format-span-line.d.mts.map +1 -1
  67. package/esm/exporters/console/index.d.mts +2 -1
  68. package/esm/exporters/console/index.mjs +1 -1
  69. package/esm/exporters/file/file-exporter.d.mts +2 -3
  70. package/esm/exporters/file/file-exporter.d.mts.map +1 -1
  71. package/esm/exporters/file/file-exporter.type.d.mts +8 -5
  72. package/esm/exporters/file/file-exporter.type.d.mts.map +1 -1
  73. package/esm/exporters/file/index.d.mts +2 -1
  74. package/esm/exporters/index.d.mts +7 -1
  75. package/esm/exporters/index.mjs +1 -1
  76. package/esm/exporters/langfuse/index.d.mts +2 -1
  77. package/esm/exporters/langfuse/index.mjs +1 -1
  78. package/esm/exporters/langfuse/langfuse-exporter.d.mts +2 -3
  79. package/esm/exporters/langfuse/langfuse-exporter.d.mts.map +1 -1
  80. package/esm/exporters/langfuse/langfuse-exporter.mjs +1 -1
  81. package/esm/exporters/langfuse/langfuse-exporter.mjs.map +1 -1
  82. package/esm/exporters/langfuse/langfuse-exporter.type.d.mts +23 -17
  83. package/esm/exporters/langfuse/langfuse-exporter.type.d.mts.map +1 -1
  84. package/esm/exporters/otel/index.d.mts +2 -1
  85. package/esm/exporters/otel/index.mjs +1 -1
  86. package/esm/exporters/otel/otel-api.shim.type.d.mts +6 -7
  87. package/esm/exporters/otel/otel-api.shim.type.d.mts.map +1 -1
  88. package/esm/exporters/otel/otel-exporter.d.mts +2 -3
  89. package/esm/exporters/otel/otel-exporter.d.mts.map +1 -1
  90. package/esm/exporters/otel/otel-exporter.type.d.mts +1 -3
  91. package/esm/exporters/otel/otel-exporter.type.d.mts.map +1 -1
  92. package/esm/exporters/utils/gen-ai-attributes.d.mts +9 -7
  93. package/esm/exporters/utils/gen-ai-attributes.d.mts.map +1 -1
  94. package/esm/exporters/utils/index.d.mts +2 -1
  95. package/esm/exporters/utils/index.mjs +1 -1
  96. package/esm/exporters/utils/total-cost.d.mts +1 -3
  97. package/esm/exporters/utils/total-cost.d.mts.map +1 -1
  98. package/esm/exporters/utils/walk-spans.d.mts +2 -2
  99. package/esm/exporters/utils/walk-spans.d.mts.map +1 -1
  100. package/esm/index.d.mts +8 -0
  101. package/esm/panoptic/index.d.mts +2 -1
  102. package/esm/panoptic/index.mjs +1 -1
  103. package/esm/panoptic/panoptic-middleware.d.mts +1 -3
  104. package/esm/panoptic/panoptic-middleware.d.mts.map +1 -1
  105. package/esm/panoptic/panoptic-target.type.d.mts +4 -5
  106. package/esm/panoptic/panoptic-target.type.d.mts.map +1 -1
  107. package/esm/panoptic/panoptic.d.mts +1 -3
  108. package/esm/panoptic/panoptic.d.mts.map +1 -1
  109. package/esm/panoptic/panoptic.type.d.mts +8 -7
  110. package/esm/panoptic/panoptic.type.d.mts.map +1 -1
  111. package/esm/store/cache-trace-store.d.mts +4 -6
  112. package/esm/store/cache-trace-store.d.mts.map +1 -1
  113. package/esm/store/cache-trace-store.mjs +1 -4
  114. package/esm/store/cache-trace-store.mjs.map +1 -1
  115. package/esm/store/in-memory-trace-store.d.mts +2 -4
  116. package/esm/store/in-memory-trace-store.d.mts.map +1 -1
  117. package/esm/store/in-memory-trace-store.mjs +1 -4
  118. package/esm/store/in-memory-trace-store.mjs.map +1 -1
  119. package/esm/store/index.d.mts +2 -1
  120. package/esm/store/index.mjs +1 -1
  121. package/esm/store/match-trace.d.mts +1 -3
  122. package/esm/store/match-trace.d.mts.map +1 -1
  123. package/esm/store/sum-usage.d.mts +4 -30
  124. package/esm/store/sum-usage.d.mts.map +1 -1
  125. package/esm/store/sum-usage.mjs +6 -49
  126. package/esm/store/sum-usage.mjs.map +1 -1
  127. package/esm/store/trace-aggregate.type.d.mts +12 -9
  128. package/esm/store/trace-aggregate.type.d.mts.map +1 -1
  129. package/esm/store/trace-query.type.d.mts +5 -5
  130. package/esm/store/trace-query.type.d.mts.map +1 -1
  131. package/esm/store/trace-store.contract.d.mts +1 -3
  132. package/esm/store/trace-store.contract.d.mts.map +1 -1
  133. package/llms-full.txt +14 -0
  134. package/package.json +4 -4
  135. package/skills/query-traces/SKILL.md +14 -0
@@ -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":";;;;;AAwDA;;;;;;;;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;
@@ -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 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;GACH,kBAAkB,YAAY,UAAU;GACxC;EAGF,SACE;CAEJ;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"}
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,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,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"}
@@ -36,13 +36,14 @@ function dashboard(store, options = {}) {
36
36
  const basePath = normalizeBasePath(options.basePath);
37
37
  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.`));
38
38
  const allowedHosts = (options.allowedHosts ?? defaultAllowedHosts(host)).map((h) => h.toLowerCase());
39
- const server = createServer(createRequestHandler(store, {
39
+ const handler = createRequestHandler(store, {
40
40
  basePath,
41
41
  title,
42
42
  authToken: options.authToken,
43
43
  allowedHosts,
44
44
  evaluate: options.evaluate
45
- }));
45
+ });
46
+ const server = createServer(handler);
46
47
  return new Promise((resolve, reject) => {
47
48
  const onError = (error) => {
48
49
  server.off("error", onError);
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/dashboard/dashboard.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport type { TraceStoreContract } from \"../store/trace-store.contract\";\nimport type { DashboardHandle, DashboardOptions } from \"./dashboard.type\";\nimport { createRequestHandler } from \"./serve\";\n\nconst DEFAULT_PORT = 4319;\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst DEFAULT_TITLE = \"Panoptic\";\n\n/**\n * Start the local Panoptic dashboard over a {@link TraceStoreContract} —\n * a zero-dependency `node:http` server that serves a read-only JSON API\n * and one self-contained HTML page polling it. The store is the live\n * object the collector fills, so each poll reflects the latest completed\n * traces with no extra wiring.\n *\n * This is a low-level building block. The documented path is\n * `ai.config({ panoptic: { dashboard } })`, which constructs (or reuses)\n * the store and calls this for you. Use it directly only when you manage\n * the store yourself.\n *\n * Binds loopback-only by default (`127.0.0.1`) so prompt content is never\n * exposed to the LAN. Pass `port: 0` for an ephemeral port — the resolved\n * port comes back on the handle. A port already in use rejects with a\n * clear, actionable `Error` rather than the raw `EADDRINUSE`.\n *\n * @example\n * const store = createInMemoryTraceStore();\n * const handle = await dashboard(store, { port: 4319, open: true });\n * console.log(handle.url); // http://127.0.0.1:4319/\n * // ...later:\n * await handle.close();\n */\nexport function dashboard(\n store: TraceStoreContract,\n options: DashboardOptions = {},\n): Promise<DashboardHandle> {\n const port = options.port ?? DEFAULT_PORT;\n const host = options.host ?? DEFAULT_HOST;\n const title = options.title ?? DEFAULT_TITLE;\n const basePath = normalizeBasePath(options.basePath);\n\n // Secure-by-default off loopback (S4): a non-loopback bind without an\n // auth token would expose raw prompt content to the network, so refuse\n // to start rather than silently exposing it.\n if (!isLoopbackHost(host) && !options.authToken) {\n return Promise.reject(\n new Error(\n `Panoptic dashboard: binding to a non-loopback host (\"${host}\") requires an \\`authToken\\` ` +\n \"(the dashboard exposes raw prompt content). Pass `authToken`, or bind to 127.0.0.1.\",\n ),\n );\n }\n\n const allowedHosts = (options.allowedHosts ?? defaultAllowedHosts(host)).map((h) =>\n h.toLowerCase(),\n );\n\n const handler = createRequestHandler(store, {\n basePath,\n title,\n authToken: options.authToken,\n allowedHosts,\n evaluate: options.evaluate,\n });\n const server = createServer(handler);\n\n return new Promise<DashboardHandle>((resolve, reject) => {\n const onError = (error: NodeJS.ErrnoException): void => {\n server.off(\"error\", onError);\n\n if (error.code === \"EADDRINUSE\") {\n reject(\n new Error(\n `Panoptic dashboard: port ${port} in use; pass { port: 0 } for an ephemeral port`,\n ),\n );\n\n return;\n }\n\n reject(error);\n };\n\n server.on(\"error\", onError);\n\n server.listen(port, host, () => {\n server.off(\"error\", onError);\n\n const address = server.address();\n const resolvedPort = typeof address === \"object\" && address !== null ? address.port : port;\n const url = `http://${host}:${resolvedPort}${basePath}`;\n\n if (options.open) {\n openBrowser(url);\n }\n\n resolve({\n url,\n port: resolvedPort,\n close(): Promise<void> {\n return new Promise<void>((closeResolve, closeReject) => {\n server.close((closeError) => {\n if (closeError) {\n closeReject(closeError);\n\n return;\n }\n\n closeResolve();\n });\n });\n },\n });\n });\n });\n}\n\n/** Loopback hosts the dashboard may bind without an auth token. */\nfunction isLoopbackHost(host: string): boolean {\n const h = host.toLowerCase();\n return h === \"127.0.0.1\" || h === \"::1\" || h === \"[::1]\" || h === \"localhost\";\n}\n\n/**\n * Default `Host` allowlist for a given bind host. A loopback bind accepts\n * the loopback names a browser would send; a non-loopback bind defaults to\n * just the bound host (callers can widen via `allowedHosts`).\n */\nfunction defaultAllowedHosts(host: string): string[] {\n if (isLoopbackHost(host)) {\n return [\"localhost\", \"127.0.0.1\", \"[::1]\", \"::1\"];\n }\n return [host];\n}\n\n/**\n * Normalize a caller `basePath` to a leading-and-trailing-slash form the\n * router can prefix routes with. `undefined` / `\"\"` → `\"/\"`.\n */\nfunction normalizeBasePath(basePath?: string): string {\n if (basePath === undefined || basePath.length === 0 || basePath === \"/\") {\n return \"/\";\n }\n\n const withLeading = basePath.startsWith(\"/\") ? basePath : `/${basePath}`;\n\n return withLeading.endsWith(\"/\") ? withLeading : `${withLeading}/`;\n}\n\n/**\n * Best-effort open of the default browser at `url`. Fire-and-forget and\n * fully swallowed — failing to open a browser must never reject the\n * dashboard start. Uses the platform's native opener via a lazy\n * `node:child_process` import so the dependency is paid only when\n * `open: true`.\n */\nfunction openBrowser(url: string): void {\n void import(\"node:child_process\")\n .then(({ spawn }) => {\n const command =\n process.platform === \"win32\" ? \"cmd\" : process.platform === \"darwin\" ? \"open\" : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n\n const child = spawn(command, args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => {\n // Swallow — opening a browser is best-effort.\n });\n child.unref();\n })\n .catch(() => {\n // Swallow — opening a browser is best-effort.\n });\n}\n"],"mappings":";;;;AAKA,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;AA0BtB,SAAgB,UACd,OACA,UAA4B,CAAC,GACH;CAC1B,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,WAAW,kBAAkB,QAAQ,QAAQ;CAKnD,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,QAAQ,WACpC,OAAO,QAAQ,uBACb,IAAI,MACF,wDAAwD,KAAK,mHAE/D,CACF;CAGF,MAAM,gBAAgB,QAAQ,gBAAgB,oBAAoB,IAAI,EAAC,CAAE,KAAK,MAC5E,EAAE,YAAY,CAChB;CASA,MAAM,SAAS,aAPC,qBAAqB,OAAO;EAC1C;EACA;EACA,WAAW,QAAQ;EACnB;EACA,UAAU,QAAQ;CACpB,CACkC,CAAC;CAEnC,OAAO,IAAI,SAA0B,SAAS,WAAW;EACvD,MAAM,WAAW,UAAuC;GACtD,OAAO,IAAI,SAAS,OAAO;GAE3B,IAAI,MAAM,SAAS,cAAc;IAC/B,uBACE,IAAI,MACF,4BAA4B,KAAK,gDACnC,CACF;IAEA;GACF;GAEA,OAAO,KAAK;EACd;EAEA,OAAO,GAAG,SAAS,OAAO;EAE1B,OAAO,OAAO,MAAM,YAAY;GAC9B,OAAO,IAAI,SAAS,OAAO;GAE3B,MAAM,UAAU,OAAO,QAAQ;GAC/B,MAAM,eAAe,OAAO,YAAY,YAAY,YAAY,OAAO,QAAQ,OAAO;GACtF,MAAM,MAAM,UAAU,KAAK,GAAG,eAAe;GAE7C,IAAI,QAAQ,MACV,YAAY,GAAG;GAGjB,QAAQ;IACN;IACA,MAAM;IACN,QAAuB;KACrB,OAAO,IAAI,SAAe,cAAc,gBAAgB;MACtD,OAAO,OAAO,eAAe;OAC3B,IAAI,YAAY;QACd,YAAY,UAAU;QAEtB;OACF;OAEA,aAAa;MACf,CAAC;KACH,CAAC;IACH;GACF,CAAC;EACH,CAAC;CACH,CAAC;AACH;;AAGA,SAAS,eAAe,MAAuB;CAC7C,MAAM,IAAI,KAAK,YAAY;CAC3B,OAAO,MAAM,eAAe,MAAM,SAAS,MAAM,WAAW,MAAM;AACpE;;;;;;AAOA,SAAS,oBAAoB,MAAwB;CACnD,IAAI,eAAe,IAAI,GACrB,OAAO;EAAC;EAAa;EAAa;EAAS;CAAK;CAElD,OAAO,CAAC,IAAI;AACd;;;;;AAMA,SAAS,kBAAkB,UAA2B;CACpD,IAAI,aAAa,UAAa,SAAS,WAAW,KAAK,aAAa,KAClE,OAAO;CAGT,MAAM,cAAc,SAAS,WAAW,GAAG,IAAI,WAAW,IAAI;CAE9D,OAAO,YAAY,SAAS,GAAG,IAAI,cAAc,GAAG,YAAY;AAClE;;;;;;;;AASA,SAAS,YAAY,KAAmB;CACtC,AAAK,OAAO,qBAAqB,CAC9B,MAAM,EAAE,YAAY;EAKnB,MAAM,QAAQ,MAHZ,QAAQ,aAAa,UAAU,QAAQ,QAAQ,aAAa,WAAW,SAAS,YACrE,QAAQ,aAAa,UAAU;GAAC;GAAM;GAAS;GAAI;EAAG,IAAI,CAAC,GAAG,GAExC;GAAE,OAAO;GAAU,UAAU;EAAK,CAAC;EACtE,MAAM,GAAG,eAAe,CAExB,CAAC;EACD,MAAM,MAAM;CACd,CAAC,CAAC,CACD,YAAY,CAEb,CAAC;AACL"}
1
+ {"version":3,"file":"dashboard.mjs","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/dashboard/dashboard.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport type { TraceStoreContract } from \"../store/trace-store.contract\";\nimport type { DashboardHandle, DashboardOptions } from \"./dashboard.type\";\nimport { createRequestHandler } from \"./serve\";\n\nconst DEFAULT_PORT = 4319;\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst DEFAULT_TITLE = \"Panoptic\";\n\n/**\n * Start the local Panoptic dashboard over a {@link TraceStoreContract} —\n * a zero-dependency `node:http` server that serves a read-only JSON API\n * and one self-contained HTML page polling it. The store is the live\n * object the collector fills, so each poll reflects the latest completed\n * traces with no extra wiring.\n *\n * This is a low-level building block. The documented path is\n * `ai.config({ panoptic: { dashboard } })`, which constructs (or reuses)\n * the store and calls this for you. Use it directly only when you manage\n * the store yourself.\n *\n * Binds loopback-only by default (`127.0.0.1`) so prompt content is never\n * exposed to the LAN. Pass `port: 0` for an ephemeral port — the resolved\n * port comes back on the handle. A port already in use rejects with a\n * clear, actionable `Error` rather than the raw `EADDRINUSE`.\n *\n * @example\n * const store = createInMemoryTraceStore();\n * const handle = await dashboard(store, { port: 4319, open: true });\n * console.log(handle.url); // http://127.0.0.1:4319/\n * // ...later:\n * await handle.close();\n */\nexport function dashboard(\n store: TraceStoreContract,\n options: DashboardOptions = {},\n): Promise<DashboardHandle> {\n const port = options.port ?? DEFAULT_PORT;\n const host = options.host ?? DEFAULT_HOST;\n const title = options.title ?? DEFAULT_TITLE;\n const basePath = normalizeBasePath(options.basePath);\n\n // Secure-by-default off loopback (S4): a non-loopback bind without an\n // auth token would expose raw prompt content to the network, so refuse\n // to start rather than silently exposing it.\n if (!isLoopbackHost(host) && !options.authToken) {\n return Promise.reject(\n new Error(\n `Panoptic dashboard: binding to a non-loopback host (\"${host}\") requires an \\`authToken\\` ` +\n \"(the dashboard exposes raw prompt content). Pass `authToken`, or bind to 127.0.0.1.\",\n ),\n );\n }\n\n const allowedHosts = (options.allowedHosts ?? defaultAllowedHosts(host)).map((h) =>\n h.toLowerCase(),\n );\n\n const handler = createRequestHandler(store, {\n basePath,\n title,\n authToken: options.authToken,\n allowedHosts,\n evaluate: options.evaluate,\n });\n const server = createServer(handler);\n\n return new Promise<DashboardHandle>((resolve, reject) => {\n const onError = (error: NodeJS.ErrnoException): void => {\n server.off(\"error\", onError);\n\n if (error.code === \"EADDRINUSE\") {\n reject(\n new Error(\n `Panoptic dashboard: port ${port} in use; pass { port: 0 } for an ephemeral port`,\n ),\n );\n\n return;\n }\n\n reject(error);\n };\n\n server.on(\"error\", onError);\n\n server.listen(port, host, () => {\n server.off(\"error\", onError);\n\n const address = server.address();\n const resolvedPort = typeof address === \"object\" && address !== null ? address.port : port;\n const url = `http://${host}:${resolvedPort}${basePath}`;\n\n if (options.open) {\n openBrowser(url);\n }\n\n resolve({\n url,\n port: resolvedPort,\n close(): Promise<void> {\n return new Promise<void>((closeResolve, closeReject) => {\n server.close((closeError) => {\n if (closeError) {\n closeReject(closeError);\n\n return;\n }\n\n closeResolve();\n });\n });\n },\n });\n });\n });\n}\n\n/** Loopback hosts the dashboard may bind without an auth token. */\nfunction isLoopbackHost(host: string): boolean {\n const h = host.toLowerCase();\n return h === \"127.0.0.1\" || h === \"::1\" || h === \"[::1]\" || h === \"localhost\";\n}\n\n/**\n * Default `Host` allowlist for a given bind host. A loopback bind accepts\n * the loopback names a browser would send; a non-loopback bind defaults to\n * just the bound host (callers can widen via `allowedHosts`).\n */\nfunction defaultAllowedHosts(host: string): string[] {\n if (isLoopbackHost(host)) {\n return [\"localhost\", \"127.0.0.1\", \"[::1]\", \"::1\"];\n }\n return [host];\n}\n\n/**\n * Normalize a caller `basePath` to a leading-and-trailing-slash form the\n * router can prefix routes with. `undefined` / `\"\"` → `\"/\"`.\n */\nfunction normalizeBasePath(basePath?: string): string {\n if (basePath === undefined || basePath.length === 0 || basePath === \"/\") {\n return \"/\";\n }\n\n const withLeading = basePath.startsWith(\"/\") ? basePath : `/${basePath}`;\n\n return withLeading.endsWith(\"/\") ? withLeading : `${withLeading}/`;\n}\n\n/**\n * Best-effort open of the default browser at `url`. Fire-and-forget and\n * fully swallowed — failing to open a browser must never reject the\n * dashboard start. Uses the platform's native opener via a lazy\n * `node:child_process` import so the dependency is paid only when\n * `open: true`.\n */\nfunction openBrowser(url: string): void {\n void import(\"node:child_process\")\n .then(({ spawn }) => {\n const command =\n process.platform === \"win32\" ? \"cmd\" : process.platform === \"darwin\" ? \"open\" : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n\n const child = spawn(command, args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => {\n // Swallow — opening a browser is best-effort.\n });\n child.unref();\n })\n .catch(() => {\n // Swallow — opening a browser is best-effort.\n });\n}\n"],"mappings":";;;;AAKA,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;AA0BtB,SAAgB,UACd,OACA,UAA4B,CAAC,GACH;CAC1B,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,WAAW,kBAAkB,QAAQ,QAAQ;CAKnD,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,QAAQ,WACpC,OAAO,QAAQ,uBACb,IAAI,MACF,wDAAwD,KAAK,mHAE/D,CACF;CAGF,MAAM,gBAAgB,QAAQ,gBAAgB,oBAAoB,IAAI,EAAC,CAAE,KAAK,MAC5E,EAAE,YAAY,CAChB;CAEA,MAAM,UAAU,qBAAqB,OAAO;EAC1C;EACA;EACA,WAAW,QAAQ;EACnB;EACA,UAAU,QAAQ;CACpB,CAAC;CACD,MAAM,SAAS,aAAa,OAAO;CAEnC,OAAO,IAAI,SAA0B,SAAS,WAAW;EACvD,MAAM,WAAW,UAAuC;GACtD,OAAO,IAAI,SAAS,OAAO;GAE3B,IAAI,MAAM,SAAS,cAAc;IAC/B,uBACE,IAAI,MACF,4BAA4B,KAAK,gDACnC,CACF;IAEA;GACF;GAEA,OAAO,KAAK;EACd;EAEA,OAAO,GAAG,SAAS,OAAO;EAE1B,OAAO,OAAO,MAAM,YAAY;GAC9B,OAAO,IAAI,SAAS,OAAO;GAE3B,MAAM,UAAU,OAAO,QAAQ;GAC/B,MAAM,eAAe,OAAO,YAAY,YAAY,YAAY,OAAO,QAAQ,OAAO;GACtF,MAAM,MAAM,UAAU,KAAK,GAAG,eAAe;GAE7C,IAAI,QAAQ,MACV,YAAY,GAAG;GAGjB,QAAQ;IACN;IACA,MAAM;IACN,QAAuB;KACrB,OAAO,IAAI,SAAe,cAAc,gBAAgB;MACtD,OAAO,OAAO,eAAe;OAC3B,IAAI,YAAY;QACd,YAAY,UAAU;QAEtB;OACF;OAEA,aAAa;MACf,CAAC;KACH,CAAC;IACH;GACF,CAAC;EACH,CAAC;CACH,CAAC;AACH;;AAGA,SAAS,eAAe,MAAuB;CAC7C,MAAM,IAAI,KAAK,YAAY;CAC3B,OAAO,MAAM,eAAe,MAAM,SAAS,MAAM,WAAW,MAAM;AACpE;;;;;;AAOA,SAAS,oBAAoB,MAAwB;CACnD,IAAI,eAAe,IAAI,GACrB,OAAO;EAAC;EAAa;EAAa;EAAS;CAAK;CAElD,OAAO,CAAC,IAAI;AACd;;;;;AAMA,SAAS,kBAAkB,UAA2B;CACpD,IAAI,aAAa,UAAa,SAAS,WAAW,KAAK,aAAa,KAClE,OAAO;CAGT,MAAM,cAAc,SAAS,WAAW,GAAG,IAAI,WAAW,IAAI;CAE9D,OAAO,YAAY,SAAS,GAAG,IAAI,cAAc,GAAG,YAAY;AAClE;;;;;;;;AASA,SAAS,YAAY,KAAmB;CACtC,AAAK,OAAO,qBAAqB,CAC9B,MAAM,EAAE,YAAY;EAKnB,MAAM,QAAQ,MAHZ,QAAQ,aAAa,UAAU,QAAQ,QAAQ,aAAa,WAAW,SAAS,YACrE,QAAQ,aAAa,UAAU;GAAC;GAAM;GAAS;GAAI;EAAG,IAAI,CAAC,GAAG,GAExC;GAAE,OAAO;GAAU,UAAU;EAAK,CAAC;EACtE,MAAM,GAAG,eAAe,CAExB,CAAC;EACD,MAAM,MAAM;CACd,CAAC,CAAC,CACD,YAAY,CAEb,CAAC;AACL"}
@@ -1,5 +1,4 @@
1
1
  import { EvaluateConfig } from "../evaluate/evaluate.type.mjs";
2
-
3
2
  //#region ../../packages/ai-panoptic/src/dashboard/dashboard.type.d.ts
4
3
  /**
5
4
  * Options for the local Panoptic {@link dashboard} server.
@@ -12,7 +11,7 @@ import { EvaluateConfig } from "../evaluate/evaluate.type.mjs";
12
11
  * {@link DashboardOptions.evaluate} enables. There is no auth or persistence
13
12
  * by default either.
14
13
  */
15
- type DashboardOptions = {
14
+ export type DashboardOptions = {
16
15
  /**
17
16
  * TCP port to listen on. Default `4319`. Pass `0` for an ephemeral
18
17
  * port — the OS-assigned port is then returned on
@@ -35,7 +34,8 @@ type DashboardOptions = {
35
34
  * Open the default browser at the resolved URL once the server is
36
35
  * listening. Default `false`.
37
36
  */
38
- open?: boolean; /** Title shown in the dashboard header. Default `"Panoptic"`. */
37
+ open?: boolean;
38
+ /** Title shown in the dashboard header. Default `"Panoptic"`. */
39
39
  title?: string;
40
40
  /**
41
41
  * Bearer token required on every request (S4). When set, a request must
@@ -66,11 +66,13 @@ type DashboardOptions = {
66
66
  * Carries the resolved URL + port (useful when `port: 0` requested an
67
67
  * ephemeral one) and a `close()` to release the port.
68
68
  */
69
- type DashboardHandle = {
70
- /** Resolved URL the UI is served at (`http://host:port{basePath}`). */readonly url: string; /** Resolved port — the real OS-assigned port when `port: 0` was passed. */
71
- readonly port: number; /** Stop the server and release the port. Resolves once fully closed. */
69
+ export type DashboardHandle = {
70
+ /** Resolved URL the UI is served at (`http://host:port{basePath}`). */
71
+ readonly url: string;
72
+ /** Resolved port — the real OS-assigned port when `port: 0` was passed. */
73
+ readonly port: number;
74
+ /** Stop the server and release the port. Resolves once fully closed. */
72
75
  close(): Promise<void>;
73
76
  };
74
77
  //#endregion
75
- export { DashboardHandle, DashboardOptions };
76
78
  //# sourceMappingURL=dashboard.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/dashboard/dashboard.type.ts"],"mappings":";;;;;AAaA;;;;;;;;;KAAY,gBAAA;EAuCV;;;;AASyB;EA1CzB,IAAA;EAkDyB;;;;;EA5CzB,IAAA;EAkDS;;AAAO;;;EA5ChB,QAAA;;;;;EAKA,IAAA;EAEA,KAAA;;;;;;;EAOA,SAAA;;;;;;;EAOA,YAAA;;;;;;;;;EASA,QAAA,GAAW,cAAc;AAAA;;;;;;KAQf,eAAA;kFAED,GAAA;WAEA,IAAA;EAET,KAAA,IAAS,OAAO;AAAA"}
1
+ {"version":3,"file":"dashboard.type.d.mts","names":[],"sources":["../../../../../../../../packages/ai-panoptic/src/dashboard/dashboard.type.ts"],"mappings":";;;;;;;;;;;;;YAaY;;;;;;EAMV;;;;;;EAMA;;;;;;EAMA;;;;;EAKA;;EAEA;;;;;;;EAOA;;;;;;;EAOA;;;;;;;;;EASA,WAAW;;;;;;;YAQD;;WAED;;WAEA;;EAET,SAAS"}
@@ -1,3 +1,6 @@
1
1
  import { DashboardHandle, DashboardOptions } from "./dashboard.type.mjs";
2
2
  import { dashboard } from "./dashboard.mjs";
3
- import { NO_PROMPT_KEY, NO_SESSION_KEY, NO_TYPE_KEY, PromptGroup, SessionGroup, TraceFilter, TypeGroup, TypeStat, aggregateByType, filterTraces, groupByPrompt, groupBySession, groupByType, heatIntensity, matchesFilter, maxNodeCost, percentile, rollupCost, traceCost, tracePromptKey } from "./trace-filter.mjs";
3
+ import "./serve.mjs";
4
+ import "./parse-query.mjs";
5
+ import { NO_PROMPT_KEY, NO_SESSION_KEY, NO_TYPE_KEY, PromptGroup, SessionGroup, TraceFilter, TypeGroup, TypeStat, aggregateByType, filterTraces, groupByPrompt, groupBySession, groupByType, heatIntensity, matchesFilter, maxNodeCost, percentile, rollupCost, traceCost, tracePromptKey } from "./trace-filter.mjs";
6
+ export { type DashboardHandle, type DashboardOptions, dashboard };