@superblocksteam/vite-plugin-file-sync 2.0.130-next.2 → 2.0.130-next.4
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/ai-service/agent/prompts/build-base-system-prompt.js +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
- package/dist/ai-service/agent/subagents/coding/run-coding-subagent.d.ts +1 -0
- package/dist/ai-service/agent/subagents/coding/run-coding-subagent.d.ts.map +1 -1
- package/dist/ai-service/agent/subagents/coding/run-coding-subagent.js +2 -1
- package/dist/ai-service/agent/subagents/coding/run-coding-subagent.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js +8 -4
- package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts +3 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.js +18 -3
- package/dist/ai-service/agent/tools/build-capture-screenshot.js.map +1 -1
- package/dist/ai-service/agent/tools/build-navigate-preview.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-navigate-preview.js +3 -2
- package/dist/ai-service/agent/tools/build-navigate-preview.js.map +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.js +4 -1
- package/dist/ai-service/agent/tools/build-reload-file.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/delete-integration.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/delete-integration.js +8 -3
- package/dist/ai-service/agent/tools/integrations/delete-integration.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/integration-setup.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/integration-setup.js +26 -14
- package/dist/ai-service/agent/tools/integrations/integration-setup.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/internal.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/internal.js +9 -2
- package/dist/ai-service/agent/tools/integrations/internal.js.map +1 -1
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +12 -9
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.d.ts +8 -0
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.js +7 -5
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.d.ts +8 -0
- package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.js +7 -0
- package/dist/ai-service/agent/tools2/tools/ask-searchable-dropdown.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/bash.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/bash.js +21 -1
- package/dist/ai-service/agent/tools2/tools/bash.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/deploy-service.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/deploy-service.js +43 -11
- package/dist/ai-service/agent/tools2/tools/deploy-service.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts +14 -2
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +67 -40
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/git.d.ts +8 -5
- package/dist/ai-service/agent/tools2/tools/git.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/git.js +36 -7
- package/dist/ai-service/agent/tools2/tools/git.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.js +7 -1
- package/dist/ai-service/agent/tools2/tools/spawn-coding-subagents.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/start-test-run.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/start-test-run.js +4 -1
- package/dist/ai-service/agent/tools2/tools/start-test-run.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/tool-timeout.d.ts +2 -0
- package/dist/ai-service/agent/tools2/tools/tool-timeout.d.ts.map +1 -0
- package/dist/ai-service/agent/tools2/tools/tool-timeout.js +2 -0
- package/dist/ai-service/agent/tools2/tools/tool-timeout.js.map +1 -0
- package/dist/ai-service/agent/tools2/tools/wait-for-task.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/wait-for-task.js +14 -4
- package/dist/ai-service/agent/tools2/tools/wait-for-task.js.map +1 -1
- package/dist/ai-service/agent/tools2/types.d.ts +3 -0
- package/dist/ai-service/agent/tools2/types.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/types.js.map +1 -1
- package/dist/ai-service/app-interface/shell.d.ts +36 -0
- package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
- package/dist/ai-service/app-interface/shell.js +169 -4
- package/dist/ai-service/app-interface/shell.js.map +1 -1
- package/dist/ai-service/app-skills/helpers.d.ts.map +1 -1
- package/dist/ai-service/app-skills/helpers.js +7 -3
- package/dist/ai-service/app-skills/helpers.js.map +1 -1
- package/dist/ai-service/attachments/csv-upload-artifacts.d.ts +35 -0
- package/dist/ai-service/attachments/csv-upload-artifacts.d.ts.map +1 -0
- package/dist/ai-service/attachments/csv-upload-artifacts.js +205 -0
- package/dist/ai-service/attachments/csv-upload-artifacts.js.map +1 -0
- package/dist/ai-service/context-download.d.ts.map +1 -1
- package/dist/ai-service/context-download.js +48 -1
- package/dist/ai-service/context-download.js.map +1 -1
- package/dist/ai-service/context-upload.d.ts.map +1 -1
- package/dist/ai-service/context-upload.js +10 -0
- package/dist/ai-service/context-upload.js.map +1 -1
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +6 -6
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/llm/clark-stream-telemetry-sink.d.ts.map +1 -1
- package/dist/ai-service/llm/clark-stream-telemetry-sink.js +47 -0
- package/dist/ai-service/llm/clark-stream-telemetry-sink.js.map +1 -1
- package/dist/ai-service/llm/client.d.ts.map +1 -1
- package/dist/ai-service/llm/client.js +7 -6
- package/dist/ai-service/llm/client.js.map +1 -1
- package/dist/ai-service/llm/context-v2/context.d.ts +14 -0
- package/dist/ai-service/llm/context-v2/context.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/context.js +51 -1
- package/dist/ai-service/llm/context-v2/context.js.map +1 -1
- package/dist/ai-service/llm/stream/errors.d.ts +8 -0
- package/dist/ai-service/llm/stream/errors.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/errors.js +13 -0
- package/dist/ai-service/llm/stream/errors.js.map +1 -1
- package/dist/ai-service/llm/stream/idle-monitor.d.ts +21 -0
- package/dist/ai-service/llm/stream/idle-monitor.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/idle-monitor.js +62 -0
- package/dist/ai-service/llm/stream/idle-monitor.js.map +1 -1
- package/dist/ai-service/llm/stream/managed-stream.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/managed-stream.js +12 -2
- package/dist/ai-service/llm/stream/managed-stream.js.map +1 -1
- package/dist/ai-service/llm/stream/orchestrator.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/orchestrator.js +252 -17
- package/dist/ai-service/llm/stream/orchestrator.js.map +1 -1
- package/dist/ai-service/llm/stream/retry-engine.d.ts +3 -2
- package/dist/ai-service/llm/stream/retry-engine.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/retry-engine.js +21 -1
- package/dist/ai-service/llm/stream/retry-engine.js.map +1 -1
- package/dist/ai-service/llm/stream/session.d.ts +9 -2
- package/dist/ai-service/llm/stream/session.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/session.js +29 -4
- package/dist/ai-service/llm/stream/session.js.map +1 -1
- package/dist/ai-service/llm/stream/types.d.ts +1 -0
- package/dist/ai-service/llm/stream/types.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +10 -1
- package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js +3 -3
- package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.d.ts +10 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.js +203 -9
- package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/change-info.d.ts +1 -1
- package/dist/ai-service/state-machine/helpers/change-info.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/peer.d.ts +6 -2
- package/dist/ai-service/state-machine/helpers/peer.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/peer.js +47 -11
- package/dist/ai-service/state-machine/helpers/peer.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/stable-peer.d.ts +2 -0
- package/dist/ai-service/state-machine/helpers/stable-peer.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/stable-peer.js +24 -0
- package/dist/ai-service/state-machine/helpers/stable-peer.js.map +1 -1
- package/dist/ai-service/state-machine/mocks.d.ts.map +1 -1
- package/dist/ai-service/state-machine/mocks.js +4 -0
- package/dist/ai-service/state-machine/mocks.js.map +1 -1
- package/dist/ai-service/tasks/task-store.d.ts +1 -1
- package/dist/ai-service/tasks/task-store.d.ts.map +1 -1
- package/dist/ai-service/tasks/task-store.js +10 -1
- package/dist/ai-service/tasks/task-store.js.map +1 -1
- package/dist/ai-service/util/rpc-timeout.d.ts +11 -0
- package/dist/ai-service/util/rpc-timeout.d.ts.map +1 -1
- package/dist/ai-service/util/rpc-timeout.js +13 -0
- package/dist/ai-service/util/rpc-timeout.js.map +1 -1
- package/dist/file-system-helpers.d.ts +13 -0
- package/dist/file-system-helpers.d.ts.map +1 -1
- package/dist/file-system-helpers.js +22 -1
- package/dist/file-system-helpers.js.map +1 -1
- package/dist/sync-service/list-dir.d.ts +1 -1
- package/dist/sync-service/list-dir.js +3 -3
- package/dist/sync-service/list-dir.js.map +1 -1
- package/package.json +8 -8
|
@@ -6,11 +6,16 @@ export class IdleMonitor {
|
|
|
6
6
|
firstChunkTimeoutMs;
|
|
7
7
|
onStallCallback;
|
|
8
8
|
onServerCompactionStart;
|
|
9
|
+
shouldPause;
|
|
10
|
+
onPauseCallback;
|
|
9
11
|
timer = null;
|
|
10
12
|
stallError = null;
|
|
11
13
|
stallCallbacks = [];
|
|
12
14
|
subscribed = false;
|
|
13
15
|
hasReceivedChunk = false;
|
|
16
|
+
// True once a local-wait suppression stretch has fired its onPause event;
|
|
17
|
+
// reset by real activity (chunk/step/retry) so each stretch logs exactly once.
|
|
18
|
+
pausedThisStretch = false;
|
|
14
19
|
compactionTextBlockIds = new Set();
|
|
15
20
|
// The budget snapshot used when the live timer was armed. fireStall() reports
|
|
16
21
|
// this rather than re-resolving, so the logged budget always matches the timer
|
|
@@ -26,6 +31,8 @@ export class IdleMonitor {
|
|
|
26
31
|
options.firstChunkTimeoutMs ?? options.maxIdleTimeMs;
|
|
27
32
|
this.onStallCallback = options.onStall;
|
|
28
33
|
this.onServerCompactionStart = options.onServerCompactionStart;
|
|
34
|
+
this.shouldPause = options.shouldPause;
|
|
35
|
+
this.onPauseCallback = options.onPause;
|
|
29
36
|
}
|
|
30
37
|
resolveBudget(budget) {
|
|
31
38
|
return typeof budget === "function" ? budget() : budget;
|
|
@@ -51,6 +58,7 @@ export class IdleMonitor {
|
|
|
51
58
|
start() {
|
|
52
59
|
this.stallError = null;
|
|
53
60
|
this.hasReceivedChunk = false;
|
|
61
|
+
this.pausedThisStretch = false;
|
|
54
62
|
this.compactionTextBlockIds.clear();
|
|
55
63
|
this.session.resetActivityTimer();
|
|
56
64
|
this.subscribeToEvents();
|
|
@@ -109,12 +117,14 @@ export class IdleMonitor {
|
|
|
109
117
|
}
|
|
110
118
|
this.stallError = null;
|
|
111
119
|
this.stallCallbacks = [];
|
|
120
|
+
this.pausedThisStretch = false;
|
|
112
121
|
this.armTimer();
|
|
113
122
|
};
|
|
114
123
|
handleStepStart = () => {
|
|
115
124
|
this.hasReceivedChunk = false;
|
|
116
125
|
this.compactionTextBlockIds.clear();
|
|
117
126
|
this.stallError = null;
|
|
127
|
+
this.pausedThisStretch = false;
|
|
118
128
|
this.session.resetActivityTimer();
|
|
119
129
|
this.armTimer();
|
|
120
130
|
};
|
|
@@ -123,6 +133,7 @@ export class IdleMonitor {
|
|
|
123
133
|
this.compactionTextBlockIds.clear();
|
|
124
134
|
this.stallError = null;
|
|
125
135
|
this.stallCallbacks = [];
|
|
136
|
+
this.pausedThisStretch = false;
|
|
126
137
|
this.session.resetActivityTimer();
|
|
127
138
|
this.armTimer();
|
|
128
139
|
};
|
|
@@ -164,8 +175,59 @@ export class IdleMonitor {
|
|
|
164
175
|
if (!this.session.isPending()) {
|
|
165
176
|
return;
|
|
166
177
|
}
|
|
178
|
+
// The timer fired on a wall-clock budget, but the gap may be local work —
|
|
179
|
+
// a running tool, a step boundary, or the consumer holding the stream —
|
|
180
|
+
// rather than the provider going silent. Re-check at fire time (state can
|
|
181
|
+
// flip between arming and firing): if we're in a local wait, leave
|
|
182
|
+
// stallError null and any waitForStall() promise pending, and just re-arm
|
|
183
|
+
// so the managed stream stays blocked on the same upstream read instead of
|
|
184
|
+
// surfacing a useless provider retry. A genuine provider silence that
|
|
185
|
+
// follows the local wait still fires on a later tick. See APPS-4605.
|
|
186
|
+
//
|
|
187
|
+
// There is no cap on how long this can keep re-arming: a healthy slow tool
|
|
188
|
+
// is allowed to run for as long as it takes. A tool that hangs forever is
|
|
189
|
+
// bounded externally instead — the parent abortSignal (the dev server
|
|
190
|
+
// request's own timeout / the user navigating away) cascades to
|
|
191
|
+
// "session:abort", which stops the monitor and tears the stream down. The
|
|
192
|
+
// onPause event below makes the long wait observable while it is happening.
|
|
193
|
+
//
|
|
194
|
+
// Guard the callback like the others below: fireStall() runs from a
|
|
195
|
+
// setTimeout, so a throw here would escape as an unhandled exception, the
|
|
196
|
+
// timer would never re-arm, and stall detection would be dead for the rest
|
|
197
|
+
// of the session. On error, fall through and fire the stall — a real stall
|
|
198
|
+
// surfacing is safer than one being silently swallowed.
|
|
199
|
+
let shouldPause = false;
|
|
200
|
+
try {
|
|
201
|
+
shouldPause = this.shouldPause?.() ?? false;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// A shouldPause failure must not break stall monitoring.
|
|
205
|
+
}
|
|
206
|
+
if (shouldPause) {
|
|
207
|
+
// Emit one onPause event at the start of each suppression stretch so a
|
|
208
|
+
// long local wait (e.g. a tool that never returns) is observable, without
|
|
209
|
+
// logging on every re-arm. The flag clears on the next real chunk/step/
|
|
210
|
+
// retry, so a later stuck stretch emits again.
|
|
211
|
+
if (!this.pausedThisStretch) {
|
|
212
|
+
this.pausedThisStretch = true;
|
|
213
|
+
try {
|
|
214
|
+
this.onPauseCallback?.();
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// A callback/logging failure must not break stall monitoring.
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
this.armTimer();
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
167
223
|
const idleTime = this.session.getTimeSinceLastActivity();
|
|
168
224
|
this.stallError = new StallTimeoutError(idleTime, this.armedBudget.timeoutMs, this.armedBudget.budgetKind);
|
|
225
|
+
// Invariant: run onStallCallback before resolving stallCallbacks. Both are
|
|
226
|
+
// synchronous, so both observe session state as it was at the instant of
|
|
227
|
+
// the stall — before the rejected waitForStall() promise propagates (a
|
|
228
|
+
// microtask) into the managed stream's catch and mutates that state. The
|
|
229
|
+
// stall_reason classifier (orchestrator onStall) relies on this to read
|
|
230
|
+
// session.isAwaitingUpstream() while it still reflects the stalled await.
|
|
169
231
|
try {
|
|
170
232
|
this.onStallCallback?.(this.stallError);
|
|
171
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idle-monitor.js","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/idle-monitor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAwB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"idle-monitor.js","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/idle-monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-stream.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/managed-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAE9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAE9C,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,WAAW,GACvB,mBAAmB,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"managed-stream.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/managed-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAE9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAE9C,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,WAAW,GACvB,mBAAmB,CAAC,CAAC,CAAC,CAkIxB"}
|
|
@@ -31,7 +31,6 @@ export function createManagedStream(source, session, idleMonitor) {
|
|
|
31
31
|
controller.close();
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
-
session.recordPull();
|
|
35
34
|
// Loop over raw chunks (provider SSE keep-alives / message metadata):
|
|
36
35
|
// these exist only to feed IdleMonitor during thinking silences so the
|
|
37
36
|
// watchdog doesn't stall a healthy stream. For each raw chunk we:
|
|
@@ -51,7 +50,17 @@ export function createManagedStream(source, session, idleMonitor) {
|
|
|
51
50
|
// chunk arrives. See APPS-3460.
|
|
52
51
|
while (true) {
|
|
53
52
|
try {
|
|
53
|
+
// Stamp each iteration so ms_since_last_pull stays fresh across
|
|
54
|
+
// keep-alive loops for stall-log triage.
|
|
55
|
+
session.recordPull();
|
|
56
|
+
// We are now blocked on upstream. If the idle monitor fires while
|
|
57
|
+
// this await is pending, the stall is "network-dark"; once a chunk
|
|
58
|
+
// arrives and we hand off to the consumer, a subsequent stall is
|
|
59
|
+
// "consumer-blocked" (the consumer is holding the stream without
|
|
60
|
+
// pulling). See orchestrator onStall + session.isAwaitingUpstream.
|
|
61
|
+
session.setAwaitingUpstream(true);
|
|
54
62
|
const result = await raceWithStallDetection(iterator.next(), idleMonitor);
|
|
63
|
+
session.setAwaitingUpstream(false);
|
|
55
64
|
if (result.done) {
|
|
56
65
|
closed = true;
|
|
57
66
|
session.finalize("complete");
|
|
@@ -101,12 +110,13 @@ export function createManagedStream(source, session, idleMonitor) {
|
|
|
101
110
|
controller.error(chunkError);
|
|
102
111
|
return;
|
|
103
112
|
}
|
|
104
|
-
session.recordChunk();
|
|
113
|
+
session.recordChunk(result.value.type);
|
|
105
114
|
void session.events.emit("chunk", result.value, session);
|
|
106
115
|
controller.enqueue(result.value);
|
|
107
116
|
return;
|
|
108
117
|
}
|
|
109
118
|
catch (error) {
|
|
119
|
+
session.setAwaitingUpstream(false);
|
|
110
120
|
closed = true;
|
|
111
121
|
// no finalization, let wrapWithRetry handle it
|
|
112
122
|
controller.error(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-stream.js","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/managed-stream.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAIhF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CAGjC,MAA8B,EAC9B,OAAsB,EACtB,WAAwB;IAExB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;IAChD,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjD,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAI;QACrC,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;gBACnC,UAAU,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;
|
|
1
|
+
{"version":3,"file":"managed-stream.js","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/managed-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/orchestrator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/stream/orchestrator.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,MAAM,EACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,MAAM,6BAA6B,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAC1E,iBAAiB,CAAC,KAAK,CAAC,GAAG;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AA+NJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA2B;gBAEvC,OAAO,EAAE,yBAAyB;IAUxC,OAAO,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC9C,OAAO,EAAE,6BAA6B,CAAC,KAAK,CAAC,GAC5C,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IA2SnC,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,wBAAwB;IAiChC;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAuErB;;;OAGG;YACW,mBAAmB;YA6EnB,oBAAoB;IAuElC,OAAO,CAAC,cAAc;YA6BR,WAAW;IAkFzB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAsC5B,OAAO,CAAC,aAAa;IA2DrB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAuE9B,OAAO,CAAC,iBAAiB;IAQzB;;;;;;;OAOG;YACW,cAAc;IAuC5B,OAAO,CAAC,KAAK;CAmBd"}
|
|
@@ -1,13 +1,142 @@
|
|
|
1
|
+
import { metrics } from "@opentelemetry/api";
|
|
1
2
|
import { getErrorMeta, } from "../../../util/logger.js";
|
|
2
3
|
import { buildThinkingProviderOptions } from "../../util/llm-config-utils.js";
|
|
3
4
|
import { LLMProviderError } from "../error.js";
|
|
4
5
|
import { getServerCompactionTextBlockUpdate } from "./compaction-text-block.js";
|
|
5
|
-
import { AbortedError, RetriesExhaustedError } from "./errors.js";
|
|
6
|
+
import { AbortedError, RetriesExhaustedError, ToolExecutionTimeoutError, } from "./errors.js";
|
|
6
7
|
import { IdleMonitor } from "./idle-monitor.js";
|
|
7
8
|
import { createManagedStream } from "./managed-stream.js";
|
|
8
9
|
import { RetryEngine } from "./retry-engine.js";
|
|
9
10
|
import { StreamSession } from "./session.js";
|
|
10
11
|
import { WaitStateTracker } from "./wait-state-tracker.js";
|
|
12
|
+
const DEFAULT_TOOL_EXECUTION_TIMEOUT_MS = 60_000;
|
|
13
|
+
const METER_NAME = "superblocks.clark.tool_execution";
|
|
14
|
+
const TOOL_EXECUTION_TIMEOUTS_METRIC = "superblocks.clark.tool.execution.timeouts_total";
|
|
15
|
+
const TOOL_EXECUTION_DURATION_METRIC = "superblocks.clark.tool.execution.duration_seconds";
|
|
16
|
+
let cachedMeter;
|
|
17
|
+
let cachedMetrics;
|
|
18
|
+
function resolveToolExecutionMetrics() {
|
|
19
|
+
const meter = metrics.getMeter(METER_NAME);
|
|
20
|
+
if (meter === cachedMeter && cachedMetrics) {
|
|
21
|
+
return cachedMetrics;
|
|
22
|
+
}
|
|
23
|
+
cachedMeter = meter;
|
|
24
|
+
cachedMetrics = {
|
|
25
|
+
durationHistogram: meter.createHistogram(TOOL_EXECUTION_DURATION_METRIC, {
|
|
26
|
+
description: "Duration of Clark tool executions guarded by the stream orchestrator.",
|
|
27
|
+
unit: "s",
|
|
28
|
+
}),
|
|
29
|
+
timeoutCounter: meter.createCounter(TOOL_EXECUTION_TIMEOUTS_METRIC, {
|
|
30
|
+
description: "Number of Clark tool executions that reached their orchestrator timeout.",
|
|
31
|
+
unit: "{timeout}",
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
return cachedMetrics;
|
|
35
|
+
}
|
|
36
|
+
function recordToolExecutionDuration(toolName, outcome, durationMs) {
|
|
37
|
+
resolveToolExecutionMetrics().durationHistogram.record(durationMs / 1000, {
|
|
38
|
+
outcome,
|
|
39
|
+
tool_name: toolName,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function recordToolExecutionTimeout(toolName) {
|
|
43
|
+
resolveToolExecutionMetrics().timeoutCounter.add(1, {
|
|
44
|
+
tool_name: toolName,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function getToolExecutionTimeoutMs(tool) {
|
|
48
|
+
// Treat non-positive, non-finite, or absent values as "use default".
|
|
49
|
+
return typeof tool.timeoutMs === "number" &&
|
|
50
|
+
Number.isFinite(tool.timeoutMs) &&
|
|
51
|
+
tool.timeoutMs > 0
|
|
52
|
+
? tool.timeoutMs
|
|
53
|
+
: DEFAULT_TOOL_EXECUTION_TIMEOUT_MS;
|
|
54
|
+
}
|
|
55
|
+
async function executeToolWithTimeout(name, tool, execute, input, executeOptions, logger) {
|
|
56
|
+
const timeoutMs = getToolExecutionTimeoutMs(tool);
|
|
57
|
+
const startedAtMs = Date.now();
|
|
58
|
+
const baseAttributes = {
|
|
59
|
+
timeout_ms: timeoutMs,
|
|
60
|
+
tool_call_id: executeOptions.toolCallId,
|
|
61
|
+
tool_name: name,
|
|
62
|
+
};
|
|
63
|
+
let timeoutId;
|
|
64
|
+
const toolAbortController = new AbortController();
|
|
65
|
+
const parentAbortSignal = executeOptions.abortSignal;
|
|
66
|
+
let removeParentAbortListener;
|
|
67
|
+
if (parentAbortSignal?.aborted) {
|
|
68
|
+
toolAbortController.abort();
|
|
69
|
+
}
|
|
70
|
+
else if (parentAbortSignal) {
|
|
71
|
+
const onParentAbort = () => toolAbortController.abort();
|
|
72
|
+
parentAbortSignal.addEventListener("abort", onParentAbort, { once: true });
|
|
73
|
+
removeParentAbortListener = () => parentAbortSignal.removeEventListener("abort", onParentAbort);
|
|
74
|
+
}
|
|
75
|
+
const timeout = new Promise((_, reject) => {
|
|
76
|
+
timeoutId = setTimeout(() => {
|
|
77
|
+
toolAbortController.abort();
|
|
78
|
+
reject(new ToolExecutionTimeoutError(name, timeoutMs, input));
|
|
79
|
+
}, timeoutMs);
|
|
80
|
+
});
|
|
81
|
+
const optionsWithTimeoutSignal = {
|
|
82
|
+
...executeOptions,
|
|
83
|
+
abortSignal: toolAbortController.signal,
|
|
84
|
+
};
|
|
85
|
+
logger.info("[orchestrator] Tool execution started", {
|
|
86
|
+
...baseAttributes,
|
|
87
|
+
event: "clark_tool_execution_start",
|
|
88
|
+
});
|
|
89
|
+
try {
|
|
90
|
+
const result = await Promise.race([
|
|
91
|
+
execute(input, optionsWithTimeoutSignal),
|
|
92
|
+
timeout,
|
|
93
|
+
]);
|
|
94
|
+
const durationMs = Date.now() - startedAtMs;
|
|
95
|
+
recordToolExecutionDuration(name, "success", durationMs);
|
|
96
|
+
logger.info("[orchestrator] Tool execution completed", {
|
|
97
|
+
...baseAttributes,
|
|
98
|
+
duration_ms: durationMs,
|
|
99
|
+
event: "clark_tool_execution_complete",
|
|
100
|
+
});
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
const durationMs = Date.now() - startedAtMs;
|
|
105
|
+
const outcome = error instanceof ToolExecutionTimeoutError ? "timeout" : "error";
|
|
106
|
+
recordToolExecutionDuration(name, outcome, durationMs);
|
|
107
|
+
if (error instanceof ToolExecutionTimeoutError) {
|
|
108
|
+
recordToolExecutionTimeout(name);
|
|
109
|
+
}
|
|
110
|
+
const attributes = {
|
|
111
|
+
...baseAttributes,
|
|
112
|
+
duration_ms: durationMs,
|
|
113
|
+
error_kind: error instanceof Error ? error.name : "unknown",
|
|
114
|
+
event: error instanceof ToolExecutionTimeoutError
|
|
115
|
+
? "clark_tool_execution_timeout"
|
|
116
|
+
: "clark_tool_execution_error",
|
|
117
|
+
};
|
|
118
|
+
if (error instanceof ToolExecutionTimeoutError) {
|
|
119
|
+
logger.warn("[orchestrator] Tool execution timed out", attributes);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
logger.warn("[orchestrator] Tool execution failed", attributes);
|
|
123
|
+
logger.error("[orchestrator] Tool execution failed", {
|
|
124
|
+
...attributes,
|
|
125
|
+
error: {
|
|
126
|
+
kind: error instanceof Error ? error.name : "unknown",
|
|
127
|
+
message: "Tool execution failed; raw error details omitted",
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
removeParentAbortListener?.();
|
|
135
|
+
if (timeoutId) {
|
|
136
|
+
clearTimeout(timeoutId);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
11
140
|
/**
|
|
12
141
|
* Tracks the in-flight provider attempt for a single execute() call so a
|
|
13
142
|
* superseded attempt can be cut off the instant we decide to retry.
|
|
@@ -175,6 +304,91 @@ export class StreamOrchestrator {
|
|
|
175
304
|
firstChunkTimeoutMs: this.config.retry.budgetForModel(session.provider.model).firstChunkTimeoutMs,
|
|
176
305
|
});
|
|
177
306
|
},
|
|
307
|
+
shouldPause: () => {
|
|
308
|
+
// Reads only plain in-memory state, so it should never throw. Guard it
|
|
309
|
+
// anyway and log if it does: a silent failure here would let a false
|
|
310
|
+
// stall through and rotate the provider — the exact bug this prevents —
|
|
311
|
+
// with no signal for oncall to find it. On error, return false so the
|
|
312
|
+
// stall still fires (failing safe toward surfacing a real stall).
|
|
313
|
+
try {
|
|
314
|
+
// Only a genuine wait on the provider's next byte should count toward
|
|
315
|
+
// a stall. If a tool is running or we're between steps, the gap is
|
|
316
|
+
// local work — not the model going silent — so pause instead of
|
|
317
|
+
// firing a false stall that would pointlessly rotate providers. See
|
|
318
|
+
// APPS-4605.
|
|
319
|
+
const waitState = waitStateTracker.getWaitState();
|
|
320
|
+
if (waitState.state === "tool" ||
|
|
321
|
+
waitState.state === "step-boundary") {
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
// isAwaitingUpstream() is true only while the managed stream is
|
|
325
|
+
// blocked waiting for the provider's next chunk. False means the
|
|
326
|
+
// consumer took a chunk and hasn't asked for the next one yet (e.g.
|
|
327
|
+
// it's busy on its own downstream call), so the silence is on the
|
|
328
|
+
// consumer's side, not the provider's. Require at least one chunk to
|
|
329
|
+
// have arrived first: before that the gap is real provider silence
|
|
330
|
+
// (and the flag may not be set yet because the read happens lazily),
|
|
331
|
+
// so it must never be mistaken for the consumer holding the stream.
|
|
332
|
+
//
|
|
333
|
+
// Trade-off: if the provider connection drops while the consumer is
|
|
334
|
+
// holding a chunk, the dead connection is invisible until the
|
|
335
|
+
// consumer pulls again, since we suppress the stall for the whole
|
|
336
|
+
// consumer-hold window. That is acceptable because a slow consumer is
|
|
337
|
+
// the intended case and the consumer (the dev server request) carries
|
|
338
|
+
// its own request timeout that aborts the stream if it never resumes.
|
|
339
|
+
return (!session.isAwaitingUpstream() && session.metrics.chunkCount > 0);
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
this.logger.error("[orchestrator] shouldPause check failed", {
|
|
343
|
+
error: {
|
|
344
|
+
kind: err instanceof Error ? err.name : "unknown",
|
|
345
|
+
message: err instanceof Error ? err.message : String(err),
|
|
346
|
+
stack: err instanceof Error ? err.stack : undefined,
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
onPause: () => {
|
|
353
|
+
// One structured event at the start of each local-wait stretch (a tool
|
|
354
|
+
// running, a step gap, or the consumer holding the stream past the idle
|
|
355
|
+
// budget). No stream_stall fires for these, so without this a hung tool
|
|
356
|
+
// would be invisible to the stream layer until the request aborts. The
|
|
357
|
+
// idle monitor fires this once per stretch, so a healthy slow tool logs
|
|
358
|
+
// once, not once per re-arm. See APPS-4605.
|
|
359
|
+
const waitState = waitStateTracker.getWaitState();
|
|
360
|
+
const message = `[orchestrator] Local wait suppressed idle stall`;
|
|
361
|
+
const attributes = {
|
|
362
|
+
event: "stream_local_wait",
|
|
363
|
+
session_id: session.id,
|
|
364
|
+
provider: session.provider.name,
|
|
365
|
+
model: session.provider.model,
|
|
366
|
+
attempt: session.attempt,
|
|
367
|
+
elapsed_ms: session.getElapsedMs(),
|
|
368
|
+
chunks_received: session.metrics.chunkCount,
|
|
369
|
+
// "tool"/"step-boundary" come from the wait tracker; "consumer" is the
|
|
370
|
+
// remaining case (consumer holding the stream), which the tracker
|
|
371
|
+
// reports as "provider" since it does not track consumer-pull state.
|
|
372
|
+
wait_state: waitState.state === "provider" ? "consumer" : waitState.state,
|
|
373
|
+
};
|
|
374
|
+
if (waitState.state === "tool") {
|
|
375
|
+
attributes.tool_name = waitState.toolName;
|
|
376
|
+
attributes.tool_call_id = waitState.toolCallId;
|
|
377
|
+
attributes.pending_tool_count = waitState.pendingToolCount;
|
|
378
|
+
}
|
|
379
|
+
if (session.organizationId) {
|
|
380
|
+
attributes.organization_id = session.organizationId;
|
|
381
|
+
}
|
|
382
|
+
if (session.applicationId) {
|
|
383
|
+
attributes.application_id = session.applicationId;
|
|
384
|
+
}
|
|
385
|
+
if (this.logger.warnStructured) {
|
|
386
|
+
this.logger.warnStructured(message, attributes);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
this.logger.warn(message, attributes);
|
|
390
|
+
}
|
|
391
|
+
},
|
|
178
392
|
onStall: (error) => {
|
|
179
393
|
// budgetKind is the keepalive-vs-content discriminator: "first-chunk"
|
|
180
394
|
// means the model never sent content (only silence/keep-alives) before
|
|
@@ -182,6 +396,27 @@ export class StreamOrchestrator {
|
|
|
182
396
|
// It is carried on the error (set when the timer armed) because budgets
|
|
183
397
|
// are now per-model and can't be re-derived by numeric comparison.
|
|
184
398
|
const budgetKind = error.budgetKind;
|
|
399
|
+
const msSinceLastPull = session.getTimeSinceLastPull();
|
|
400
|
+
// Discriminate network-dark vs consumer-blocked (APPS-4729). The
|
|
401
|
+
// managed stream flips isAwaitingUpstream() around its
|
|
402
|
+
// `await iterator.next()`: true means the stall fired while we were
|
|
403
|
+
// blocked reading upstream (the wire went dark); false means the
|
|
404
|
+
// consumer is holding the stream without pulling (e.g. blocked on a
|
|
405
|
+
// downstream RPC). A boolean rather than an ms_since_last_pull
|
|
406
|
+
// comparison, which is unreliable near the idle-budget boundary. The
|
|
407
|
+
// flag read here is consistent because IdleMonitor runs this onStall
|
|
408
|
+
// callback synchronously, before the rejected waitForStall() propagates
|
|
409
|
+
// into the managed stream's catch and clears the flag (see idle-monitor).
|
|
410
|
+
//
|
|
411
|
+
// A first-chunk stall is upstream silence by definition: no chunk was
|
|
412
|
+
// delivered, so the consumer cannot be holding the stream. Force
|
|
413
|
+
// "network-dark" rather than trusting the flag — pull() is lazy, so a
|
|
414
|
+
// first-chunk timer can fire before the loop's first await ever set it.
|
|
415
|
+
// budget_kind still separates a first-chunk network-dark from an
|
|
416
|
+
// inter-chunk one.
|
|
417
|
+
const stallReason = budgetKind === "first-chunk" || session.isAwaitingUpstream()
|
|
418
|
+
? "network-dark"
|
|
419
|
+
: "consumer-blocked";
|
|
185
420
|
const message = `[orchestrator] Idle timeout exceeded, triggering retry`;
|
|
186
421
|
// Emit as structured attributes (OTel log attributes -> Datadog facets)
|
|
187
422
|
// so stalls are queryable by provider/model/attempt and chartable,
|
|
@@ -190,7 +425,6 @@ export class StreamOrchestrator {
|
|
|
190
425
|
// awaiting-user.ts). budget_ms + budget_kind already capture which idle
|
|
191
426
|
// budget applied and its value, so the static config constants are not
|
|
192
427
|
// re-emitted per stall. See APPS-4643.
|
|
193
|
-
const msSinceLastPull = session.getTimeSinceLastPull();
|
|
194
428
|
// wait_state says what the stall was stuck on: "provider" = the model
|
|
195
429
|
// went silent, "tool" = a local tool was still running (a slow tool,
|
|
196
430
|
// not the model), "step-boundary" = it was between steps.
|
|
@@ -210,6 +444,7 @@ export class StreamOrchestrator {
|
|
|
210
444
|
budget_ms: error.maxIdleTimeMs,
|
|
211
445
|
elapsed_ms: session.getElapsedMs(),
|
|
212
446
|
chunks_received: session.metrics.chunkCount,
|
|
447
|
+
stall_reason: stallReason,
|
|
213
448
|
wait_state: waitState.state,
|
|
214
449
|
raw_reset_count: waitStateTracker.getRawResetCount(),
|
|
215
450
|
};
|
|
@@ -218,9 +453,9 @@ export class StreamOrchestrator {
|
|
|
218
453
|
attributes.tool_call_id = waitState.toolCallId;
|
|
219
454
|
attributes.pending_tool_count = waitState.pendingToolCount;
|
|
220
455
|
}
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
//
|
|
456
|
+
// Supporting numeric signal: how long since the consumer last pulled.
|
|
457
|
+
// stall_reason is the primary discriminator; this aids triage. Absent
|
|
458
|
+
// when the consumer never made a productive pull.
|
|
224
459
|
if (msSinceLastPull !== undefined) {
|
|
225
460
|
attributes.ms_since_last_pull = msSinceLastPull;
|
|
226
461
|
}
|
|
@@ -240,13 +475,13 @@ export class StreamOrchestrator {
|
|
|
240
475
|
}
|
|
241
476
|
},
|
|
242
477
|
});
|
|
243
|
-
const result = await this.startStreamWithRetry(optionsWithAbort, session, retryEngine, attempts);
|
|
478
|
+
const result = await this.startStreamWithRetry(optionsWithAbort, session, retryEngine, attempts, waitStateTracker);
|
|
244
479
|
// Start monitoring now that the stream is active
|
|
245
480
|
idleMonitor.start();
|
|
246
481
|
// wrapper order matters here. managed stream throws errors (error chunks), retry wrapper catches them.
|
|
247
482
|
// Pass the idle monitor so it can interrupt hung streams.
|
|
248
483
|
const managedStream = createManagedStream(result.fullStream, session, idleMonitor);
|
|
249
|
-
const retryableFullStream = this.wrapWithRetry(managedStream, (r) => createManagedStream(r.fullStream, session, idleMonitor), optionsWithAbort, session, retryEngine, internalAbortController, attempts);
|
|
484
|
+
const retryableFullStream = this.wrapWithRetry(managedStream, (r) => createManagedStream(r.fullStream, session, idleMonitor), optionsWithAbort, session, retryEngine, internalAbortController, attempts, waitStateTracker);
|
|
250
485
|
// `tee()` preserves the public contract that fullStream and textStream can
|
|
251
486
|
// be consumed independently; the slower branch may buffer response chunks.
|
|
252
487
|
const [fullStream, textSourceStream] = retryableFullStream.tee();
|
|
@@ -310,7 +545,7 @@ export class StreamOrchestrator {
|
|
|
310
545
|
* retries will silently fail (the new stream will close immediately because
|
|
311
546
|
* session.isPending() returns false).
|
|
312
547
|
*/
|
|
313
|
-
wrapWithRetry(initialStream, getNewStream, options, session, retryEngine, abortController, attempts) {
|
|
548
|
+
wrapWithRetry(initialStream, getNewStream, options, session, retryEngine, abortController, attempts, waitStateTracker) {
|
|
314
549
|
const handleRetry = this.handleRetryDecision.bind(this);
|
|
315
550
|
let currentStream = initialStream;
|
|
316
551
|
async function* createRetryIterator() {
|
|
@@ -326,7 +561,7 @@ export class StreamOrchestrator {
|
|
|
326
561
|
return;
|
|
327
562
|
}
|
|
328
563
|
catch (error) {
|
|
329
|
-
const retryResult = await handleRetry(error, options, session, retryEngine, attempts);
|
|
564
|
+
const retryResult = await handleRetry(error, options, session, retryEngine, attempts, waitStateTracker);
|
|
330
565
|
if (!retryResult.shouldRetry) {
|
|
331
566
|
// abort the internal signal so any in-flight stream processing stops.
|
|
332
567
|
// without this, tools keep getting called in the background since the stream is not closed.
|
|
@@ -363,8 +598,8 @@ export class StreamOrchestrator {
|
|
|
363
598
|
* Handle an error by making a retry decision. Returns either a new result to continue
|
|
364
599
|
* with, or the final error to throw.
|
|
365
600
|
*/
|
|
366
|
-
async handleRetryDecision(error, options, session, retryEngine, attempts) {
|
|
367
|
-
const decision = retryEngine.getRetryDecision(error, session, options.abortSignal);
|
|
601
|
+
async handleRetryDecision(error, options, session, retryEngine, attempts, waitStateTracker) {
|
|
602
|
+
const decision = retryEngine.getRetryDecision(error, session, options.abortSignal, waitStateTracker.getWaitState());
|
|
368
603
|
if (!decision.shouldRetry) {
|
|
369
604
|
this.logger.warn(`[orchestrator] Not retrying: reason=${decision.reason}`, getErrorMeta(error));
|
|
370
605
|
session.finalize("error", error);
|
|
@@ -381,18 +616,18 @@ export class StreamOrchestrator {
|
|
|
381
616
|
await this.switchProvider(session, decision.newProvider, decision.fastFallback === true, error);
|
|
382
617
|
}
|
|
383
618
|
session.recordRetry(decision.delayMs);
|
|
384
|
-
this.logger.warn(`[orchestrator] Retrying in ${decision.delayMs}ms (attempt ${session.attempt})`, getErrorMeta(error));
|
|
619
|
+
this.logger.warn(`[orchestrator] Retrying in ${decision.delayMs}ms (attempt ${session.attempt}) reason=${decision.reason ?? "retry"}`, getErrorMeta(error));
|
|
385
620
|
await this.delay(decision.delayMs, options.abortSignal);
|
|
386
|
-
const newResult = await this.startStreamWithRetry(options, session, retryEngine, attempts);
|
|
621
|
+
const newResult = await this.startStreamWithRetry(options, session, retryEngine, attempts, waitStateTracker);
|
|
387
622
|
return { shouldRetry: true, newResult };
|
|
388
623
|
}
|
|
389
|
-
async startStreamWithRetry(options, session, retryEngine, attempts) {
|
|
624
|
+
async startStreamWithRetry(options, session, retryEngine, attempts, waitStateTracker) {
|
|
390
625
|
while (true) {
|
|
391
626
|
try {
|
|
392
627
|
return await this.startStream(options, session, attempts);
|
|
393
628
|
}
|
|
394
629
|
catch (error) {
|
|
395
|
-
const decision = retryEngine.getRetryDecision(error, session, options.abortSignal);
|
|
630
|
+
const decision = retryEngine.getRetryDecision(error, session, options.abortSignal, waitStateTracker.getWaitState());
|
|
396
631
|
if (!decision.shouldRetry) {
|
|
397
632
|
this.logger.error(`[orchestrator] Startup error, not retrying: reason=${decision.reason}`, {
|
|
398
633
|
error: {
|
|
@@ -411,7 +646,7 @@ export class StreamOrchestrator {
|
|
|
411
646
|
await this.switchProvider(session, decision.newProvider, decision.fastFallback === true, error);
|
|
412
647
|
}
|
|
413
648
|
session.recordRetry(decision.delayMs);
|
|
414
|
-
this.logger.info(`[orchestrator] Startup retry in ${decision.delayMs}ms (attempt ${session.attempt})`);
|
|
649
|
+
this.logger.info(`[orchestrator] Startup retry in ${decision.delayMs}ms (attempt ${session.attempt}) reason=${decision.reason ?? "retry"}`);
|
|
415
650
|
await this.delay(decision.delayMs, options.abortSignal);
|
|
416
651
|
}
|
|
417
652
|
}
|
|
@@ -509,7 +744,7 @@ export class StreamOrchestrator {
|
|
|
509
744
|
if (!isCurrent()) {
|
|
510
745
|
throw new AbortedError();
|
|
511
746
|
}
|
|
512
|
-
return execute
|
|
747
|
+
return executeToolWithTimeout(name, tool, execute, input, executeOptions, this.logger);
|
|
513
748
|
},
|
|
514
749
|
};
|
|
515
750
|
}
|