@warlock.js/ai-panoptic 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/cjs/index.cjs +1370 -0
- package/cjs/index.cjs.map +1 -0
- package/esm/collector/collector.d.mts +19 -0
- package/esm/collector/collector.d.mts.map +1 -0
- package/esm/collector/collector.mjs +89 -0
- package/esm/collector/collector.mjs.map +1 -0
- package/esm/collector/extract-span-attributes.d.mts +29 -0
- package/esm/collector/extract-span-attributes.d.mts.map +1 -0
- package/esm/collector/extract-span-attributes.mjs +76 -0
- package/esm/collector/extract-span-attributes.mjs.map +1 -0
- package/esm/collector/index.d.mts +5 -0
- package/esm/collector/normalize-error.d.mts +27 -0
- package/esm/collector/normalize-error.d.mts.map +1 -0
- package/esm/collector/normalize-error.mjs +49 -0
- package/esm/collector/normalize-error.mjs.map +1 -0
- package/esm/collector/report-to-span.d.mts +31 -0
- package/esm/collector/report-to-span.d.mts.map +1 -0
- package/esm/collector/report-to-span.mjs +53 -0
- package/esm/collector/report-to-span.mjs.map +1 -0
- package/esm/collector/report-to-trace.d.mts +35 -0
- package/esm/collector/report-to-trace.d.mts.map +1 -0
- package/esm/collector/report-to-trace.mjs +53 -0
- package/esm/collector/report-to-trace.mjs.map +1 -0
- package/esm/contracts/collector.contract.d.mts +63 -0
- package/esm/contracts/collector.contract.d.mts.map +1 -0
- package/esm/contracts/exporter.contract.d.mts +76 -0
- package/esm/contracts/exporter.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +3 -0
- package/esm/contracts/trace.type.d.mts +122 -0
- package/esm/contracts/trace.type.d.mts.map +1 -0
- package/esm/exporters/console/console-exporter.d.mts +25 -0
- package/esm/exporters/console/console-exporter.d.mts.map +1 -0
- package/esm/exporters/console/console-exporter.mjs +79 -0
- package/esm/exporters/console/console-exporter.mjs.map +1 -0
- package/esm/exporters/console/console-exporter.type.d.mts +36 -0
- package/esm/exporters/console/console-exporter.type.d.mts.map +1 -0
- package/esm/exporters/console/format-span-line.d.mts +17 -0
- package/esm/exporters/console/format-span-line.d.mts.map +1 -0
- package/esm/exporters/console/format-span-line.mjs +41 -0
- package/esm/exporters/console/format-span-line.mjs.map +1 -0
- package/esm/exporters/console/index.d.mts +3 -0
- package/esm/exporters/file/file-exporter.d.mts +23 -0
- package/esm/exporters/file/file-exporter.d.mts.map +1 -0
- package/esm/exporters/file/file-exporter.mjs +93 -0
- package/esm/exporters/file/file-exporter.mjs.map +1 -0
- package/esm/exporters/file/file-exporter.type.d.mts +39 -0
- package/esm/exporters/file/file-exporter.type.d.mts.map +1 -0
- package/esm/exporters/file/index.d.mts +2 -0
- package/esm/exporters/index.d.mts +12 -0
- package/esm/exporters/index.mjs +12 -0
- package/esm/exporters/langfuse/index.d.mts +2 -0
- package/esm/exporters/langfuse/index.mjs +3 -0
- package/esm/exporters/langfuse/langfuse-exporter.d.mts +27 -0
- package/esm/exporters/langfuse/langfuse-exporter.d.mts.map +1 -0
- package/esm/exporters/langfuse/langfuse-exporter.mjs +158 -0
- package/esm/exporters/langfuse/langfuse-exporter.mjs.map +1 -0
- package/esm/exporters/langfuse/langfuse-exporter.type.d.mts +90 -0
- package/esm/exporters/langfuse/langfuse-exporter.type.d.mts.map +1 -0
- package/esm/exporters/otel/index.d.mts +2 -0
- package/esm/exporters/otel/index.mjs +3 -0
- package/esm/exporters/otel/otel-exporter.d.mts +29 -0
- package/esm/exporters/otel/otel-exporter.d.mts.map +1 -0
- package/esm/exporters/otel/otel-exporter.mjs +142 -0
- package/esm/exporters/otel/otel-exporter.mjs.map +1 -0
- package/esm/exporters/otel/otel-exporter.type.d.mts +39 -0
- package/esm/exporters/otel/otel-exporter.type.d.mts.map +1 -0
- package/esm/exporters/utils/gen-ai-attributes.d.mts +65 -0
- package/esm/exporters/utils/gen-ai-attributes.d.mts.map +1 -0
- package/esm/exporters/utils/gen-ai-attributes.mjs +88 -0
- package/esm/exporters/utils/gen-ai-attributes.mjs.map +1 -0
- package/esm/exporters/utils/index.d.mts +3 -0
- package/esm/exporters/utils/total-cost.d.mts +20 -0
- package/esm/exporters/utils/total-cost.d.mts.map +1 -0
- package/esm/exporters/utils/total-cost.mjs +23 -0
- package/esm/exporters/utils/total-cost.mjs.map +1 -0
- package/esm/exporters/utils/walk-spans.d.mts +18 -0
- package/esm/exporters/utils/walk-spans.d.mts.map +1 -0
- package/esm/exporters/utils/walk-spans.mjs +21 -0
- package/esm/exporters/utils/walk-spans.mjs.map +1 -0
- package/esm/index.d.mts +31 -0
- package/esm/index.mjs +22 -0
- package/esm/panoptic/index.d.mts +4 -0
- package/esm/panoptic/panoptic-middleware.d.mts +38 -0
- package/esm/panoptic/panoptic-middleware.d.mts.map +1 -0
- package/esm/panoptic/panoptic-middleware.mjs +68 -0
- package/esm/panoptic/panoptic-middleware.mjs.map +1 -0
- package/esm/panoptic/panoptic-target.type.d.mts +53 -0
- package/esm/panoptic/panoptic-target.type.d.mts.map +1 -0
- package/esm/panoptic/panoptic.d.mts +37 -0
- package/esm/panoptic/panoptic.d.mts.map +1 -0
- package/esm/panoptic/panoptic.mjs +134 -0
- package/esm/panoptic/panoptic.mjs.map +1 -0
- package/esm/panoptic/panoptic.type.d.mts +100 -0
- package/esm/panoptic/panoptic.type.d.mts.map +1 -0
- package/esm/store/in-memory-trace-store.d.mts +32 -0
- package/esm/store/in-memory-trace-store.d.mts.map +1 -0
- package/esm/store/in-memory-trace-store.mjs +134 -0
- package/esm/store/in-memory-trace-store.mjs.map +1 -0
- package/esm/store/index.d.mts +6 -0
- package/esm/store/index.mjs +5 -0
- package/esm/store/match-trace.d.mts +21 -0
- package/esm/store/match-trace.d.mts.map +1 -0
- package/esm/store/match-trace.mjs +44 -0
- package/esm/store/match-trace.mjs.map +1 -0
- package/esm/store/sum-usage.d.mts +34 -0
- package/esm/store/sum-usage.d.mts.map +1 -0
- package/esm/store/sum-usage.mjs +65 -0
- package/esm/store/sum-usage.mjs.map +1 -0
- package/esm/store/trace-aggregate.type.d.mts +51 -0
- package/esm/store/trace-aggregate.type.d.mts.map +1 -0
- package/esm/store/trace-query.type.d.mts +45 -0
- package/esm/store/trace-query.type.d.mts.map +1 -0
- package/esm/store/trace-store.contract.d.mts +55 -0
- package/esm/store/trace-store.contract.d.mts.map +1 -0
- package/llms-full.txt +450 -0
- package/llms.txt +11 -0
- package/package.json +40 -0
- package/skills/README.md +17 -0
- package/skills/export-traces/SKILL.md +152 -0
- package/skills/observe-with-panoptic/SKILL.md +128 -0
- package/skills/query-traces/SKILL.md +152 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { normalizeError } from "./normalize-error.mjs";
|
|
2
|
+
import { extractSpanAttributes } from "./extract-span-attributes.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-panoptic/src/collector/report-to-span.ts
|
|
5
|
+
/**
|
|
6
|
+
* Project one {@link BaseReport} node — and its entire subtree — into a
|
|
7
|
+
* {@link TraceSpan}. Pure and recursive: identity, timing, status, and
|
|
8
|
+
* the rolled-up `usage` map across 1:1 from the report; lineage maps
|
|
9
|
+
* `runId → spanId`, `parentRunId → parentSpanId`, `rootRunId → traceId`;
|
|
10
|
+
* children recurse in invocation order so the span tree mirrors the
|
|
11
|
+
* report tree exactly.
|
|
12
|
+
*
|
|
13
|
+
* The error is normalized to the JSON-safe {@link
|
|
14
|
+
* import("../contracts/trace.type").TraceSpanError} shape only when the
|
|
15
|
+
* node carried one (failed / cancelled). Primitive-specific detail that
|
|
16
|
+
* has no first-class span field (trip / step / iteration counts, model
|
|
17
|
+
* identity, tool trip index) is routed into the optional `attributes`
|
|
18
|
+
* bag via {@link extractSpanAttributes}.
|
|
19
|
+
*
|
|
20
|
+
* No external lookup is needed — a `BaseReport` already carries
|
|
21
|
+
* everything a span requires, so a collector can flatten a tree without
|
|
22
|
+
* consulting any other source.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const root = reportToSpan(result.report);
|
|
26
|
+
* console.log(root.spanId, root.traceId, root.children.length);
|
|
27
|
+
*/
|
|
28
|
+
function reportToSpan(report) {
|
|
29
|
+
const span = {
|
|
30
|
+
spanId: report.runId,
|
|
31
|
+
traceId: report.rootRunId,
|
|
32
|
+
name: report.name,
|
|
33
|
+
type: report.type,
|
|
34
|
+
status: report.status,
|
|
35
|
+
startedAt: report.startedAt,
|
|
36
|
+
endedAt: report.endedAt,
|
|
37
|
+
duration: report.duration,
|
|
38
|
+
usage: report.usage,
|
|
39
|
+
children: report.children.map(reportToSpan)
|
|
40
|
+
};
|
|
41
|
+
if (report.parentRunId !== void 0) span.parentSpanId = report.parentRunId;
|
|
42
|
+
if (report.sessionId !== void 0) span.sessionId = report.sessionId;
|
|
43
|
+
if (report.version !== void 0) span.version = report.version;
|
|
44
|
+
const error = normalizeError(report.error);
|
|
45
|
+
if (error !== void 0) span.error = error;
|
|
46
|
+
const attributes = extractSpanAttributes(report);
|
|
47
|
+
if (attributes !== void 0) span.attributes = attributes;
|
|
48
|
+
return span;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
export { reportToSpan };
|
|
53
|
+
//# sourceMappingURL=report-to-span.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-to-span.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai-panoptic/src/collector/report-to-span.ts"],"sourcesContent":["import type { BaseReport } from \"@warlock.js/ai\";\nimport type { TraceSpan } from \"../contracts/trace.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 * 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): 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(reportToSpan),\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 return span;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,aAAa,QAA+B;CAC1D,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,IAAI,YAAY;CAC5C;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,OAAO;AACT"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Trace } from "../contracts/trace.type.mjs";
|
|
2
|
+
import { BaseReport } from "@warlock.js/ai";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-panoptic/src/collector/report-to-trace.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Project an outermost {@link BaseReport} (one whole `.execute()` /
|
|
7
|
+
* `.invoke()` run) into a {@link Trace} — the root {@link
|
|
8
|
+
* import("../contracts/trace.type").TraceSpan} plus the trace-wide
|
|
9
|
+
* rollups exporters need without re-walking the tree.
|
|
10
|
+
*
|
|
11
|
+
* The trace-level identity and rollups all read off the root span the
|
|
12
|
+
* projection already built (`traceId`, `usage`, timing), so the trace
|
|
13
|
+
* envelope never disagrees with its own root. `reportSchemaVersion` is
|
|
14
|
+
* mirrored from the root report when present (it is stamped only on
|
|
15
|
+
* root nodes upstream) so exporters can branch on the source shape.
|
|
16
|
+
*
|
|
17
|
+
* Pure — the same input always yields the same trace. The collector
|
|
18
|
+
* exposes this as `toTrace` so callers can inspect the normalized shape
|
|
19
|
+
* without dispatching to exporters.
|
|
20
|
+
*
|
|
21
|
+
* The optional `rootError` threads the failing run's envelope error
|
|
22
|
+
* (`BaseResult.error`) onto the root span. The error lives on the result
|
|
23
|
+
* envelope, never on the `BaseReport` tree, so without this a failed root
|
|
24
|
+
* would export `status` with no error type/message. Applied only when the
|
|
25
|
+
* root span carries none of its own; the subtree projection stays pure
|
|
26
|
+
* (each child surfaces its own report-level error, if any).
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const trace = reportToTrace(result.report, result.error);
|
|
30
|
+
* console.log(trace.traceId, trace.usage.total, trace.duration);
|
|
31
|
+
*/
|
|
32
|
+
declare function reportToTrace(report: BaseReport, rootError?: unknown): Trace;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { reportToTrace };
|
|
35
|
+
//# sourceMappingURL=report-to-trace.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-to-trace.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai-panoptic/src/collector/report-to-trace.ts"],"mappings":";;;;;;AAgCA;;;;;;;;;AAA6E;;;;;;;;;;;;;;;;iBAA7D,aAAA,CAAc,MAAA,EAAQ,UAAA,EAAY,SAAA,aAAsB,KAAK"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { normalizeError } from "./normalize-error.mjs";
|
|
2
|
+
import { reportToSpan } from "./report-to-span.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-panoptic/src/collector/report-to-trace.ts
|
|
5
|
+
/**
|
|
6
|
+
* Project an outermost {@link BaseReport} (one whole `.execute()` /
|
|
7
|
+
* `.invoke()` run) into a {@link Trace} — the root {@link
|
|
8
|
+
* import("../contracts/trace.type").TraceSpan} plus the trace-wide
|
|
9
|
+
* rollups exporters need without re-walking the tree.
|
|
10
|
+
*
|
|
11
|
+
* The trace-level identity and rollups all read off the root span the
|
|
12
|
+
* projection already built (`traceId`, `usage`, timing), so the trace
|
|
13
|
+
* envelope never disagrees with its own root. `reportSchemaVersion` is
|
|
14
|
+
* mirrored from the root report when present (it is stamped only on
|
|
15
|
+
* root nodes upstream) so exporters can branch on the source shape.
|
|
16
|
+
*
|
|
17
|
+
* Pure — the same input always yields the same trace. The collector
|
|
18
|
+
* exposes this as `toTrace` so callers can inspect the normalized shape
|
|
19
|
+
* without dispatching to exporters.
|
|
20
|
+
*
|
|
21
|
+
* The optional `rootError` threads the failing run's envelope error
|
|
22
|
+
* (`BaseResult.error`) onto the root span. The error lives on the result
|
|
23
|
+
* envelope, never on the `BaseReport` tree, so without this a failed root
|
|
24
|
+
* would export `status` with no error type/message. Applied only when the
|
|
25
|
+
* root span carries none of its own; the subtree projection stays pure
|
|
26
|
+
* (each child surfaces its own report-level error, if any).
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const trace = reportToTrace(result.report, result.error);
|
|
30
|
+
* console.log(trace.traceId, trace.usage.total, trace.duration);
|
|
31
|
+
*/
|
|
32
|
+
function reportToTrace(report, rootError) {
|
|
33
|
+
const root = reportToSpan(report);
|
|
34
|
+
if (root.error === void 0) {
|
|
35
|
+
const error = normalizeError(rootError);
|
|
36
|
+
if (error !== void 0) root.error = error;
|
|
37
|
+
}
|
|
38
|
+
const trace = {
|
|
39
|
+
traceId: root.traceId,
|
|
40
|
+
root,
|
|
41
|
+
startedAt: root.startedAt,
|
|
42
|
+
endedAt: root.endedAt,
|
|
43
|
+
duration: root.duration,
|
|
44
|
+
usage: root.usage
|
|
45
|
+
};
|
|
46
|
+
if (root.sessionId !== void 0) trace.sessionId = root.sessionId;
|
|
47
|
+
if (report.reportSchemaVersion !== void 0) trace.reportSchemaVersion = report.reportSchemaVersion;
|
|
48
|
+
return trace;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
export { reportToTrace };
|
|
53
|
+
//# sourceMappingURL=report-to-trace.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-to-trace.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai-panoptic/src/collector/report-to-trace.ts"],"sourcesContent":["import type { BaseReport } from \"@warlock.js/ai\";\nimport type { Trace } from \"../contracts/trace.type\";\nimport { normalizeError } from \"./normalize-error\";\nimport { reportToSpan } from \"./report-to-span\";\n\n/**\n * Project an outermost {@link BaseReport} (one whole `.execute()` /\n * `.invoke()` run) into a {@link Trace} — the root {@link\n * import(\"../contracts/trace.type\").TraceSpan} plus the trace-wide\n * rollups exporters need without re-walking the tree.\n *\n * The trace-level identity and rollups all read off the root span the\n * projection already built (`traceId`, `usage`, timing), so the trace\n * envelope never disagrees with its own root. `reportSchemaVersion` is\n * mirrored from the root report when present (it is stamped only on\n * root nodes upstream) so exporters can branch on the source shape.\n *\n * Pure — the same input always yields the same trace. The collector\n * exposes this as `toTrace` so callers can inspect the normalized shape\n * without dispatching to exporters.\n *\n * The optional `rootError` threads the failing run's envelope error\n * (`BaseResult.error`) onto the root span. The error lives on the result\n * envelope, never on the `BaseReport` tree, so without this a failed root\n * would export `status` with no error type/message. Applied only when the\n * root span carries none of its own; the subtree projection stays pure\n * (each child surfaces its own report-level error, if any).\n *\n * @example\n * const trace = reportToTrace(result.report, result.error);\n * console.log(trace.traceId, trace.usage.total, trace.duration);\n */\nexport function reportToTrace(report: BaseReport, rootError?: unknown): Trace {\n const root = reportToSpan(report);\n\n if (root.error === undefined) {\n const error = normalizeError(rootError);\n\n if (error !== undefined) {\n root.error = error;\n }\n }\n\n const trace: Trace = {\n traceId: root.traceId,\n root,\n startedAt: root.startedAt,\n endedAt: root.endedAt,\n duration: root.duration,\n usage: root.usage,\n };\n\n if (root.sessionId !== undefined) {\n trace.sessionId = root.sessionId;\n }\n\n if (report.reportSchemaVersion !== undefined) {\n trace.reportSchemaVersion = report.reportSchemaVersion;\n }\n\n return trace;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,cAAc,QAAoB,WAA4B;CAC5E,MAAM,OAAO,aAAa,MAAM;CAEhC,IAAI,KAAK,UAAU,QAAW;EAC5B,MAAM,QAAQ,eAAe,SAAS;EAEtC,IAAI,UAAU,QACZ,KAAK,QAAQ;CAEjB;CAEA,MAAM,QAAe;EACnB,SAAS,KAAK;EACd;EACA,WAAW,KAAK;EAChB,SAAS,KAAK;EACd,UAAU,KAAK;EACf,OAAO,KAAK;CACd;CAEA,IAAI,KAAK,cAAc,QACrB,MAAM,YAAY,KAAK;CAGzB,IAAI,OAAO,wBAAwB,QACjC,MAAM,sBAAsB,OAAO;CAGrC,OAAO;AACT"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Trace } from "./trace.type.mjs";
|
|
2
|
+
import { ExporterContract } from "./exporter.contract.mjs";
|
|
3
|
+
import { BaseReport } from "@warlock.js/ai";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai-panoptic/src/contracts/collector.contract.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Contract for the Panoptic collector — the source end of the
|
|
8
|
+
* observability pipeline. A collector ingests core `@warlock.js/ai`
|
|
9
|
+
* execution reports (a {@link BaseReport} tree), normalizes them into a
|
|
10
|
+
* {@link Trace}, and fans the result out to every registered
|
|
11
|
+
* {@link ExporterContract}.
|
|
12
|
+
*
|
|
13
|
+
* The collector is the single integration point an app wires into its
|
|
14
|
+
* agents/workflows (typically via the `onComplete` report hook). It
|
|
15
|
+
* owns exporter registration, the report-to-trace projection, and
|
|
16
|
+
* graceful shutdown so exporters drain before exit.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* collector.use(otelExporter).use(langfuseExporter);
|
|
20
|
+
* agent.on("onComplete", (report) => collector.collect(report));
|
|
21
|
+
* // on shutdown:
|
|
22
|
+
* await collector.shutdown();
|
|
23
|
+
*/
|
|
24
|
+
interface CollectorContract {
|
|
25
|
+
/**
|
|
26
|
+
* Register an exporter. Returns the collector for chaining. Duplicate
|
|
27
|
+
* registration (same `ExporterContract.name`) is ignored.
|
|
28
|
+
*/
|
|
29
|
+
use(exporter: ExporterContract): this;
|
|
30
|
+
/**
|
|
31
|
+
* Ingest one finalized root report, project it into a {@link Trace},
|
|
32
|
+
* and dispatch it to every registered exporter. Resolves once all
|
|
33
|
+
* exporters have been invoked; individual exporter failures are
|
|
34
|
+
* isolated and never propagate back into the originating run.
|
|
35
|
+
*
|
|
36
|
+
* `rootError` threads the failing run's envelope error (`BaseResult.error`)
|
|
37
|
+
* onto the root span — the error lives on the result envelope, not on the
|
|
38
|
+
* `BaseReport` tree, so a failed root would otherwise carry `status` with
|
|
39
|
+
* no error type/message. Applied only when the root span has none of its
|
|
40
|
+
* own.
|
|
41
|
+
*/
|
|
42
|
+
collect(report: BaseReport, rootError?: unknown): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Pure projection of a report tree into a {@link Trace}, exposed so
|
|
45
|
+
* callers can inspect or test the normalized shape without dispatching
|
|
46
|
+
* to exporters. `collect` uses this internally. `rootError` threads the
|
|
47
|
+
* envelope error onto the root span exactly as in {@link collect}.
|
|
48
|
+
*/
|
|
49
|
+
toTrace(report: BaseReport, rootError?: unknown): Trace;
|
|
50
|
+
/**
|
|
51
|
+
* Flush every registered exporter that supports it. Useful between
|
|
52
|
+
* batches or before a checkpoint.
|
|
53
|
+
*/
|
|
54
|
+
flush(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Flush and shut down every registered exporter, then release the
|
|
57
|
+
* collector. Call once during process teardown.
|
|
58
|
+
*/
|
|
59
|
+
shutdown(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { CollectorContract };
|
|
63
|
+
//# sourceMappingURL=collector.contract.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.contract.d.mts","names":[],"sources":["../../../../../../../@warlock.js/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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Trace, TraceSpan } from "./trace.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai-panoptic/src/contracts/exporter.contract.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Contract every Panoptic exporter implements. An exporter is the sink
|
|
6
|
+
* end of the observability pipeline: a `Collector` flattens core
|
|
7
|
+
* `@warlock.js/ai` reports into {@link Trace} / {@link TraceSpan}
|
|
8
|
+
* values and hands them to one or more exporters, which translate them
|
|
9
|
+
* into a backend's wire format (OpenTelemetry spans, Langfuse
|
|
10
|
+
* generations, a console table, …).
|
|
11
|
+
*
|
|
12
|
+
* **Optional-peer rule.** Concrete exporters that wrap a third-party
|
|
13
|
+
* SDK (`@opentelemetry/*`, `langfuse`) MUST lazily import that SDK
|
|
14
|
+
* inside the factory/`export` path — never at module top level — so
|
|
15
|
+
* the SDK stays an OPTIONAL peer dependency and importing this package
|
|
16
|
+
* never forces an unused vendor SDK to be installed.
|
|
17
|
+
*
|
|
18
|
+
* **Lifecycle.** A collector calls {@link ExporterContract.export} once
|
|
19
|
+
* per completed trace (and, when the exporter advertises it, also calls
|
|
20
|
+
* {@link ExporterContract.exportSpan} once for every span in the
|
|
21
|
+
* finalized tree — a post-completion per-span hook, not a live stream).
|
|
22
|
+
* `flush` / `shutdown` let buffered exporters drain before process
|
|
23
|
+
* exit.
|
|
24
|
+
*
|
|
25
|
+
* All methods may be async; the collector awaits them. An exporter that
|
|
26
|
+
* throws must not crash the originating run — the collector isolates
|
|
27
|
+
* exporter failures the same way the core event hooks swallow consumer
|
|
28
|
+
* errors.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const exporter: ExporterContract = {
|
|
32
|
+
* name: "console",
|
|
33
|
+
* async export(trace) {
|
|
34
|
+
* console.log(trace.traceId, trace.usage.total, "tokens");
|
|
35
|
+
* },
|
|
36
|
+
* };
|
|
37
|
+
*/
|
|
38
|
+
interface ExporterContract {
|
|
39
|
+
/**
|
|
40
|
+
* Stable identifier for this exporter (e.g. `"otel"`, `"langfuse"`,
|
|
41
|
+
* `"console"`). Used in logs and to de-duplicate exporters registered
|
|
42
|
+
* on a collector.
|
|
43
|
+
*/
|
|
44
|
+
readonly name: string;
|
|
45
|
+
/**
|
|
46
|
+
* Emit one completed trace. Called once per outermost run after the
|
|
47
|
+
* root report is finalized. The exporter translates `trace` into its
|
|
48
|
+
* backend format and dispatches it.
|
|
49
|
+
*/
|
|
50
|
+
export(trace: Trace): void | Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Optional per-span hook — invoked once for every span in the
|
|
53
|
+
* finalized trace tree (root first, then each descendant in
|
|
54
|
+
* invocation order), after `export`. A post-completion projection of
|
|
55
|
+
* the same tree, not a live feed: it lets flat-stream backends emit
|
|
56
|
+
* one record per node without re-walking `children` themselves.
|
|
57
|
+
* Collectors only invoke this when present; exporters that consume the
|
|
58
|
+
* whole tree in `export` may omit it.
|
|
59
|
+
*/
|
|
60
|
+
exportSpan?(span: TraceSpan): void | Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Optional — flush any buffered traces/spans to the backend without
|
|
63
|
+
* tearing the exporter down. Collectors call this on demand (e.g.
|
|
64
|
+
* between batches) and during `shutdown`.
|
|
65
|
+
*/
|
|
66
|
+
flush?(): void | Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Optional — flush and release resources (close HTTP clients, OTel
|
|
69
|
+
* processors). Called once when the owning collector is disposed.
|
|
70
|
+
* After `shutdown`, the exporter should not be reused.
|
|
71
|
+
*/
|
|
72
|
+
shutdown?(): void | Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { ExporterContract };
|
|
76
|
+
//# sourceMappingURL=exporter.contract.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter.contract.d.mts","names":[],"sources":["../../../../../../../@warlock.js/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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ReportStatus, ReportType, Usage } from "@warlock.js/ai";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai-panoptic/src/contracts/trace.type.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A single node in a Panoptic trace tree, derived 1:1 from a core
|
|
6
|
+
* `@warlock.js/ai` {@link BaseReport} node. Where `BaseReport` is the
|
|
7
|
+
* framework's native execution report, a {@link TraceSpan} is its
|
|
8
|
+
* observability-vendor projection: the same identity and timing
|
|
9
|
+
* normalized to the span vocabulary shared by OpenTelemetry, Langfuse,
|
|
10
|
+
* and similar backends.
|
|
11
|
+
*
|
|
12
|
+
* The mapping is intentionally lossless on the fields exporters care
|
|
13
|
+
* about — identity (`spanId` / `parentSpanId` / `traceId`), timing
|
|
14
|
+
* (`startedAt` / `endedAt` / `duration`), outcome (`status` / `error`),
|
|
15
|
+
* and cost (`usage`) — so a collector can flatten a `BaseReport` tree
|
|
16
|
+
* into spans without consulting any other source.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const root: TraceSpan = {
|
|
20
|
+
* spanId: report.runId,
|
|
21
|
+
* traceId: report.rootRunId,
|
|
22
|
+
* name: report.name,
|
|
23
|
+
* type: report.type,
|
|
24
|
+
* status: report.status,
|
|
25
|
+
* startedAt: report.startedAt,
|
|
26
|
+
* endedAt: report.endedAt,
|
|
27
|
+
* duration: report.duration,
|
|
28
|
+
* usage: report.usage,
|
|
29
|
+
* children: [],
|
|
30
|
+
* };
|
|
31
|
+
*/
|
|
32
|
+
type TraceSpan = {
|
|
33
|
+
/**
|
|
34
|
+
* Stable id for this span. Mirrors `BaseReport.runId` — one span per
|
|
35
|
+
* execution node.
|
|
36
|
+
*/
|
|
37
|
+
spanId: string;
|
|
38
|
+
/**
|
|
39
|
+
* Id of the immediate parent span, mirroring `BaseReport.parentRunId`.
|
|
40
|
+
* Absent on the root span of a trace.
|
|
41
|
+
*/
|
|
42
|
+
parentSpanId?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Id of the top-level trace this span belongs to. Mirrors
|
|
45
|
+
* `BaseReport.rootRunId`; equals `spanId` on the root span. Exporters
|
|
46
|
+
* map this onto the backend's trace id (OTel `traceId`, Langfuse
|
|
47
|
+
* trace).
|
|
48
|
+
*/
|
|
49
|
+
traceId: string;
|
|
50
|
+
/**
|
|
51
|
+
* Caller-supplied grouping id mirrored from `BaseReport.sessionId`.
|
|
52
|
+
* Surfaces as a session/thread dimension in backends that model
|
|
53
|
+
* conversations. Absent when the caller didn't supply one.
|
|
54
|
+
*/
|
|
55
|
+
sessionId?: string; /** Executable identity — the tool/agent/workflow/supervisor name. */
|
|
56
|
+
name: string;
|
|
57
|
+
/**
|
|
58
|
+
* Dev-curated version string mirrored from `BaseReport.version`.
|
|
59
|
+
* Free-form; surfaced as a span attribute so dashboards can slice
|
|
60
|
+
* runs of "agent X v2.1" from "v2.2". Absent when undeclared.
|
|
61
|
+
*/
|
|
62
|
+
version?: string; /** Discriminator for the kind of executable that produced this span. */
|
|
63
|
+
type: ReportType; /** Terminal status of this execution, mirrored from `BaseReport.status`. */
|
|
64
|
+
status: ReportStatus; /** ISO-8601 wall-clock timestamp when execution began. */
|
|
65
|
+
startedAt: string; /** ISO-8601 wall-clock timestamp when execution finished. */
|
|
66
|
+
endedAt: string; /** Monotonic duration in milliseconds. */
|
|
67
|
+
duration: number; /** Rolled-up usage for this node (own cost + sum of children). */
|
|
68
|
+
usage: Usage;
|
|
69
|
+
/**
|
|
70
|
+
* Normalized error description when `status` is `"failed"` /
|
|
71
|
+
* `"cancelled"`. Carried separately from status so exporters can set
|
|
72
|
+
* a backend error event/attribute. Absent on successful spans.
|
|
73
|
+
*/
|
|
74
|
+
error?: TraceSpanError;
|
|
75
|
+
/**
|
|
76
|
+
* Free-form attribute bag forwarded verbatim onto the backend span
|
|
77
|
+
* (OTel attributes, Langfuse metadata). Collectors populate this with
|
|
78
|
+
* primitive-specific detail (trip index, step name, tool args digest)
|
|
79
|
+
* that has no first-class field here. Absent when empty.
|
|
80
|
+
*/
|
|
81
|
+
attributes?: Record<string, unknown>;
|
|
82
|
+
/**
|
|
83
|
+
* Child spans, mirroring `BaseReport.children` in invocation order.
|
|
84
|
+
* Empty for leaf spans (pure tools). Exporters that emit a flat
|
|
85
|
+
* stream may ignore this and rely on `parentSpanId` instead.
|
|
86
|
+
*/
|
|
87
|
+
children: TraceSpan[];
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Normalized error attached to a failed / cancelled {@link TraceSpan}.
|
|
91
|
+
* Kept structural (not an `Error` instance) so it survives JSON
|
|
92
|
+
* serialization to a backend collector unchanged.
|
|
93
|
+
*/
|
|
94
|
+
type TraceSpanError = {
|
|
95
|
+
/** Stable error identifier (typed framework error name when available). */type: string; /** Human-readable message. */
|
|
96
|
+
message: string; /** Optional captured stack trace, when the source error carried one. */
|
|
97
|
+
stack?: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* The root of a Panoptic trace — a top-level {@link TraceSpan} plus the
|
|
101
|
+
* trace-wide rollups exporters need without re-walking the tree. One
|
|
102
|
+
* `Trace` corresponds to one outermost `BaseReport` (a single
|
|
103
|
+
* `.execute()` / `.invoke()` call).
|
|
104
|
+
*/
|
|
105
|
+
type Trace = {
|
|
106
|
+
/** Trace id — equals the root span's `traceId` / `rootRunId`. */traceId: string; /** Session grouping id, when the originating run carried one. */
|
|
107
|
+
sessionId?: string; /** Root span of this trace. */
|
|
108
|
+
root: TraceSpan; /** Wall-clock start of the trace (root span `startedAt`). */
|
|
109
|
+
startedAt: string; /** Wall-clock end of the trace (root span `endedAt`). */
|
|
110
|
+
endedAt: string; /** Total trace duration in milliseconds (root span `duration`). */
|
|
111
|
+
duration: number; /** Trace-wide usage rollup (root span `usage`). */
|
|
112
|
+
usage: Usage;
|
|
113
|
+
/**
|
|
114
|
+
* Wire-format version of the source `BaseReport` shape, mirrored from
|
|
115
|
+
* `BaseReport.reportSchemaVersion`. Exporters branch on this to parse
|
|
116
|
+
* older stored traces with their original-shape rules.
|
|
117
|
+
*/
|
|
118
|
+
reportSchemaVersion?: number;
|
|
119
|
+
};
|
|
120
|
+
//#endregion
|
|
121
|
+
export { Trace, TraceSpan, TraceSpanError };
|
|
122
|
+
//# sourceMappingURL=trace.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.type.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai-panoptic/src/contracts/trace.type.ts"],"mappings":";;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;KAAY,SAAA;EAiDF;;;;EA5CR,MAAA;EAyDmB;AAAA;AAQrB;;EA5DE,YAAA;EA4DwB;;;;;AAMnB;EA3DL,OAAA;EAoEe;;;;;EA9Df,SAAA,WAoEM;EAlEN,IAAA;EAsEA;;;;;EAhEA,OAAA,WA0EmB;EAxEnB,IAAA,EAAM,UAAA;EAEN,MAAA,EAAQ,YAAA;EAER,SAAA;EAEA,OAAA;EAEA,QAAA;EAEA,KAAA,EAAO,KAAA;;;;;;EAMP,KAAA,GAAQ,cAAA;;;;;;;EAOR,UAAA,GAAa,MAAA;;;;;;EAMb,QAAA,EAAU,SAAA;AAAA;;;;;;KAQA,cAAA;6EAEV,IAAA;EAEA,OAAA;EAEA,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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ExporterContract } from "../../contracts/exporter.contract.mjs";
|
|
2
|
+
import { ConsoleExporterOptions } from "./console-exporter.type.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-panoptic/src/exporters/console/console-exporter.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Zero-dependency {@link ExporterContract} that prints traces to a
|
|
7
|
+
* console-like sink. The simplest exporter — useful in development and
|
|
8
|
+
* as the reference implementation of the contract.
|
|
9
|
+
*
|
|
10
|
+
* By default it prints one summary line per completed trace. Set
|
|
11
|
+
* `tree: true` to print the full indented span tree, and
|
|
12
|
+
* `streaming: true` to also print each span the moment it finalizes
|
|
13
|
+
* (via the optional `exportSpan` hook).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* collector.use(consoleExporter());
|
|
17
|
+
* // ok workflow "checkout" — 2103ms, 1820 tok, $0.0094
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* collector.use(consoleExporter({ tree: true }));
|
|
21
|
+
*/
|
|
22
|
+
declare function consoleExporter(options?: ConsoleExporterOptions): ExporterContract;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { consoleExporter };
|
|
25
|
+
//# sourceMappingURL=console-exporter.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console-exporter.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai-panoptic/src/exporters/console/console-exporter.ts"],"mappings":";;;;;;;AAwBA;;;;;;;;AAAuF;;;;;;iBAAvE,eAAA,CAAgB,OAAA,GAAS,sBAAA,GAA8B,gBAAgB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { walkSpans } from "../utils/walk-spans.mjs";
|
|
2
|
+
import { formatSpanLine } from "./format-span-line.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-panoptic/src/exporters/console/console-exporter.ts
|
|
5
|
+
const EXPORTER_NAME = "console";
|
|
6
|
+
/**
|
|
7
|
+
* Zero-dependency {@link ExporterContract} that prints traces to a
|
|
8
|
+
* console-like sink. The simplest exporter — useful in development and
|
|
9
|
+
* as the reference implementation of the contract.
|
|
10
|
+
*
|
|
11
|
+
* By default it prints one summary line per completed trace. Set
|
|
12
|
+
* `tree: true` to print the full indented span tree, and
|
|
13
|
+
* `streaming: true` to also print each span the moment it finalizes
|
|
14
|
+
* (via the optional `exportSpan` hook).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* collector.use(consoleExporter());
|
|
18
|
+
* // ok workflow "checkout" — 2103ms, 1820 tok, $0.0094
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* collector.use(consoleExporter({ tree: true }));
|
|
22
|
+
*/
|
|
23
|
+
function consoleExporter(options = {}) {
|
|
24
|
+
const sink = options.console ?? console;
|
|
25
|
+
const tree = options.tree ?? false;
|
|
26
|
+
const exporter = {
|
|
27
|
+
name: EXPORTER_NAME,
|
|
28
|
+
export(trace) {
|
|
29
|
+
writeTrace(sink, trace, tree);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
if (options.streaming) exporter.exportSpan = (span) => {
|
|
33
|
+
sink.log(formatSpanLine(span));
|
|
34
|
+
};
|
|
35
|
+
return exporter;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Write a completed trace — either a single root summary line or the
|
|
39
|
+
* full indented tree. Failed traces are routed to `console.error` so
|
|
40
|
+
* they surface at the right severity in log aggregators.
|
|
41
|
+
*/
|
|
42
|
+
function writeTrace(sink, trace, tree) {
|
|
43
|
+
if (!tree) {
|
|
44
|
+
const line = formatSpanLine(trace.root);
|
|
45
|
+
writeAtSeverity(sink, trace.root.status, line);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const span of walkSpans(trace.root)) {
|
|
49
|
+
const line = formatSpanLine(span, spanDepth(trace.root, span.spanId));
|
|
50
|
+
writeAtSeverity(sink, span.status, line);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Route a line to `error` when the span failed/cancelled, otherwise to
|
|
55
|
+
* `log`. Keeps healthy traces out of the error stream.
|
|
56
|
+
*/
|
|
57
|
+
function writeAtSeverity(sink, status, line) {
|
|
58
|
+
if (status === "failed" || status === "cancelled") {
|
|
59
|
+
sink.error(line);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
sink.log(line);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Depth of `targetSpanId` below `root` for indentation. Walks the tree
|
|
66
|
+
* once; returns 0 when the span is the root or not found.
|
|
67
|
+
*/
|
|
68
|
+
function spanDepth(root, targetSpanId, depth = 0) {
|
|
69
|
+
if (root.spanId === targetSpanId) return depth;
|
|
70
|
+
for (const child of root.children) {
|
|
71
|
+
const found = spanDepth(child, targetSpanId, depth + 1);
|
|
72
|
+
if (found > 0) return found;
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { consoleExporter };
|
|
79
|
+
//# sourceMappingURL=console-exporter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console-exporter.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai-panoptic/src/exporters/console/console-exporter.ts"],"sourcesContent":["import type { ExporterContract, Trace, TraceSpan } from \"../../contracts\";\nimport { walkSpans } from \"../utils\";\nimport type { ConsoleExporterOptions, ConsoleLike } from \"./console-exporter.type\";\nimport { formatSpanLine } from \"./format-span-line\";\n\nconst EXPORTER_NAME = \"console\";\n\n/**\n * Zero-dependency {@link ExporterContract} that prints traces to a\n * console-like sink. The simplest exporter — useful in development and\n * as the reference implementation of the contract.\n *\n * By default it prints one summary line per completed trace. Set\n * `tree: true` to print the full indented span tree, and\n * `streaming: true` to also print each span the moment it finalizes\n * (via the optional `exportSpan` hook).\n *\n * @example\n * collector.use(consoleExporter());\n * // ok workflow \"checkout\" — 2103ms, 1820 tok, $0.0094\n *\n * @example\n * collector.use(consoleExporter({ tree: true }));\n */\nexport function consoleExporter(options: ConsoleExporterOptions = {}): ExporterContract {\n const sink: ConsoleLike = options.console ?? console;\n const tree = options.tree ?? false;\n\n const exporter: ExporterContract = {\n name: EXPORTER_NAME,\n export(trace: Trace): void {\n writeTrace(sink, trace, tree);\n },\n };\n\n if (options.streaming) {\n exporter.exportSpan = (span: TraceSpan): void => {\n sink.log(formatSpanLine(span));\n };\n }\n\n return exporter;\n}\n\n/**\n * Write a completed trace — either a single root summary line or the\n * full indented tree. Failed traces are routed to `console.error` so\n * they surface at the right severity in log aggregators.\n */\nfunction writeTrace(sink: ConsoleLike, trace: Trace, tree: boolean): void {\n if (!tree) {\n const line = formatSpanLine(trace.root);\n writeAtSeverity(sink, trace.root.status, line);\n return;\n }\n\n for (const span of walkSpans(trace.root)) {\n const depth = spanDepth(trace.root, span.spanId);\n const line = formatSpanLine(span, depth);\n writeAtSeverity(sink, span.status, line);\n }\n}\n\n/**\n * Route a line to `error` when the span failed/cancelled, otherwise to\n * `log`. Keeps healthy traces out of the error stream.\n */\nfunction writeAtSeverity(sink: ConsoleLike, status: TraceSpan[\"status\"], line: string): void {\n if (status === \"failed\" || status === \"cancelled\") {\n sink.error(line);\n return;\n }\n\n sink.log(line);\n}\n\n/**\n * Depth of `targetSpanId` below `root` for indentation. Walks the tree\n * once; returns 0 when the span is the root or not found.\n */\nfunction spanDepth(root: TraceSpan, targetSpanId: string, depth = 0): number {\n if (root.spanId === targetSpanId) {\n return depth;\n }\n\n for (const child of root.children) {\n const found = spanDepth(child, targetSpanId, depth + 1);\n\n if (found > 0) {\n return found;\n }\n }\n\n return 0;\n}\n"],"mappings":";;;;AAKA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;AAmBtB,SAAgB,gBAAgB,UAAkC,CAAC,GAAqB;CACtF,MAAM,OAAoB,QAAQ,WAAW;CAC7C,MAAM,OAAO,QAAQ,QAAQ;CAE7B,MAAM,WAA6B;EACjC,MAAM;EACN,OAAO,OAAoB;GACzB,WAAW,MAAM,OAAO,IAAI;EAC9B;CACF;CAEA,IAAI,QAAQ,WACV,SAAS,cAAc,SAA0B;EAC/C,KAAK,IAAI,eAAe,IAAI,CAAC;CAC/B;CAGF,OAAO;AACT;;;;;;AAOA,SAAS,WAAW,MAAmB,OAAc,MAAqB;CACxE,IAAI,CAAC,MAAM;EACT,MAAM,OAAO,eAAe,MAAM,IAAI;EACtC,gBAAgB,MAAM,MAAM,KAAK,QAAQ,IAAI;EAC7C;CACF;CAEA,KAAK,MAAM,QAAQ,UAAU,MAAM,IAAI,GAAG;EAExC,MAAM,OAAO,eAAe,MADd,UAAU,MAAM,MAAM,KAAK,MACH,CAAC;EACvC,gBAAgB,MAAM,KAAK,QAAQ,IAAI;CACzC;AACF;;;;;AAMA,SAAS,gBAAgB,MAAmB,QAA6B,MAAoB;CAC3F,IAAI,WAAW,YAAY,WAAW,aAAa;EACjD,KAAK,MAAM,IAAI;EACf;CACF;CAEA,KAAK,IAAI,IAAI;AACf;;;;;AAMA,SAAS,UAAU,MAAiB,cAAsB,QAAQ,GAAW;CAC3E,IAAI,KAAK,WAAW,cAClB,OAAO;CAGT,KAAK,MAAM,SAAS,KAAK,UAAU;EACjC,MAAM,QAAQ,UAAU,OAAO,cAAc,QAAQ,CAAC;EAEtD,IAAI,QAAQ,GACV,OAAO;CAEX;CAEA,OAAO;AACT"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai-panoptic/src/exporters/console/console-exporter.type.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Sink a {@link ConsoleExporter} writes formatted lines to. Defaults to
|
|
4
|
+
* the global `console`; injectable so tests can capture output without
|
|
5
|
+
* monkey-patching the global. Only the two levels the exporter uses are
|
|
6
|
+
* required.
|
|
7
|
+
*/
|
|
8
|
+
type ConsoleLike = {
|
|
9
|
+
log(...args: unknown[]): void;
|
|
10
|
+
error(...args: unknown[]): void;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Options for {@link consoleExporter}.
|
|
14
|
+
*/
|
|
15
|
+
type ConsoleExporterOptions = {
|
|
16
|
+
/**
|
|
17
|
+
* Where to write. Defaults to the global `console`. Inject a custom
|
|
18
|
+
* sink in tests or to redirect to a structured logger.
|
|
19
|
+
*/
|
|
20
|
+
console?: ConsoleLike;
|
|
21
|
+
/**
|
|
22
|
+
* Emit one indented line per span in the trace tree (`true`) instead
|
|
23
|
+
* of a single summary line for the whole trace (`false`). Defaults to
|
|
24
|
+
* `false` — one line per trace keeps long-running processes readable.
|
|
25
|
+
*/
|
|
26
|
+
tree?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Also print live `exportSpan` lines as each span finalizes. Defaults
|
|
29
|
+
* to `false`; the collector only calls `exportSpan` when the method is
|
|
30
|
+
* present, so leaving this off omits the method entirely.
|
|
31
|
+
*/
|
|
32
|
+
streaming?: boolean;
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
export { ConsoleExporterOptions, ConsoleLike };
|
|
36
|
+
//# sourceMappingURL=console-exporter.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console-exporter.type.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai-panoptic/src/exporters/console/console-exporter.type.ts"],"mappings":";;AAMA;;;;;KAAY,WAAA;EACV,GAAA,IAAO,IAAA;EACP,KAAA,IAAS,IAAA;AAAA;AAAI;AAMf;;AANe,KAMH,sBAAA;EAKW;;;;EAArB,OAAA,GAAU,WAAW;EAYZ;AAAA;;;;EANT,IAAA;;;;;;EAMA,SAAA;AAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TraceSpan } from "../../contracts/trace.type.mjs";
|
|
2
|
+
//#region ../@warlock.js/ai-panoptic/src/exporters/console/format-span-line.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Render a single {@link TraceSpan} as one scannable console line:
|
|
5
|
+
* `<status> <type> "<name>" — <duration>ms, <tokens> tok[, $<cost>]`.
|
|
6
|
+
* `depth` controls leading indentation when printing a tree. Pure — no
|
|
7
|
+
* side effects — so it is trivially testable and reused by both the
|
|
8
|
+
* per-trace summary and the per-span streaming line.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* formatSpanLine(span, 1);
|
|
12
|
+
* // ' ok agent "router" — 1240ms, 470 tok, $0.0021'
|
|
13
|
+
*/
|
|
14
|
+
declare function formatSpanLine(span: TraceSpan, depth?: number): string;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { formatSpanLine };
|
|
17
|
+
//# sourceMappingURL=format-span-line.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-span-line.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai-panoptic/src/exporters/console/format-span-line.ts"],"mappings":";;;;;AAcA;;;;;;;;iBAAgB,cAAA,CAAe,IAAA,EAAM,SAAS,EAAE,KAAA"}
|