elasticdash-test 0.1.18-alpha-13 → 0.1.18-alpha-15
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.
|
@@ -13,9 +13,9 @@ import 'dotenv/config';
|
|
|
13
13
|
* stdin — one JSON line: { toolsModulePath, toolName, args, frozenEvents? }
|
|
14
14
|
* stdout — prefixed result line: __ELASTICDASH_RESULT__:{...json...}
|
|
15
15
|
*
|
|
16
|
-
* When frozenEvents are provided, sets up an HttpRunContext so that
|
|
17
|
-
*
|
|
18
|
-
* will replay from frozen data instead of hitting real services.
|
|
16
|
+
* When frozenEvents are provided, sets up an HttpRunContext so that all
|
|
17
|
+
* freezable actions within the tool (wrapAI, wrapDB, and fetch-intercepted
|
|
18
|
+
* HTTP calls) will replay from frozen data instead of hitting real services.
|
|
19
19
|
*/
|
|
20
20
|
import { pathToFileURL } from 'node:url';
|
|
21
21
|
const RESULT_PREFIX = '__ELASTICDASH_RESULT__:';
|
|
@@ -27,14 +27,13 @@ function writeResult(result) {
|
|
|
27
27
|
/**
|
|
28
28
|
* Set up frozen event replay context.
|
|
29
29
|
*
|
|
30
|
-
* For HTTP events: uses **URL-based matching** via a fetch wrapper
|
|
31
|
-
*
|
|
32
|
-
* reruns because wrapTool/wrapAI also consume nextId() IDs, causing the
|
|
33
|
-
* sequential counter to drift away from the frozen event IDs.
|
|
30
|
+
* For HTTP events: uses **URL-based matching** via a fetch wrapper, which is
|
|
31
|
+
* robust against ID counter drift.
|
|
34
32
|
*
|
|
35
|
-
* For DB events: uses the HttpRunContext frozen map
|
|
36
|
-
*
|
|
37
|
-
*
|
|
33
|
+
* For AI and DB events: uses the HttpRunContext frozen map with sequential
|
|
34
|
+
* ID-based matching. All freezable event types (AI + DB) are included in the
|
|
35
|
+
* map and re-indexed in original execution order, so the shared nextId()
|
|
36
|
+
* counter stays aligned across interleaved wrapAI and wrapDB calls.
|
|
38
37
|
*/
|
|
39
38
|
async function setupFrozenContext(frozenEvents) {
|
|
40
39
|
if (frozenEvents.length === 0)
|
|
@@ -42,12 +41,17 @@ async function setupFrozenContext(frozenEvents) {
|
|
|
42
41
|
// Always install URL-based fetch replay for HTTP events — this is the
|
|
43
42
|
// reliable matching strategy for tool reruns in subprocesses.
|
|
44
43
|
installFrozenFetchFallback(frozenEvents);
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
// Set up HttpRunContext for all freezable event types (AI + DB).
|
|
45
|
+
// Both wrapAI and wrapDB call httpCtx.nextId() sequentially, so we must
|
|
46
|
+
// include all freezable types in the frozen map, re-indexed in original
|
|
47
|
+
// execution order, to keep the sequential counter aligned.
|
|
48
|
+
const freezableEvents = frozenEvents
|
|
49
|
+
.filter(e => e.type === 'ai' || e.type === 'db')
|
|
50
|
+
.sort((a, b) => a.id - b.id); // preserve original execution order
|
|
51
|
+
if (freezableEvents.length > 0) {
|
|
48
52
|
try {
|
|
49
53
|
const telemetryPush = await import('./interceptors/telemetry-push.js');
|
|
50
|
-
const workflowEvents =
|
|
54
|
+
const workflowEvents = freezableEvents.map((e, i) => ({
|
|
51
55
|
id: i + 1,
|
|
52
56
|
type: e.type,
|
|
53
57
|
name: e.name,
|
|
@@ -67,7 +71,7 @@ async function setupFrozenContext(frozenEvents) {
|
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
catch {
|
|
70
|
-
//
|
|
74
|
+
// Frozen replay not available — tool will hit real services
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
}
|
|
@@ -87,8 +91,11 @@ function restoreFrozenFetch() {
|
|
|
87
91
|
*/
|
|
88
92
|
function installFrozenFetchFallback(frozenEvents) {
|
|
89
93
|
const httpEvents = frozenEvents.filter(e => e.type === 'http');
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
const frozenUrls = httpEvents.map(e => {
|
|
95
|
+
const inp = e.input;
|
|
96
|
+
return inp && typeof inp === 'object' && typeof inp.url === 'string' ? inp.url : '(no url)';
|
|
97
|
+
});
|
|
98
|
+
process.stderr.write(`[elasticdash-worker] Frozen HTTP events: ${httpEvents.length}, URLs: ${JSON.stringify(frozenUrls)}\n`);
|
|
92
99
|
savedOriginalFetch = globalThis.fetch;
|
|
93
100
|
const originalFetch = globalThis.fetch;
|
|
94
101
|
const usageCounts = new Map();
|
|
@@ -104,13 +111,21 @@ function installFrozenFetchFallback(frozenEvents) {
|
|
|
104
111
|
const callCount = usageCounts.get(url) || 0;
|
|
105
112
|
const match = matches[Math.min(callCount, matches.length - 1)];
|
|
106
113
|
usageCounts.set(url, callCount + 1);
|
|
114
|
+
process.stderr.write(`[elasticdash-worker] Frozen replay: ${url}\n`);
|
|
107
115
|
const body = typeof match.output === 'string' ? match.output : JSON.stringify(match.output);
|
|
108
116
|
return new Response(body, {
|
|
109
117
|
status: 200,
|
|
110
118
|
headers: { 'Content-Type': 'application/json', 'X-Frozen': 'true' }
|
|
111
119
|
});
|
|
112
120
|
}
|
|
113
|
-
|
|
121
|
+
process.stderr.write(`[elasticdash-worker] Fetch pass-through (no frozen match): ${url}\n`);
|
|
122
|
+
try {
|
|
123
|
+
return await originalFetch(input, init);
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
process.stderr.write(`[elasticdash-worker] Fetch FAILED for ${url}: ${e.stack || e.message || String(e)}\n`);
|
|
127
|
+
throw e;
|
|
128
|
+
}
|
|
114
129
|
};
|
|
115
130
|
}
|
|
116
131
|
async function main() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-runner-worker.js","sourceRoot":"","sources":["../src/tool-runner-worker.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,CAAC;AAAC,UAAkB,CAAC,sBAAsB,GAAG,IAAI,CAAA;AAElD,iDAAiD;AACjD,OAAO,eAAe,CAAA;AAEtB;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,aAAa,GAAG,yBAAyB,CAAA;AAE/C,SAAS,WAAW,CAAC,MAAe;IAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAC1E,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAC9B,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAcD
|
|
1
|
+
{"version":3,"file":"tool-runner-worker.js","sourceRoot":"","sources":["../src/tool-runner-worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -14,9 +14,9 @@ import 'dotenv/config'
|
|
|
14
14
|
* stdin — one JSON line: { toolsModulePath, toolName, args, frozenEvents? }
|
|
15
15
|
* stdout — prefixed result line: __ELASTICDASH_RESULT__:{...json...}
|
|
16
16
|
*
|
|
17
|
-
* When frozenEvents are provided, sets up an HttpRunContext so that
|
|
18
|
-
*
|
|
19
|
-
* will replay from frozen data instead of hitting real services.
|
|
17
|
+
* When frozenEvents are provided, sets up an HttpRunContext so that all
|
|
18
|
+
* freezable actions within the tool (wrapAI, wrapDB, and fetch-intercepted
|
|
19
|
+
* HTTP calls) will replay from frozen data instead of hitting real services.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { pathToFileURL } from 'node:url'
|
|
@@ -46,14 +46,13 @@ interface FrozenEvent {
|
|
|
46
46
|
/**
|
|
47
47
|
* Set up frozen event replay context.
|
|
48
48
|
*
|
|
49
|
-
* For HTTP events: uses **URL-based matching** via a fetch wrapper
|
|
50
|
-
*
|
|
51
|
-
* reruns because wrapTool/wrapAI also consume nextId() IDs, causing the
|
|
52
|
-
* sequential counter to drift away from the frozen event IDs.
|
|
49
|
+
* For HTTP events: uses **URL-based matching** via a fetch wrapper, which is
|
|
50
|
+
* robust against ID counter drift.
|
|
53
51
|
*
|
|
54
|
-
* For DB events: uses the HttpRunContext frozen map
|
|
55
|
-
*
|
|
56
|
-
*
|
|
52
|
+
* For AI and DB events: uses the HttpRunContext frozen map with sequential
|
|
53
|
+
* ID-based matching. All freezable event types (AI + DB) are included in the
|
|
54
|
+
* map and re-indexed in original execution order, so the shared nextId()
|
|
55
|
+
* counter stays aligned across interleaved wrapAI and wrapDB calls.
|
|
57
56
|
*/
|
|
58
57
|
async function setupFrozenContext(frozenEvents: FrozenEvent[]): Promise<void> {
|
|
59
58
|
if (frozenEvents.length === 0) return
|
|
@@ -62,14 +61,19 @@ async function setupFrozenContext(frozenEvents: FrozenEvent[]): Promise<void> {
|
|
|
62
61
|
// reliable matching strategy for tool reruns in subprocesses.
|
|
63
62
|
installFrozenFetchFallback(frozenEvents)
|
|
64
63
|
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
// Set up HttpRunContext for all freezable event types (AI + DB).
|
|
65
|
+
// Both wrapAI and wrapDB call httpCtx.nextId() sequentially, so we must
|
|
66
|
+
// include all freezable types in the frozen map, re-indexed in original
|
|
67
|
+
// execution order, to keep the sequential counter aligned.
|
|
68
|
+
const freezableEvents = frozenEvents
|
|
69
|
+
.filter(e => e.type === 'ai' || e.type === 'db')
|
|
70
|
+
.sort((a, b) => a.id - b.id) // preserve original execution order
|
|
71
|
+
if (freezableEvents.length > 0) {
|
|
68
72
|
try {
|
|
69
73
|
const telemetryPush = await import('./interceptors/telemetry-push.js')
|
|
70
|
-
const workflowEvents =
|
|
74
|
+
const workflowEvents = freezableEvents.map((e, i) => ({
|
|
71
75
|
id: i + 1,
|
|
72
|
-
type: e.type as 'db',
|
|
76
|
+
type: e.type as 'ai' | 'db',
|
|
73
77
|
name: e.name,
|
|
74
78
|
input: e.input,
|
|
75
79
|
output: e.output,
|
|
@@ -86,7 +90,7 @@ async function setupFrozenContext(frozenEvents: FrozenEvent[]): Promise<void> {
|
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
} catch {
|
|
89
|
-
//
|
|
93
|
+
// Frozen replay not available — tool will hit real services
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
96
|
}
|
|
@@ -109,7 +113,12 @@ function restoreFrozenFetch(): void {
|
|
|
109
113
|
*/
|
|
110
114
|
function installFrozenFetchFallback(frozenEvents: FrozenEvent[]): void {
|
|
111
115
|
const httpEvents = frozenEvents.filter(e => e.type === 'http')
|
|
112
|
-
|
|
116
|
+
|
|
117
|
+
const frozenUrls = httpEvents.map(e => {
|
|
118
|
+
const inp = e.input as Record<string, unknown> | null
|
|
119
|
+
return inp && typeof inp === 'object' && typeof inp.url === 'string' ? inp.url : '(no url)'
|
|
120
|
+
})
|
|
121
|
+
process.stderr.write(`[elasticdash-worker] Frozen HTTP events: ${httpEvents.length}, URLs: ${JSON.stringify(frozenUrls)}\n`)
|
|
113
122
|
|
|
114
123
|
savedOriginalFetch = globalThis.fetch
|
|
115
124
|
const originalFetch = globalThis.fetch
|
|
@@ -130,6 +139,7 @@ function installFrozenFetchFallback(frozenEvents: FrozenEvent[]): void {
|
|
|
130
139
|
const match = matches[Math.min(callCount, matches.length - 1)]
|
|
131
140
|
usageCounts.set(url, callCount + 1)
|
|
132
141
|
|
|
142
|
+
process.stderr.write(`[elasticdash-worker] Frozen replay: ${url}\n`)
|
|
133
143
|
const body = typeof match.output === 'string' ? match.output : JSON.stringify(match.output)
|
|
134
144
|
return new Response(body, {
|
|
135
145
|
status: 200,
|
|
@@ -137,7 +147,13 @@ function installFrozenFetchFallback(frozenEvents: FrozenEvent[]): void {
|
|
|
137
147
|
})
|
|
138
148
|
}
|
|
139
149
|
|
|
140
|
-
|
|
150
|
+
process.stderr.write(`[elasticdash-worker] Fetch pass-through (no frozen match): ${url}\n`)
|
|
151
|
+
try {
|
|
152
|
+
return await originalFetch(input, init)
|
|
153
|
+
} catch (e) {
|
|
154
|
+
process.stderr.write(`[elasticdash-worker] Fetch FAILED for ${url}: ${(e as Error).stack || (e as Error).message || String(e)}\n`)
|
|
155
|
+
throw e
|
|
156
|
+
}
|
|
141
157
|
}
|
|
142
158
|
}
|
|
143
159
|
|