elasticdash-test 0.1.13-alpha → 0.1.13-alpha-2

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 (70) hide show
  1. package/README.md +16 -9
  2. package/dist/cli.js +1 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/dashboard-server.d.ts +8 -0
  5. package/dist/dashboard-server.d.ts.map +1 -1
  6. package/dist/dashboard-server.js +229 -1758
  7. package/dist/dashboard-server.js.map +1 -1
  8. package/dist/http.d.ts +9 -0
  9. package/dist/http.d.ts.map +1 -0
  10. package/dist/http.js +9 -0
  11. package/dist/http.js.map +1 -0
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/interceptors/telemetry-push.d.ts +21 -0
  17. package/dist/interceptors/telemetry-push.d.ts.map +1 -0
  18. package/dist/interceptors/telemetry-push.js +56 -0
  19. package/dist/interceptors/telemetry-push.js.map +1 -0
  20. package/dist/interceptors/tool.d.ts.map +1 -1
  21. package/dist/interceptors/tool.js +71 -22
  22. package/dist/interceptors/tool.js.map +1 -1
  23. package/dist/interceptors/workflow-ai.d.ts.map +1 -1
  24. package/dist/interceptors/workflow-ai.js +99 -17
  25. package/dist/interceptors/workflow-ai.js.map +1 -1
  26. package/package.json +15 -2
  27. package/src/browser-ui.ts +281 -0
  28. package/src/capture/event.ts +26 -0
  29. package/src/capture/index.ts +3 -0
  30. package/src/capture/recorder.ts +62 -0
  31. package/src/capture/replay.ts +55 -0
  32. package/src/cli.ts +315 -0
  33. package/src/core/agent-state.ts +162 -0
  34. package/src/core/registry.ts +92 -0
  35. package/src/dashboard-server.ts +1862 -0
  36. package/src/html/dashboard.html +1782 -0
  37. package/src/http.ts +8 -0
  38. package/src/index.ts +32 -0
  39. package/src/interceptors/ai-interceptor.ts +542 -0
  40. package/src/interceptors/db-auto.ts +147 -0
  41. package/src/interceptors/db.ts +81 -0
  42. package/src/interceptors/http.ts +367 -0
  43. package/src/interceptors/side-effects.ts +83 -0
  44. package/src/interceptors/telemetry-push.ts +67 -0
  45. package/src/interceptors/tool.ts +231 -0
  46. package/src/interceptors/workflow-ai.ts +117 -0
  47. package/src/internals/conditional-recorder.ts +63 -0
  48. package/src/internals/mock-resolver.ts +92 -0
  49. package/src/matchers/index.ts +814 -0
  50. package/src/proxy/llm-capture.ts +301 -0
  51. package/src/reporter.ts +81 -0
  52. package/src/runWorkflowSubprocess.ts +74 -0
  53. package/src/runner.ts +178 -0
  54. package/src/test-setup.ts +16 -0
  55. package/src/tool-runner-worker.ts +64 -0
  56. package/src/trace-adapter/context.ts +156 -0
  57. package/src/tracing.ts +62 -0
  58. package/src/types/agent.d.ts +63 -0
  59. package/src/types/expect.d.ts +81 -0
  60. package/src/types/modules.d.ts +2 -0
  61. package/src/workflow-runner-worker.ts +357 -0
  62. package/src/workflow-runner.ts +55 -0
  63. package/dist/internals/async-storage.d.ts +0 -21
  64. package/dist/internals/async-storage.d.ts.map +0 -1
  65. package/dist/internals/async-storage.js +0 -46
  66. package/dist/internals/async-storage.js.map +0 -1
  67. package/dist/internals/node-crypto.d.ts +0 -12
  68. package/dist/internals/node-crypto.d.ts.map +0 -1
  69. package/dist/internals/node-crypto.js +0 -38
  70. package/dist/internals/node-crypto.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/interceptors/tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/interceptors/tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-ai.d.ts","sourceRoot":"","sources":["../../src/interceptors/workflow-ai.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,CAAC,EAC9C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GACpC,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CA0B/B"}
1
+ {"version":3,"file":"workflow-ai.d.ts","sourceRoot":"","sources":["../../src/interceptors/workflow-ai.ts"],"names":[],"mappings":"AAyCA,wBAAgB,MAAM,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,CAAC,EAC9C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GACpC,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAwE/B"}
@@ -1,26 +1,108 @@
1
1
  import { getCaptureContext } from '../capture/recorder.js';
2
+ import { rawDateNow } from './side-effects.js';
3
+ import { getHttpRunContext, getHttpFrozenEvent, pushTelemetryEvent } from './telemetry-push.js';
4
+ function extractUsage(output) {
5
+ if (!output || typeof output !== 'object')
6
+ return undefined;
7
+ const o = output;
8
+ if (o.usage && typeof o.usage === 'object') {
9
+ const u = o.usage;
10
+ // Anthropic SDK: input_tokens / output_tokens
11
+ if (u.input_tokens != null || u.output_tokens != null) {
12
+ return {
13
+ inputTokens: u.input_tokens,
14
+ outputTokens: u.output_tokens,
15
+ totalTokens: (u.input_tokens ?? 0) + (u.output_tokens ?? 0),
16
+ };
17
+ }
18
+ // OpenAI SDK: prompt_tokens / completion_tokens
19
+ if (u.prompt_tokens != null || u.completion_tokens != null) {
20
+ return {
21
+ inputTokens: u.prompt_tokens,
22
+ outputTokens: u.completion_tokens,
23
+ totalTokens: u.total_tokens,
24
+ };
25
+ }
26
+ }
27
+ // Gemini SDK: usageMetadata
28
+ if (o.usageMetadata && typeof o.usageMetadata === 'object') {
29
+ const u = o.usageMetadata;
30
+ return {
31
+ inputTokens: u.promptTokenCount,
32
+ outputTokens: u.candidatesTokenCount,
33
+ totalTokens: u.totalTokenCount,
34
+ };
35
+ }
36
+ return undefined;
37
+ }
2
38
  export function wrapAI(modelName, callFn) {
3
39
  return async (...args) => {
4
40
  const ctx = getCaptureContext();
5
- if (!ctx)
41
+ const httpCtx = getHttpRunContext();
42
+ if (!ctx && !httpCtx)
6
43
  return callFn(...args);
7
- const { recorder, replay } = ctx;
8
- const id = recorder.nextId();
9
- if (replay.shouldReplay(id)) {
10
- return replay.getRecordedResult(id);
44
+ const start = rawDateNow();
45
+ const input = args.length === 1 ? args[0] : args;
46
+ if (ctx) {
47
+ const { recorder, replay } = ctx;
48
+ const id = recorder.nextId();
49
+ if (replay.shouldReplay(id)) {
50
+ return replay.getRecordedResult(id);
51
+ }
52
+ try {
53
+ const output = await callFn(...args);
54
+ const durationMs = rawDateNow() - start;
55
+ const usage = extractUsage(output);
56
+ const event = {
57
+ id, type: 'ai', name: modelName, input, output,
58
+ timestamp: start, durationMs,
59
+ ...(usage ? { usage } : {}),
60
+ };
61
+ recorder.record(event);
62
+ if (httpCtx)
63
+ pushTelemetryEvent(event);
64
+ return output;
65
+ }
66
+ catch (e) {
67
+ const durationMs = rawDateNow() - start;
68
+ const event = {
69
+ id, type: 'ai', name: modelName, input,
70
+ output: { error: String(e) }, timestamp: start, durationMs,
71
+ };
72
+ recorder.record(event);
73
+ if (httpCtx)
74
+ pushTelemetryEvent(event);
75
+ throw e;
76
+ }
77
+ }
78
+ // HTTP mode only (no capture context)
79
+ const id = httpCtx.nextId();
80
+ // Replay frozen step: push historical event so dashboard trace stays complete
81
+ const frozen = getHttpFrozenEvent(id);
82
+ if (frozen) {
83
+ pushTelemetryEvent(frozen);
84
+ return frozen.output;
85
+ }
86
+ try {
87
+ const output = await callFn(...args);
88
+ const durationMs = rawDateNow() - start;
89
+ const usage = extractUsage(output);
90
+ const event = {
91
+ id, type: 'ai', name: modelName, input, output,
92
+ timestamp: start, durationMs,
93
+ ...(usage ? { usage } : {}),
94
+ };
95
+ pushTelemetryEvent(event);
96
+ return output;
97
+ }
98
+ catch (e) {
99
+ const durationMs = rawDateNow() - start;
100
+ pushTelemetryEvent({
101
+ id, type: 'ai', name: modelName, input,
102
+ output: { error: String(e) }, timestamp: start, durationMs,
103
+ });
104
+ throw e;
11
105
  }
12
- const start = Date.now();
13
- const output = await callFn(...args);
14
- recorder.record({
15
- id,
16
- type: 'ai',
17
- name: modelName,
18
- input: args.length === 1 ? args[0] : args,
19
- output,
20
- timestamp: start,
21
- durationMs: Date.now() - start,
22
- });
23
- return output;
24
106
  };
25
107
  }
26
108
  //# sourceMappingURL=workflow-ai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-ai.js","sourceRoot":"","sources":["../../src/interceptors/workflow-ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAE1D,MAAM,UAAU,MAAM,CACpB,SAAiB,EACjB,MAAqC;IAErC,OAAO,KAAK,EAAE,GAAG,IAAU,EAAc,EAAE;QACzC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAA;QAC/B,IAAI,CAAC,GAAG;YAAE,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;QAEhC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAChC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAA;QAE5B,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAM,CAAA;QAC1C,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;QACpC,QAAQ,CAAC,MAAM,CAAC;YACd,EAAE;YACF,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;YACzC,MAAM;YACN,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAC/B,CAAC,CAAA;QAEF,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"workflow-ai.js","sourceRoot":"","sources":["../../src/interceptors/workflow-ai.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elasticdash-test",
3
- "version": "0.1.13-alpha",
3
+ "version": "0.1.13-alpha-2",
4
4
  "description": "AI-native test runner for ElasticDash workflow testing",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,8 +8,21 @@
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./http": {
17
+ "types": "./dist/http.d.ts",
18
+ "default": "./dist/http.js"
19
+ }
20
+ },
11
21
  "files": [
12
- "dist"
22
+ "dist",
23
+ "src",
24
+ "package.json",
25
+ "README.md"
13
26
  ],
14
27
  "scripts": {
15
28
  "build": "node scripts/inline-html.js && tsc && npm run restore:inline-html",
@@ -0,0 +1,281 @@
1
+ import http from 'node:http'
2
+ import path from 'node:path'
3
+ import os from 'node:os'
4
+ import { fileURLToPath } from 'node:url'
5
+ import { spawn } from 'node:child_process'
6
+
7
+ export type UiEvent =
8
+ | { type: 'run-start'; payload: { files: string[] } }
9
+ | { type: 'test-start'; payload: { name: string } }
10
+ | { type: 'test-finish'; payload: { name: string; passed: boolean; durationMs: number; errorMessage?: string } }
11
+ | { type: 'run-summary'; payload: { passed: number; failed: number; total: number; durationMs: number; failures: Array<{ name: string; errorMessage?: string }> } }
12
+
13
+ export interface BrowserUiServer {
14
+ url: string
15
+ send(event: UiEvent): void
16
+ close(): void
17
+ }
18
+
19
+ interface BrowserUiOptions {
20
+ port?: number
21
+ autoOpen?: boolean
22
+ }
23
+
24
+ const defaultHtml = `<!doctype html>
25
+ <html lang="en">
26
+ <head>
27
+ <meta charset="UTF-8" />
28
+ <title>ElasticDash Test Runner</title>
29
+ <style>
30
+ :root { font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0b1021; color: #e8ecf7; }
31
+ body { margin: 0; padding: 24px; }
32
+ h1 { margin: 0 0 16px; font-size: 20px; }
33
+ .summary { display: flex; gap: 12px; margin-bottom: 16px; }
34
+ .pill { padding: 8px 12px; border-radius: 999px; font-weight: 600; }
35
+ .pass { background: #12351b; color: #8de0a3; }
36
+ .fail { background: #351212; color: #f59b9b; }
37
+ .total { background: #1c2745; color: #cdd7ff; }
38
+ .tests { margin-top: 12px; }
39
+ .test { border: 1px solid #1f2a4f; border-radius: 8px; padding: 12px; margin-bottom: 8px; background: #0f1731; }
40
+ .name { font-weight: 600; }
41
+ .error { margin-top: 8px; white-space: pre-wrap; color: #f59b9b; font-family: ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; }
42
+ .status { font-weight: 600; }
43
+ </style>
44
+ </head>
45
+ <body>
46
+ <h1>ElasticDash Test Runner</h1>
47
+ <div class="summary">
48
+ <div class="pill total" id="total">Total: -</div>
49
+ <div class="pill pass" id="passed">Passed: -</div>
50
+ <div class="pill fail" id="failed">Failed: -</div>
51
+ </div>
52
+ <div id="progress">Waiting for test run...</div>
53
+ <div class="tests" id="tests"></div>
54
+ <script>
55
+ const totalEl = document.getElementById('total');
56
+ const passedEl = document.getElementById('passed');
57
+ const failedEl = document.getElementById('failed');
58
+ const progressEl = document.getElementById('progress');
59
+ const testsEl = document.getElementById('tests');
60
+
61
+ const tests = new Map();
62
+ let processed = 0;
63
+ let passedCount = 0;
64
+ let failedCount = 0;
65
+ let finalTotal = null;
66
+
67
+ function setError(el, message) {
68
+ const errEl = el.querySelector('.error');
69
+ let toggle = el.querySelector('.toggle');
70
+ if (!message) {
71
+ errEl.textContent = '';
72
+ errEl.style.display = 'none';
73
+ if (toggle) toggle.style.display = 'none';
74
+ return;
75
+ }
76
+ if (!toggle) {
77
+ toggle = document.createElement('button');
78
+ toggle.className = 'toggle';
79
+ toggle.textContent = 'Show details';
80
+ toggle.style.marginTop = '8px';
81
+ toggle.style.background = '#1c2745';
82
+ toggle.style.color = '#cdd7ff';
83
+ toggle.style.border = '1px solid #2a3866';
84
+ toggle.style.borderRadius = '6px';
85
+ toggle.style.padding = '6px 10px';
86
+ toggle.style.cursor = 'pointer';
87
+ toggle.style.fontWeight = '600';
88
+ el.appendChild(toggle);
89
+ toggle.addEventListener('click', () => {
90
+ const isHidden = errEl.style.display === 'none';
91
+ errEl.style.display = isHidden ? 'block' : 'none';
92
+ toggle.textContent = isHidden ? 'Hide details' : 'Show details';
93
+ });
94
+ }
95
+ errEl.textContent = message;
96
+ errEl.style.display = 'none';
97
+ toggle.style.display = 'inline-block';
98
+ toggle.textContent = 'Show details';
99
+ }
100
+
101
+ function renderTest(name) {
102
+ let el = tests.get(name);
103
+ if (!el) {
104
+ el = document.createElement('div');
105
+ el.className = 'test';
106
+ el.innerHTML = '<div class="name"></div><div class="status"></div><div class="error"></div>';
107
+ tests.set(name, el);
108
+ testsEl.appendChild(el);
109
+ }
110
+ return el;
111
+ }
112
+
113
+ function updatePills(passed, failed, total) {
114
+ totalEl.textContent = 'Total: ' + total;
115
+ passedEl.textContent = 'Passed: ' + passed;
116
+ failedEl.textContent = 'Failed: ' + failed;
117
+ }
118
+
119
+ const evtSource = new EventSource('/events');
120
+ evtSource.onmessage = (ev) => {
121
+ try {
122
+ const msg = JSON.parse(ev.data);
123
+ if (msg.type === 'test-start') {
124
+ const el = renderTest(msg.payload.name);
125
+ el.querySelector('.name').textContent = msg.payload.name;
126
+ el.querySelector('.status').textContent = 'Running...';
127
+ el.querySelector('.status').style.color = '#cdd7ff';
128
+ el.querySelector('.error').textContent = '';
129
+ progressEl.textContent = 'Running tests...';
130
+ }
131
+ if (msg.type === 'test-finish') {
132
+ const el = renderTest(msg.payload.name);
133
+ el.querySelector('.name').textContent = msg.payload.name;
134
+ el.querySelector('.status').textContent = msg.payload.passed ? 'Passed' : 'Failed';
135
+ el.querySelector('.status').style.color = msg.payload.passed ? '#8de0a3' : '#f59b9b';
136
+ setError(el, msg.payload.errorMessage || '');
137
+
138
+ // live tally
139
+ processed += 1;
140
+ if (msg.payload.passed) passedCount += 1;
141
+ else failedCount += 1;
142
+ const displayTotal = finalTotal !== null ? finalTotal : processed;
143
+ updatePills(passedCount, failedCount, displayTotal);
144
+ }
145
+ if (msg.type === 'run-summary') {
146
+ finalTotal = msg.payload.total;
147
+ passedCount = msg.payload.passed;
148
+ failedCount = msg.payload.failed;
149
+ processed = msg.payload.total;
150
+ updatePills(msg.payload.passed, msg.payload.failed, msg.payload.total);
151
+ progressEl.textContent = 'Finished';
152
+ msg.payload.failures.forEach(function (f) {
153
+ const el = renderTest(f.name);
154
+ el.querySelector('.name').textContent = f.name;
155
+ el.querySelector('.status').textContent = 'Failed';
156
+ el.querySelector('.status').style.color = '#f59b9b';
157
+ setError(el, f.errorMessage || '');
158
+ });
159
+ }
160
+ } catch (e) {
161
+ console.error('Bad event data', e);
162
+ }
163
+ };
164
+ </script>
165
+ </body>
166
+ </html>`
167
+
168
+ export async function startBrowserUiServer(opts: BrowserUiOptions = {}): Promise<BrowserUiServer | undefined> {
169
+ const autoOpen = opts.autoOpen !== false
170
+ let port = opts.port ?? 4571
171
+
172
+ // // Ensure base dir for potential static assets (none now)
173
+ // const __dirname = path.dirname(fileURLToPath(import.meta.url))
174
+
175
+ type FlushableResponse = http.ServerResponse & { flush?: () => void; flushHeaders?: () => void }
176
+ const clients: FlushableResponse[] = []
177
+ const eventBuffer: UiEvent[] = []
178
+
179
+ const handler: http.RequestListener = (req, res) => {
180
+ if (!req.url) return res.end()
181
+ if (req.url.startsWith('/events')) {
182
+ const sseRes = res as FlushableResponse
183
+ sseRes.writeHead(200, {
184
+ 'Content-Type': 'text/event-stream',
185
+ Connection: 'keep-alive',
186
+ 'Cache-Control': 'no-cache',
187
+ })
188
+ // Prime the connection so browsers render immediately
189
+ sseRes.flushHeaders?.()
190
+ sseRes.write(': connected\n\n')
191
+ sseRes.flush?.()
192
+ // Replay all previously sent events so late-connecting browsers get the full history
193
+ for (const e of eventBuffer) {
194
+ sseRes.write(`data: ${JSON.stringify(e)}\n\n`)
195
+ }
196
+ sseRes.flush?.()
197
+ clients.push(sseRes)
198
+ req.on('close', () => {
199
+ const idx = clients.indexOf(sseRes)
200
+ if (idx >= 0) clients.splice(idx, 1)
201
+ })
202
+ return
203
+ }
204
+
205
+ // Serve inline HTML
206
+ res.writeHead(200, { 'Content-Type': 'text/html' })
207
+ res.end(defaultHtml)
208
+ }
209
+
210
+ let server: http.Server | undefined
211
+ let heartbeat: ReturnType<typeof setInterval> | undefined
212
+ let started = false
213
+
214
+ while (!started) {
215
+ try {
216
+ server = http.createServer(handler)
217
+ await new Promise<void>((resolve, reject) => {
218
+ server!.once('error', reject)
219
+ server!.listen(port, resolve)
220
+ })
221
+ started = true
222
+ } catch (err) {
223
+ port += 1
224
+ if (port > (opts.port ?? 4571) + 10) {
225
+ console.error('[elasticdash] Browser UI server failed to start:', (err as Error).message)
226
+ return undefined
227
+ }
228
+ }
229
+ }
230
+
231
+ const url = `http://localhost:${port}`
232
+
233
+ function send(event: UiEvent): void {
234
+ eventBuffer.push(event)
235
+ const payload = `data: ${JSON.stringify(event)}\n\n`
236
+ for (const client of [...clients]) {
237
+ client.write(payload)
238
+ client.flush?.()
239
+ }
240
+ }
241
+
242
+ function close(): void {
243
+ if (heartbeat) {
244
+ clearInterval(heartbeat)
245
+ heartbeat = undefined
246
+ }
247
+ for (const client of clients) {
248
+ client.end()
249
+ }
250
+ clients.length = 0
251
+ server?.close()
252
+ }
253
+
254
+ if (autoOpen) {
255
+ openBrowser(url)
256
+ }
257
+
258
+ // Periodic keepalive comments to keep EventSource connections from timing out
259
+ heartbeat = setInterval(() => {
260
+ for (const client of [...clients]) {
261
+ client.write(': keepalive\n\n')
262
+ client.flush?.()
263
+ }
264
+ }, 5000)
265
+
266
+ return { url, send, close }
267
+ }
268
+
269
+ function openBrowser(url: string): void {
270
+ const platform = os.platform()
271
+ const command =
272
+ platform === 'darwin'
273
+ ? 'open'
274
+ : platform === 'win32'
275
+ ? 'cmd'
276
+ : 'xdg-open'
277
+
278
+ const args = platform === 'win32' ? ['/c', 'start', '""', url] : [url]
279
+ const child = spawn(command, args, { stdio: 'ignore', detached: true })
280
+ child.unref()
281
+ }
@@ -0,0 +1,26 @@
1
+ export type WorkflowEventType = 'ai' | 'tool' | 'http' | 'db' | 'side_effect'
2
+
3
+ export interface WorkflowEvent {
4
+ id: number
5
+ type: WorkflowEventType
6
+ name: string
7
+ input: unknown
8
+ output: unknown
9
+ timestamp: number
10
+ durationMs: number
11
+ /** Token usage for LLM (ai) events */
12
+ usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number }
13
+ /** Optional: ID of the agent task that produced this event */
14
+ agentTaskId?: string
15
+ /** Optional: Zero-based index of the agent task that produced this event */
16
+ agentTaskIndex?: number
17
+ /** Set to true when the original response / output was a stream */
18
+ streamed?: boolean
19
+ /** Raw buffered text of a streamed response (used for replay) */
20
+ streamRaw?: string
21
+ }
22
+
23
+ export interface WorkflowTrace {
24
+ traceId: string
25
+ events: WorkflowEvent[]
26
+ }
@@ -0,0 +1,3 @@
1
+ export * from './event.js'
2
+ export * from './recorder.js'
3
+ export * from './replay.js'
@@ -0,0 +1,62 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks'
2
+ import { randomUUID } from 'node:crypto'
3
+ import type { WorkflowEvent, WorkflowTrace } from './event.js'
4
+ import type { ReplayController } from './replay.js'
5
+
6
+ export class TraceRecorder {
7
+ events: WorkflowEvent[] = []
8
+ private _counter = 0
9
+ private _sideEffectCounter = 0
10
+ private _pending: Set<Promise<void>> = new Set()
11
+
12
+ record(event: WorkflowEvent): void {
13
+ this.events.push(event)
14
+ }
15
+
16
+ /** Register an in-flight async recording promise so flush() can await it. */
17
+ trackAsync(promise: Promise<void>): void {
18
+ this._pending.add(promise)
19
+ promise.finally(() => { this._pending.delete(promise) })
20
+ }
21
+
22
+ /** Await all in-flight async recordings. No-op when none are pending. */
23
+ async flush(): Promise<void> {
24
+ await Promise.allSettled([...this._pending])
25
+ }
26
+
27
+ nextId(): number {
28
+ return ++this._counter
29
+ }
30
+
31
+ /** Separate counter for Date.now / Math.random — never shares IDs with main events. */
32
+ nextSideEffectId(): number {
33
+ return ++this._sideEffectCounter
34
+ }
35
+
36
+ toTrace(traceId?: string): WorkflowTrace {
37
+ return {
38
+ traceId: traceId ?? randomUUID(),
39
+ events: [...this.events],
40
+ }
41
+ }
42
+ }
43
+
44
+ export interface CaptureContext {
45
+ recorder: TraceRecorder
46
+ replay: ReplayController
47
+ }
48
+
49
+ const g = globalThis as Record<string, unknown>
50
+ const CAPTURE_ALS_KEY = '__elasticdash_capture_als__'
51
+ const captureAls: AsyncLocalStorage<CaptureContext | undefined> =
52
+ (g[CAPTURE_ALS_KEY] as AsyncLocalStorage<CaptureContext | undefined>) ??
53
+ new AsyncLocalStorage<CaptureContext | undefined>()
54
+ if (!g[CAPTURE_ALS_KEY]) g[CAPTURE_ALS_KEY] = captureAls
55
+
56
+ export function setCaptureContext(ctx: CaptureContext | undefined): void {
57
+ captureAls.enterWith(ctx)
58
+ }
59
+
60
+ export function getCaptureContext(): CaptureContext | undefined {
61
+ return captureAls.getStore()
62
+ }
@@ -0,0 +1,55 @@
1
+ import type { WorkflowEvent } from './event.js'
2
+
3
+ export class ReplayController {
4
+ private historyMap: Map<number, WorkflowEvent>
5
+ /** Side effects keyed by their assigned sideEffectId, independent of main event IDs */
6
+ private sideEffectMap: Map<number, WorkflowEvent>
7
+
8
+ constructor(
9
+ public replayMode: boolean,
10
+ public checkpoint: number,
11
+ public history: WorkflowEvent[],
12
+ ) {
13
+ this.historyMap = new Map(history.map(e => [e.id, e]))
14
+ this.sideEffectMap = new Map(
15
+ history.filter(e => e.type === 'side_effect').map(e => [e.id, e]),
16
+ )
17
+ }
18
+
19
+ shouldReplay(eventId: number): boolean {
20
+ return this.replayMode && eventId <= this.checkpoint
21
+ }
22
+
23
+ getRecordedEvent(eventId: number): WorkflowEvent | undefined {
24
+ return this.historyMap.get(eventId)
25
+ }
26
+
27
+ getRecordedResult(eventId: number): unknown {
28
+ return this.historyMap.get(eventId)?.output
29
+ }
30
+
31
+ /** Returns true if the side effect with this sideEffectId has a recorded value to replay */
32
+ shouldReplaySideEffect(n: number): boolean {
33
+ return this.replayMode && this.sideEffectMap.has(n)
34
+ }
35
+
36
+ getSideEffectResult(n: number): unknown {
37
+ return this.sideEffectMap.get(n)?.output
38
+ }
39
+
40
+ getRecordedSideEffectEvent(n: number): WorkflowEvent | undefined {
41
+ return this.sideEffectMap.get(n)
42
+ }
43
+
44
+ shouldReplaySideEffectOfType(n: number, expectedName: string): boolean {
45
+ if (!this.replayMode) return false
46
+ const event = this.sideEffectMap.get(n)
47
+ return !!event && event.type === 'side_effect' && event.name === expectedName
48
+ }
49
+
50
+ getSideEffectResultOfType(n: number, expectedName: string): unknown {
51
+ const event = this.sideEffectMap.get(n)
52
+ if (!event || event.type !== 'side_effect' || event.name !== expectedName) return undefined
53
+ return event.output
54
+ }
55
+ }