@newrelic/preflight 1.4.46 → 1.5.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/dist/dashboard/index.d.ts +1 -1
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/live-event-bus.d.ts +32 -0
- package/dist/dashboard/live-event-bus.d.ts.map +1 -1
- package/dist/dashboard/live-event-bus.js.map +1 -1
- package/dist/dashboard/routes/api-handler.d.ts +46 -0
- package/dist/dashboard/routes/api-handler.d.ts.map +1 -1
- package/dist/dashboard/routes/api-handler.js +188 -5
- package/dist/dashboard/routes/api-handler.js.map +1 -1
- package/dist/dashboard/subagent-timeline-store.d.ts +156 -0
- package/dist/dashboard/subagent-timeline-store.d.ts.map +1 -0
- package/dist/dashboard/subagent-timeline-store.js +674 -0
- package/dist/dashboard/subagent-timeline-store.js.map +1 -0
- package/dist/dashboard/workflow-store.d.ts +85 -0
- package/dist/dashboard/workflow-store.d.ts.map +1 -0
- package/dist/dashboard/workflow-store.js +330 -0
- package/dist/dashboard/workflow-store.js.map +1 -0
- package/dist/hooks/event-processor.d.ts +86 -1
- package/dist/hooks/event-processor.d.ts.map +1 -1
- package/dist/hooks/event-processor.js +182 -0
- package/dist/hooks/event-processor.js.map +1 -1
- package/dist/hooks/subagent-watcher.d.ts +182 -0
- package/dist/hooks/subagent-watcher.d.ts.map +1 -0
- package/dist/hooks/subagent-watcher.js +765 -0
- package/dist/hooks/subagent-watcher.js.map +1 -0
- package/dist/hooks/workflow-script-parser.d.ts +44 -0
- package/dist/hooks/workflow-script-parser.d.ts.map +1 -0
- package/dist/hooks/workflow-script-parser.js +255 -0
- package/dist/hooks/workflow-script-parser.js.map +1 -0
- package/dist/hooks/workflow-watcher.d.ts +65 -0
- package/dist/hooks/workflow-watcher.d.ts.map +1 -0
- package/dist/hooks/workflow-watcher.js +402 -0
- package/dist/hooks/workflow-watcher.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +315 -11
- package/dist/index.js.map +1 -1
- package/dist/metrics/cost-tracker.d.ts +113 -17
- package/dist/metrics/cost-tracker.d.ts.map +1 -1
- package/dist/metrics/cost-tracker.js +151 -8
- package/dist/metrics/cost-tracker.js.map +1 -1
- package/dist/metrics/workflow-run-tracker.d.ts +140 -0
- package/dist/metrics/workflow-run-tracker.d.ts.map +1 -0
- package/dist/metrics/workflow-run-tracker.js +306 -0
- package/dist/metrics/workflow-run-tracker.js.map +1 -0
- package/dist/storage/session-store.d.ts +8 -0
- package/dist/storage/session-store.d.ts.map +1 -1
- package/dist/storage/session-store.js +1 -1
- package/dist/storage/session-store.js.map +1 -1
- package/dist/storage/types.d.ts +40 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/transport/nr-ingest.d.ts +153 -2
- package/dist/transport/nr-ingest.d.ts.map +1 -1
- package/dist/transport/nr-ingest.js +276 -1
- package/dist/transport/nr-ingest.js.map +1 -1
- package/dist/web/assets/index-B4DkT4Go.css +2 -0
- package/dist/web/assets/index-CWwZdwYX.js +64 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-C5S1WHiP.js +0 -64
- package/dist/web/assets/index-DwBQxRYb.css +0 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { LiveEventBus } from './live-event-bus.js';
|
|
2
|
-
export type { LiveEventName, LiveEventMap, ToolCallEvent, CostUpdateEvent, AntiPatternEvent, HeartbeatEvent, AlertEvent, ReplayEntry, } from './live-event-bus.js';
|
|
2
|
+
export type { LiveEventName, LiveEventMap, ToolCallEvent, CostUpdateEvent, AntiPatternEvent, HeartbeatEvent, AlertEvent, ReplayEntry, SubagentTurnEvent, WorkflowRunLiveEvent, ObservabilityHealthEvent, } from './live-event-bus.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC"}
|
|
@@ -62,6 +62,35 @@ export interface ContextUpdateEvent {
|
|
|
62
62
|
readonly estimatedTokens: number;
|
|
63
63
|
}>;
|
|
64
64
|
}
|
|
65
|
+
export interface SubagentTurnEvent {
|
|
66
|
+
readonly sessionId?: string;
|
|
67
|
+
readonly agentId: string;
|
|
68
|
+
readonly workflowRunId: string | null;
|
|
69
|
+
readonly model: string;
|
|
70
|
+
readonly inputTokens: number;
|
|
71
|
+
readonly outputTokens: number;
|
|
72
|
+
readonly cacheReadTokens: number;
|
|
73
|
+
readonly cacheCreationTokens: number;
|
|
74
|
+
readonly usdEstimate: number | null;
|
|
75
|
+
readonly ts: number;
|
|
76
|
+
}
|
|
77
|
+
export interface WorkflowRunLiveEvent {
|
|
78
|
+
readonly sessionId?: string;
|
|
79
|
+
readonly workflowRunId: string;
|
|
80
|
+
readonly runSource: 'agent_tool' | 'script';
|
|
81
|
+
readonly workflowName: string;
|
|
82
|
+
readonly status: string;
|
|
83
|
+
readonly agentCount: number;
|
|
84
|
+
readonly totalTokens: number;
|
|
85
|
+
readonly durationMs: number;
|
|
86
|
+
readonly ts: number;
|
|
87
|
+
}
|
|
88
|
+
export interface ObservabilityHealthEvent {
|
|
89
|
+
readonly filesWatched: number;
|
|
90
|
+
readonly parseErrors: number;
|
|
91
|
+
readonly watcherDisabledByLock: boolean;
|
|
92
|
+
readonly ts: number;
|
|
93
|
+
}
|
|
65
94
|
export type LiveEventMap = {
|
|
66
95
|
'tool-call': ToolCallEvent;
|
|
67
96
|
'cost-update': CostUpdateEvent;
|
|
@@ -69,6 +98,9 @@ export type LiveEventMap = {
|
|
|
69
98
|
'context-update': ContextUpdateEvent;
|
|
70
99
|
heartbeat: HeartbeatEvent;
|
|
71
100
|
alert: AlertEvent;
|
|
101
|
+
'subagent-turn': SubagentTurnEvent;
|
|
102
|
+
'workflow-run': WorkflowRunLiveEvent;
|
|
103
|
+
'observability-health': ObservabilityHealthEvent;
|
|
72
104
|
};
|
|
73
105
|
export type LiveEventName = keyof LiveEventMap;
|
|
74
106
|
export interface ReplayEntry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-event-bus.d.ts","sourceRoot":"","sources":["../../src/dashboard/live-event-bus.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/F;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,aAAa,CAAC;IAC3B,aAAa,EAAE,eAAe,CAAC;IAC/B,cAAc,EAAE,gBAAgB,CAAC;IACjC,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"live-event-bus.d.ts","sourceRoot":"","sources":["../../src/dashboard/live-event-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-event-bus.js","sourceRoot":"","sources":["../../src/dashboard/live-event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"live-event-bus.js","sourceRoot":"","sources":["../../src/dashboard/live-event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA6I3C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAOhC,4EAA4E;AAC5E,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AACxE,MAAM,UAAU,GAAG,UAAU,CAAC;AAE9B,MAAM,OAAO,YAAY;IACN,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IAC7B,MAAM,GAAkB,EAAE,CAAC;IAC3B,UAAU,CAAS;IACpC,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,6DAA6D;IACrD,OAAO,GAAG,CAAC,CAAC;IAEpB,YAAY,OAA4B,EAAE;QACxC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,gBAAgB,IAAI,mBAAmB,CAAC;QAC/D,gEAAgE;QAChE,sEAAsE;QACtE,sEAAsE;QACtE,kEAAkE;QAClE,0EAA0E;QAC1E,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,EAAE,CAA0B,KAAQ,EAAE,OAA2C;QAC/E,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAuC,CAAC,CAAC;IAClE,CAAC;IAED,GAAG,CAA0B,KAAQ,EAAE,OAA2C;QAChF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAuC,CAAC,CAAC;IACnE,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,oEAAoE;IACpE,sBAAsB;IACtB,SAAS,CAA0B,KAAQ,EAAE,OAAqC;QAChF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,KAAK,EAAE,OAAuC,CAAC,CAAC;IAC/E,CAAC;IAED,UAAU,CAA0B,KAAQ,EAAE,OAAqC;QACjF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,KAAK,EAAE,OAAuC,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,CAA0B,KAAQ,EAAE,OAAwB;QAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9D,wEAAwE;QACxE,wEAAwE;QACxE,6CAA6C;QAC7C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAwB,CAAC,CAAC;IAChF,CAAC;IAED,UAAU,CAAC,OAAe;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC;IACpD,CAAC;CACF"}
|
|
@@ -45,6 +45,52 @@ export interface ApiHandlerDeps {
|
|
|
45
45
|
totalCacheSavingsUsd?: number;
|
|
46
46
|
};
|
|
47
47
|
getCostForDay?: (dayKey: string) => number;
|
|
48
|
+
getSubagentCostForDay?: (dayKey: string) => number;
|
|
49
|
+
getSubagentMetrics?: () => {
|
|
50
|
+
subagentUsd: number;
|
|
51
|
+
parentUsd: number;
|
|
52
|
+
subagentSharePct: number;
|
|
53
|
+
reconciliationDeltaPct: number | null;
|
|
54
|
+
};
|
|
55
|
+
getCostForWorkflowRun?: (runId: string) => number;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Optional reader for the on-disk workflow rollup JSONs and workflow
|
|
59
|
+
* scripts. The dashboard server constructs one from
|
|
60
|
+
* `~/.claude/projects/<slug>/<sessionId>/workflows/` and passes it in.
|
|
61
|
+
* Returns null when the watcher is not enabled.
|
|
62
|
+
*/
|
|
63
|
+
readonly workflowStore?: {
|
|
64
|
+
listRuns: (opts?: {
|
|
65
|
+
since?: number;
|
|
66
|
+
runSource?: string;
|
|
67
|
+
status?: string;
|
|
68
|
+
}) => unknown[];
|
|
69
|
+
getRun: (runId: string) => unknown | null;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Optional reader for per-session subagent timeline spans, backing the
|
|
73
|
+
* "agent fan-out" swimlane chart (GET /api/sessions/:sessionId/subagents).
|
|
74
|
+
* The dashboard server constructs a SubagentTimelineStore and passes it in;
|
|
75
|
+
* absent when the watcher / subagent data is not available, in which case
|
|
76
|
+
* the route 503s via the standard `unavailable` path.
|
|
77
|
+
*
|
|
78
|
+
* `getAgentCalls` backs the attributed session-trace view
|
|
79
|
+
* (GET /api/sessions/:sessionId/subagents/:agentId/calls), returning ONE
|
|
80
|
+
* subagent's individual tool calls. Both methods come off the same
|
|
81
|
+
* SubagentTimelineStore instance so the dashboard tree wiring stays a single
|
|
82
|
+
* dep object.
|
|
83
|
+
*/
|
|
84
|
+
readonly subagentTimeline?: {
|
|
85
|
+
getSubagentsForSession: (sessionId: string) => unknown;
|
|
86
|
+
getAgentCalls: (sessionId: string, agentId: string) => unknown;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Snapshot of latest watcher health frames so the dashboard can render
|
|
90
|
+
* counters without re-reading NR.
|
|
91
|
+
*/
|
|
92
|
+
readonly observabilityHealth?: {
|
|
93
|
+
getSnapshot: () => unknown;
|
|
48
94
|
};
|
|
49
95
|
readonly costForecast?: () => unknown;
|
|
50
96
|
readonly antiPatternDetector?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-handler.d.ts","sourceRoot":"","sources":["../../../src/dashboard/routes/api-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAM5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EAAuB,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"api-handler.d.ts","sourceRoot":"","sources":["../../../src/dashboard/routes/api-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -93,6 +93,47 @@ function toAuditEntry(entry) {
|
|
|
93
93
|
severity: r.securityAlert?.severity,
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
+
function toWorkflowRunDto(row) {
|
|
97
|
+
const r = (row ?? {});
|
|
98
|
+
return {
|
|
99
|
+
runId: r.workflow_run_id,
|
|
100
|
+
parentSessionId: r.parent_session_id,
|
|
101
|
+
taskId: r.task_id ?? null,
|
|
102
|
+
workflowName: r.workflow_name,
|
|
103
|
+
status: r.status,
|
|
104
|
+
errorReason: r.error_reason ?? null,
|
|
105
|
+
defaultModel: r.default_model,
|
|
106
|
+
startedAt: r.started_at,
|
|
107
|
+
durationMs: r.duration_ms,
|
|
108
|
+
agentCount: r.agent_count,
|
|
109
|
+
totalTokens: r.total_tokens,
|
|
110
|
+
totalUsd: r.total_usd ?? null,
|
|
111
|
+
declaredPhases: r.declared_phases ?? null,
|
|
112
|
+
observedPhases: r.observed_phases,
|
|
113
|
+
declaredParallelWidths: r.declared_parallel_widths ?? [],
|
|
114
|
+
tokenReconciliationDelta: r.token_reconciliation_delta,
|
|
115
|
+
incomplete: r.incomplete,
|
|
116
|
+
runSource: r.run_source,
|
|
117
|
+
scriptPath: r.script_path ?? null,
|
|
118
|
+
workflowJsonPath: r.workflow_json_path,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function toWorkflowAgentDto(agent) {
|
|
122
|
+
const a = (agent ?? {});
|
|
123
|
+
return {
|
|
124
|
+
agentId: a.agent_id,
|
|
125
|
+
label: a.label,
|
|
126
|
+
phaseIndex: a.phase_index,
|
|
127
|
+
phaseTitle: a.phase_title,
|
|
128
|
+
model: a.model,
|
|
129
|
+
state: a.state,
|
|
130
|
+
attempt: a.attempt,
|
|
131
|
+
durationMs: a.duration_ms ?? null,
|
|
132
|
+
tokens: a.tokens,
|
|
133
|
+
toolCalls: a.tool_calls,
|
|
134
|
+
startedAt: a.started_at ?? null,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
96
137
|
function jsonOk(res, body) {
|
|
97
138
|
const payload = JSON.stringify(body);
|
|
98
139
|
res.writeHead(200, {
|
|
@@ -752,11 +793,18 @@ export function createApiHandler(deps) {
|
|
|
752
793
|
totalCostUsd += liveTodayUsd;
|
|
753
794
|
}
|
|
754
795
|
else {
|
|
755
|
-
// Fallback for older deployments without per-day API.
|
|
756
|
-
//
|
|
796
|
+
// Fallback for older deployments without the per-day API. NEVER add the
|
|
797
|
+
// full session total here: a session that began before midnight would
|
|
798
|
+
// inflate "spend today" by its entire multi-day cost (observed up to
|
|
799
|
+
// ~4.3x over-counts). Without per-day buckets we cannot pro-rate, so we
|
|
800
|
+
// only attribute a session that actually started today; a cross-midnight
|
|
801
|
+
// session is omitted (a bounded undercount) rather than over-counted.
|
|
757
802
|
const sessionCost = deps.costTracker?.getMetrics().sessionTotalCostUsd ?? null;
|
|
758
|
-
|
|
803
|
+
const startedTs = deps.sessionTracker?.getMetrics().sessionStartTime ?? null;
|
|
804
|
+
const startedToday = typeof startedTs === 'number' && localDateKey(startedTs) === todayKey;
|
|
805
|
+
if (typeof sessionCost === 'number' && startedToday) {
|
|
759
806
|
totalCostUsd += sessionCost;
|
|
807
|
+
}
|
|
760
808
|
}
|
|
761
809
|
}
|
|
762
810
|
// Live session anti-patterns (in-memory, not yet persisted).
|
|
@@ -768,6 +816,24 @@ export function createApiHandler(deps) {
|
|
|
768
816
|
antiPatternCount += live.length;
|
|
769
817
|
}
|
|
770
818
|
const avgDurationMs = durationSamples > 0 ? totalDurationMs / durationSamples : 0;
|
|
819
|
+
// Subagent breakdown for the Today KPI strip. Read directly
|
|
820
|
+
// off the in-memory tracker; if the workflow store is wired, also count
|
|
821
|
+
// workflow runs that started today.
|
|
822
|
+
// Today-scoped subagent spend so the "subagent spend" KPI lines up with the
|
|
823
|
+
// day-bucketed "spend today" (totalCostUsd) above — both are today-only.
|
|
824
|
+
// IMPORTANT: getCostForDay and persisted estimatedCostUsd are already all-in
|
|
825
|
+
// (parent + subagent), so totalCostUsd ALREADY includes subagent cost. This
|
|
826
|
+
// is the breakdown, NOT an addend — do not add it to totalCostUsd.
|
|
827
|
+
const subagentUsd = deps.costTracker?.getSubagentCostForDay?.(localDateKey(now)) ?? 0;
|
|
828
|
+
let subagentTurnCount = 0;
|
|
829
|
+
let workflowRunCount = 0;
|
|
830
|
+
if (deps.workflowStore) {
|
|
831
|
+
const todayRuns = deps.workflowStore.listRuns({ since: startMs });
|
|
832
|
+
workflowRunCount = todayRuns.length;
|
|
833
|
+
for (const r of todayRuns) {
|
|
834
|
+
subagentTurnCount += typeof r.agent_count === 'number' ? r.agent_count : 0;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
771
837
|
const payload = {
|
|
772
838
|
toolCallCount,
|
|
773
839
|
totalCostUsd: Math.round(totalCostUsd * 1000) / 1000,
|
|
@@ -775,10 +841,43 @@ export function createApiHandler(deps) {
|
|
|
775
841
|
avgDurationMs: Math.round(avgDurationMs),
|
|
776
842
|
sessionCount: sessionsSeen.size,
|
|
777
843
|
sparkline: { startTimestamp: startMs, bucketSizeMs: 60_000, points: sparkline },
|
|
844
|
+
subagentUsd: Math.round(subagentUsd * 1000) / 1000,
|
|
845
|
+
subagentTurnCount,
|
|
846
|
+
workflowRunCount,
|
|
778
847
|
};
|
|
779
848
|
aggregateCache = { bucket: currentBucket, payload };
|
|
780
849
|
jsonOk(res, payload);
|
|
781
850
|
});
|
|
851
|
+
// Workflow listing (script-driven runs). Reads the workflow
|
|
852
|
+
// store, which the dashboard server constructs from on-disk wf_*.json
|
|
853
|
+
// files, so dashboards work even when the watcher is disabled.
|
|
854
|
+
routes.set('GET /api/workflows', (req, res) => {
|
|
855
|
+
if (!deps.workflowStore)
|
|
856
|
+
return unavailable(res, 'workflowStore');
|
|
857
|
+
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
858
|
+
const since = url.searchParams.get('since');
|
|
859
|
+
const runSource = url.searchParams.get('run_source') ?? undefined;
|
|
860
|
+
const status = url.searchParams.get('status') ?? undefined;
|
|
861
|
+
let sinceMs;
|
|
862
|
+
if (since) {
|
|
863
|
+
const parsed = parseInt(since, 10);
|
|
864
|
+
if (Number.isFinite(parsed))
|
|
865
|
+
sinceMs = parsed;
|
|
866
|
+
}
|
|
867
|
+
const runs = deps.workflowStore.listRuns({
|
|
868
|
+
since: sinceMs,
|
|
869
|
+
runSource,
|
|
870
|
+
status,
|
|
871
|
+
});
|
|
872
|
+
// Bare array (not { runs }) — the SPA's fetchWorkflows helper feeds this
|
|
873
|
+
// straight into Array.isArray(); a wrapper object renders an empty list.
|
|
874
|
+
jsonOk(res, runs.map(toWorkflowRunDto));
|
|
875
|
+
});
|
|
876
|
+
routes.set('GET /api/observability-health', (_req, res) => {
|
|
877
|
+
if (!deps.observabilityHealth)
|
|
878
|
+
return unavailable(res, 'observabilityHealth');
|
|
879
|
+
jsonOk(res, deps.observabilityHealth.getSnapshot());
|
|
880
|
+
});
|
|
782
881
|
routes.set('GET /api/cost', (_req, res) => {
|
|
783
882
|
if (!deps.costTracker)
|
|
784
883
|
return unavailable(res, 'costTracker');
|
|
@@ -789,7 +888,30 @@ export function createApiHandler(deps) {
|
|
|
789
888
|
// Without it, the client would add persistedTodaySpend to forecastEndOfDayUsd and
|
|
790
889
|
// risk double-counting the live session when its snapshot is already in persisted data.
|
|
791
890
|
const sessionTodayUsd = deps.costTracker.getCostForDay?.(localDateKey(Date.now())) ?? null;
|
|
792
|
-
|
|
891
|
+
// Extend with subagent spend breakdown so the Today view's
|
|
892
|
+
// new "Subagent spend" KPI and stacked HourlyCostBlocks have data without
|
|
893
|
+
// an extra round-trip.
|
|
894
|
+
const subagentMetrics = deps.costTracker.getSubagentMetrics?.() ?? null;
|
|
895
|
+
const subagentUsd = subagentMetrics?.subagentUsd ?? 0;
|
|
896
|
+
const totalUsd = cost.sessionTotalCostUsd ?? 0;
|
|
897
|
+
const parentUsd = subagentMetrics
|
|
898
|
+
? subagentMetrics.parentUsd
|
|
899
|
+
: Math.max(0, totalUsd - subagentUsd);
|
|
900
|
+
const subagentSharePct = subagentMetrics?.subagentSharePct ?? (totalUsd > 0 ? (subagentUsd / totalUsd) * 100 : 0);
|
|
901
|
+
// Reconciliation delta is computed by the watcher self-check; the dashboard
|
|
902
|
+
// reads the latest health snapshot here when available. A stub of `null`
|
|
903
|
+
// is returned when no self-check has run yet so the banner stays hidden.
|
|
904
|
+
const healthSnapshot = deps.observabilityHealth?.getSnapshot();
|
|
905
|
+
const reconciliationDeltaPct = healthSnapshot?.costSelfCheckDeltaPct ?? null;
|
|
906
|
+
jsonOk(res, {
|
|
907
|
+
cost,
|
|
908
|
+
forecast,
|
|
909
|
+
sessionTodayUsd,
|
|
910
|
+
subagentUsd,
|
|
911
|
+
parentUsd,
|
|
912
|
+
subagentSharePct,
|
|
913
|
+
reconciliationDeltaPct,
|
|
914
|
+
});
|
|
793
915
|
});
|
|
794
916
|
routes.set('GET /api/anti-patterns', (_req, res) => {
|
|
795
917
|
if (!deps.antiPatternDetector)
|
|
@@ -1347,13 +1469,74 @@ export function createApiHandler(deps) {
|
|
|
1347
1469
|
});
|
|
1348
1470
|
return async (req, res) => {
|
|
1349
1471
|
try {
|
|
1350
|
-
const
|
|
1472
|
+
const rawPath = (req.url ?? '/').split('?')[0] ?? '/';
|
|
1473
|
+
// Normalize a single trailing slash so `/api/workflows/` resolves to the
|
|
1474
|
+
// same static route as `/api/workflows`. Without this, a trailing-slash
|
|
1475
|
+
// request misses the exact-match static `routes` map AND misses the
|
|
1476
|
+
// workflow-detail regex `^/api/workflows/([…]{1,64})$` (its capture group
|
|
1477
|
+
// requires ≥1 char after the slash), so it fell through to the catch-all
|
|
1478
|
+
// 404 `{error:'not_found'}`. The root path `/` is preserved. Applied to
|
|
1479
|
+
// every route, so detail/replay dynamic matchers also accept a trailing
|
|
1480
|
+
// slash (`/api/sessions/<id>/`).
|
|
1481
|
+
const path = rawPath.length > 1 && rawPath.endsWith('/') ? rawPath.slice(0, -1) : rawPath;
|
|
1351
1482
|
const key = `${req.method ?? 'GET'} ${path}`;
|
|
1352
1483
|
const fn = routes.get(key);
|
|
1353
1484
|
if (fn) {
|
|
1354
1485
|
await fn(req, res);
|
|
1355
1486
|
return;
|
|
1356
1487
|
}
|
|
1488
|
+
// Workflow detail. Allow `wf_<hex>-<hex>` filename runIds
|
|
1489
|
+
// (lowercase letters, digits, hyphens, underscores; capped at 64 chars
|
|
1490
|
+
// to defend against pathological inputs).
|
|
1491
|
+
const workflowDetailMatch = /^\/api\/workflows\/([a-zA-Z0-9_-]{1,64})$/.exec(path);
|
|
1492
|
+
if (req.method === 'GET' && workflowDetailMatch) {
|
|
1493
|
+
const runId = workflowDetailMatch[1];
|
|
1494
|
+
if (!deps.workflowStore)
|
|
1495
|
+
return unavailable(res, 'workflowStore');
|
|
1496
|
+
const run = deps.workflowStore.getRun(runId);
|
|
1497
|
+
if (run === null) {
|
|
1498
|
+
res.writeHead(404, { 'content-type': 'application/json' });
|
|
1499
|
+
res.end(JSON.stringify({ error: 'not_found' }));
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
// Serialize to camelCase so the detail drawer + agent table read real
|
|
1503
|
+
// values instead of rendering every field as `—`. The per-agent rows
|
|
1504
|
+
// only carry an aggregate `tokens` count (no input/output/cache split).
|
|
1505
|
+
const runRow = run;
|
|
1506
|
+
jsonOk(res, {
|
|
1507
|
+
run: toWorkflowRunDto(runRow),
|
|
1508
|
+
agents: (runRow.agents ?? []).map(toWorkflowAgentDto),
|
|
1509
|
+
topology: runRow.topology ?? null,
|
|
1510
|
+
});
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
// ONE subagent's individual tool calls, for the attributed session-trace
|
|
1514
|
+
// view. Matched BEFORE the `/subagents` branch below so the longer,
|
|
1515
|
+
// more-specific path wins (`.../subagents/<agentId>/calls` would also
|
|
1516
|
+
// satisfy the broader matcher's prefix otherwise). Trailing slashes are
|
|
1517
|
+
// already normalized by the dispatcher, so `.../calls/` resolves here too.
|
|
1518
|
+
const subagentCallsMatch = /^\/api\/sessions\/([A-Za-z0-9_-]{1,128})\/subagents\/([a-zA-Z0-9_-]{1,64})\/calls$/.exec(path);
|
|
1519
|
+
if (req.method === 'GET' && subagentCallsMatch) {
|
|
1520
|
+
if (!deps.subagentTimeline)
|
|
1521
|
+
return unavailable(res, 'subagentTimeline');
|
|
1522
|
+
const sessionId = subagentCallsMatch[1];
|
|
1523
|
+
const agentId = subagentCallsMatch[2];
|
|
1524
|
+
jsonOk(res, deps.subagentTimeline.getAgentCalls(sessionId, agentId));
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
// Agent fan-out swimlane data for one session. Dynamic `:sessionId`
|
|
1528
|
+
// route — matched here alongside the other `/api/sessions/:id/...`
|
|
1529
|
+
// branches (and after the workflow-detail branch above). Trailing
|
|
1530
|
+
// slashes are already normalized by the dispatcher, so
|
|
1531
|
+
// `/api/sessions/<id>/subagents/` resolves here too.
|
|
1532
|
+
const subagentsMatch = /^\/api\/sessions\/([A-Za-z0-9_-]{1,128})\/subagents$/.exec(path);
|
|
1533
|
+
if (req.method === 'GET' && subagentsMatch) {
|
|
1534
|
+
if (!deps.subagentTimeline)
|
|
1535
|
+
return unavailable(res, 'subagentTimeline');
|
|
1536
|
+
const sessionId = subagentsMatch[1];
|
|
1537
|
+
jsonOk(res, deps.subagentTimeline.getSubagentsForSession(sessionId));
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1357
1540
|
// Try dynamic routes
|
|
1358
1541
|
const replayMatch = /^\/api\/sessions\/([A-Za-z0-9_-]{1,128})\/replay$/.exec(path);
|
|
1359
1542
|
if (req.method === 'GET' && replayMatch) {
|