visionclaw 0.1.219-dev.codex-issue-2805-worker-runtime.3 → 0.1.219-dev.codex-fix-2941-activity-foreground.1
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/agent/api-proxy.d.ts +16 -0
- package/dist/agent/api-proxy.d.ts.map +1 -1
- package/dist/agent/api-proxy.js +8 -9
- package/dist/agent/api-proxy.js.map +1 -1
- package/dist/agent/browser-launcher.d.ts +0 -3
- package/dist/agent/browser-launcher.d.ts.map +1 -1
- package/dist/agent/browser-launcher.js +43 -101
- package/dist/agent/browser-launcher.js.map +1 -1
- package/dist/agent/coding-conventions.d.ts +3 -2
- package/dist/agent/coding-conventions.d.ts.map +1 -1
- package/dist/agent/coding-conventions.js +8 -7
- package/dist/agent/coding-conventions.js.map +1 -1
- package/dist/agent/command-handlers.d.ts.map +1 -1
- package/dist/agent/command-handlers.js +16 -4
- package/dist/agent/command-handlers.js.map +1 -1
- package/dist/agent/context-action-restart-fallback.d.ts.map +1 -1
- package/dist/agent/context-action-restart-fallback.js +3 -9
- package/dist/agent/context-action-restart-fallback.js.map +1 -1
- package/dist/agent/context-refresh.d.ts.map +1 -1
- package/dist/agent/context-refresh.js +7 -0
- package/dist/agent/context-refresh.js.map +1 -1
- package/dist/agent/context.d.ts.map +1 -1
- package/dist/agent/context.js +8 -6
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/engine-fallback.d.ts +35 -0
- package/dist/agent/engine-fallback.d.ts.map +1 -1
- package/dist/agent/engine-fallback.js +3 -4
- package/dist/agent/engine-fallback.js.map +1 -1
- package/dist/agent/engines/browser-tool-policy.d.ts +1 -12
- package/dist/agent/engines/browser-tool-policy.d.ts.map +1 -1
- package/dist/agent/engines/browser-tool-policy.js +2 -17
- package/dist/agent/engines/browser-tool-policy.js.map +1 -1
- package/dist/agent/engines/claude/session.d.ts +0 -1
- package/dist/agent/engines/claude/session.d.ts.map +1 -1
- package/dist/agent/engines/claude/session.js +36 -21
- package/dist/agent/engines/claude/session.js.map +1 -1
- package/dist/agent/engines/pi/tools.d.ts.map +1 -1
- package/dist/agent/engines/pi/tools.js +10 -2
- package/dist/agent/engines/pi/tools.js.map +1 -1
- package/dist/agent/engines/pi-coding/session.d.ts +0 -3
- package/dist/agent/engines/pi-coding/session.d.ts.map +1 -1
- package/dist/agent/engines/pi-coding/session.js +22 -19
- package/dist/agent/engines/pi-coding/session.js.map +1 -1
- package/dist/agent/engines/session-types.d.ts +0 -6
- package/dist/agent/engines/session-types.d.ts.map +1 -1
- package/dist/agent/external-context/runtime.d.ts.map +1 -1
- package/dist/agent/external-context/runtime.js +14 -15
- package/dist/agent/external-context/runtime.js.map +1 -1
- package/dist/agent/fast-responder.d.ts +20 -4
- package/dist/agent/fast-responder.d.ts.map +1 -1
- package/dist/agent/fast-responder.js +39 -9
- package/dist/agent/fast-responder.js.map +1 -1
- package/dist/agent/interrupt-handler.d.ts +18 -4
- package/dist/agent/interrupt-handler.d.ts.map +1 -1
- package/dist/agent/interrupt-handler.js +284 -49
- package/dist/agent/interrupt-handler.js.map +1 -1
- package/dist/agent/lab-run-system-prompt.d.ts.map +1 -1
- package/dist/agent/lab-run-system-prompt.js +0 -3
- package/dist/agent/lab-run-system-prompt.js.map +1 -1
- package/dist/agent/lifecycle-trace.d.ts.map +1 -1
- package/dist/agent/lifecycle-trace.js +5 -6
- package/dist/agent/lifecycle-trace.js.map +1 -1
- package/dist/agent/loop.d.ts +1 -4
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +129 -105
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory-protocol.d.ts +2 -2
- package/dist/agent/memory-protocol.d.ts.map +1 -1
- package/dist/agent/memory-protocol.js +15 -3
- package/dist/agent/memory-protocol.js.map +1 -1
- package/dist/agent/memory-store.d.ts.map +1 -1
- package/dist/agent/memory-store.js +1 -11
- package/dist/agent/memory-store.js.map +1 -1
- package/dist/agent/model-provider.d.ts +0 -2
- package/dist/agent/model-provider.d.ts.map +1 -1
- package/dist/agent/model-provider.js +25 -31
- package/dist/agent/model-provider.js.map +1 -1
- package/dist/agent/product-identity.d.ts +4 -5
- package/dist/agent/product-identity.d.ts.map +1 -1
- package/dist/agent/product-identity.js +6 -7
- package/dist/agent/product-identity.js.map +1 -1
- package/dist/agent/public-activity.d.ts +1 -1
- package/dist/agent/public-activity.d.ts.map +1 -1
- package/dist/agent/public-activity.js.map +1 -1
- package/dist/agent/reply-watchdog.d.ts +3 -5
- package/dist/agent/reply-watchdog.d.ts.map +1 -1
- package/dist/agent/reply-watchdog.js +4 -6
- package/dist/agent/reply-watchdog.js.map +1 -1
- package/dist/agent/session-manager.d.ts +0 -5
- package/dist/agent/session-manager.d.ts.map +1 -1
- package/dist/agent/session-manager.js +0 -7
- package/dist/agent/session-manager.js.map +1 -1
- package/dist/agent/state.d.ts +0 -7
- package/dist/agent/state.d.ts.map +1 -1
- package/dist/agent/state.js +11 -21
- package/dist/agent/state.js.map +1 -1
- package/dist/agent/stream-handler.d.ts.map +1 -1
- package/dist/agent/stream-handler.js +17 -0
- package/dist/agent/stream-handler.js.map +1 -1
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +6 -10
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/transcript/transcript-indexer.d.ts +28 -0
- package/dist/agent/transcript/transcript-indexer.d.ts.map +1 -1
- package/dist/agent/transcript/transcript-indexer.js +57 -58
- package/dist/agent/transcript/transcript-indexer.js.map +1 -1
- package/dist/agent/usage/usage-report-queue.d.ts.map +1 -1
- package/dist/agent/usage/usage-report-queue.js +52 -53
- package/dist/agent/usage/usage-report-queue.js.map +1 -1
- package/dist/agent/wake-cycle-runner.d.ts +8 -7
- package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
- package/dist/agent/wake-cycle-runner.js +66 -105
- package/dist/agent/wake-cycle-runner.js.map +1 -1
- package/dist/builtin-skills/owner-manual/SKILL.md +2 -2
- package/dist/calendar/occurrence-ownership.d.ts.map +1 -1
- package/dist/calendar/occurrence-ownership.js +5 -6
- package/dist/calendar/occurrence-ownership.js.map +1 -1
- package/dist/calendar/scheduler.d.ts.map +1 -1
- package/dist/calendar/scheduler.js +3 -4
- package/dist/calendar/scheduler.js.map +1 -1
- package/dist/channels/interface.d.ts +2 -8
- package/dist/channels/interface.d.ts.map +1 -1
- package/dist/channels/interface.js +1 -8
- package/dist/channels/interface.js.map +1 -1
- package/dist/channels/manager.d.ts.map +1 -1
- package/dist/channels/manager.js +0 -2
- package/dist/channels/manager.js.map +1 -1
- package/dist/channels/qq-status.d.ts.map +1 -1
- package/dist/channels/qq-status.js +1 -0
- package/dist/channels/qq-status.js.map +1 -1
- package/dist/channels/queue.d.ts.map +1 -1
- package/dist/channels/queue.js +0 -8
- package/dist/channels/queue.js.map +1 -1
- package/dist/channels/telegram-status.d.ts.map +1 -1
- package/dist/channels/telegram-status.js +2 -0
- package/dist/channels/telegram-status.js.map +1 -1
- package/dist/channels/tui.d.ts +2 -2
- package/dist/channels/tui.d.ts.map +1 -1
- package/dist/channels/tui.js +2 -7
- package/dist/channels/tui.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +15 -16
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +8 -16
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +24 -13
- package/dist/config/types.js.map +1 -1
- package/dist/email/email-route-store.d.ts.map +1 -1
- package/dist/email/email-route-store.js +5 -6
- package/dist/email/email-route-store.js.map +1 -1
- package/dist/i18n/messages.d.ts +0 -12
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/i18n/messages.js +9 -21
- package/dist/i18n/messages.js.map +1 -1
- package/dist/logger.d.ts +0 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +1 -19
- package/dist/logger.js.map +1 -1
- package/dist/threads/active-threads-store.d.ts.map +1 -1
- package/dist/threads/active-threads-store.js +27 -8
- package/dist/threads/active-threads-store.js.map +1 -1
- package/dist/threads/execution-host.d.ts.map +1 -1
- package/dist/threads/execution-host.js +0 -1
- package/dist/threads/execution-host.js.map +1 -1
- package/dist/threads/execution-scheduler.d.ts +0 -4
- package/dist/threads/execution-scheduler.d.ts.map +1 -1
- package/dist/threads/execution-scheduler.js +2 -38
- package/dist/threads/execution-scheduler.js.map +1 -1
- package/dist/threads/execution-store.d.ts +5 -20
- package/dist/threads/execution-store.d.ts.map +1 -1
- package/dist/threads/execution-store.js +8 -45
- package/dist/threads/execution-store.js.map +1 -1
- package/dist/threads/foreground-task.d.ts +6 -10
- package/dist/threads/foreground-task.d.ts.map +1 -1
- package/dist/threads/foreground-task.js +26 -34
- package/dist/threads/foreground-task.js.map +1 -1
- package/dist/threads/foreman-client.d.ts.map +1 -1
- package/dist/threads/foreman-client.js +1 -3
- package/dist/threads/foreman-client.js.map +1 -1
- package/dist/threads/foreman-execution.d.ts +12 -12
- package/dist/threads/foreman-execution.d.ts.map +1 -1
- package/dist/threads/foreman-execution.js +19 -30
- package/dist/threads/foreman-execution.js.map +1 -1
- package/dist/threads/foreman-host.d.ts +2 -17
- package/dist/threads/foreman-host.d.ts.map +1 -1
- package/dist/threads/foreman-host.js +63 -452
- package/dist/threads/foreman-host.js.map +1 -1
- package/dist/threads/foreman-protocol.d.ts +12 -113
- package/dist/threads/foreman-protocol.d.ts.map +1 -1
- package/dist/threads/foreman-protocol.js +15 -41
- package/dist/threads/foreman-protocol.js.map +1 -1
- package/dist/threads/foreman-store.d.ts +10 -44
- package/dist/threads/foreman-store.d.ts.map +1 -1
- package/dist/threads/foreman-store.js +19 -78
- package/dist/threads/foreman-store.js.map +1 -1
- package/dist/threads/generic-execution.d.ts +2 -2
- package/dist/threads/generic-execution.d.ts.map +1 -1
- package/dist/threads/generic-execution.js +6 -9
- package/dist/threads/generic-execution.js.map +1 -1
- package/dist/threads/ipc.d.ts +0 -3
- package/dist/threads/ipc.d.ts.map +1 -1
- package/dist/threads/ipc.js.map +1 -1
- package/dist/threads/relay-adapter.d.ts +2 -0
- package/dist/threads/relay-adapter.d.ts.map +1 -1
- package/dist/threads/relay-adapter.js +7 -1
- package/dist/threads/relay-adapter.js.map +1 -1
- package/dist/threads/supervisor.d.ts +51 -21
- package/dist/threads/supervisor.d.ts.map +1 -1
- package/dist/threads/supervisor.js +449 -160
- package/dist/threads/supervisor.js.map +1 -1
- package/dist/threads/task-contracts.d.ts +194 -0
- package/dist/threads/task-contracts.d.ts.map +1 -0
- package/dist/threads/task-contracts.js +82 -0
- package/dist/threads/task-contracts.js.map +1 -0
- package/dist/threads/task-sidecar.d.ts +145 -0
- package/dist/threads/task-sidecar.d.ts.map +1 -0
- package/dist/threads/task-sidecar.js +311 -0
- package/dist/threads/task-sidecar.js.map +1 -0
- package/dist/threads/task-store.d.ts +172 -0
- package/dist/threads/task-store.d.ts.map +1 -0
- package/dist/threads/task-store.js +599 -0
- package/dist/threads/task-store.js.map +1 -0
- package/dist/threads/thread-activity-controller.d.ts +7 -0
- package/dist/threads/thread-activity-controller.d.ts.map +1 -1
- package/dist/threads/thread-activity-controller.js +52 -2
- package/dist/threads/thread-activity-controller.js.map +1 -1
- package/dist/threads/thread-task-context.d.ts +40 -0
- package/dist/threads/thread-task-context.d.ts.map +1 -0
- package/dist/threads/thread-task-context.js +160 -0
- package/dist/threads/thread-task-context.js.map +1 -0
- package/dist/threads/thread-task-controller.d.ts +122 -0
- package/dist/threads/thread-task-controller.d.ts.map +1 -0
- package/dist/threads/thread-task-controller.js +276 -0
- package/dist/threads/thread-task-controller.js.map +1 -0
- package/dist/threads/thread-task-runtime.d.ts +350 -0
- package/dist/threads/thread-task-runtime.d.ts.map +1 -0
- package/dist/threads/thread-task-runtime.js +896 -0
- package/dist/threads/thread-task-runtime.js.map +1 -0
- package/dist/threads/worker-entry.d.ts.map +1 -1
- package/dist/threads/worker-entry.js +28 -29
- package/dist/threads/worker-entry.js.map +1 -1
- package/dist/threads/worker-execution-runtime.d.ts +2 -3
- package/dist/threads/worker-execution-runtime.d.ts.map +1 -1
- package/dist/threads/worker-execution-runtime.js +2 -5
- package/dist/threads/worker-execution-runtime.js.map +1 -1
- package/dist/tools/delegation.d.ts +2 -75
- package/dist/tools/delegation.d.ts.map +1 -1
- package/dist/tools/delegation.js +29 -63
- package/dist/tools/delegation.js.map +1 -1
- package/dist/tools/email.d.ts +1 -1
- package/dist/tools/execution-control.d.ts +0 -5
- package/dist/tools/execution-control.d.ts.map +1 -1
- package/dist/tools/execution-control.js +2 -9
- package/dist/tools/execution-control.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp-manager.d.ts +1 -1
- package/dist/tools/memory.d.ts +1 -1
- package/dist/tools/notify.d.ts +0 -2
- package/dist/tools/notify.d.ts.map +1 -1
- package/dist/tools/notify.js +5 -21
- package/dist/tools/notify.js.map +1 -1
- package/dist/tools/skill.d.ts +1 -1
- package/dist/tools/thread-tasks.d.ts +23 -0
- package/dist/tools/thread-tasks.d.ts.map +1 -0
- package/dist/tools/thread-tasks.js +122 -0
- package/dist/tools/thread-tasks.js.map +1 -0
- package/dist/tools/totp.d.ts +1 -1
- package/dist/tui/request-store.d.ts +1 -1
- package/dist/tui/request-store.d.ts.map +1 -1
- package/dist/tui/request-store.js +2 -2
- package/dist/tui/request-store.js.map +1 -1
- package/dist/tui/server.d.ts.map +1 -1
- package/dist/tui/server.js +2 -17
- package/dist/tui/server.js.map +1 -1
- package/dist/utils/restart.d.ts.map +1 -1
- package/dist/utils/restart.js +0 -6
- package/dist/utils/restart.js.map +1 -1
- package/dist-agent/bundle.cjs +2 -2
- package/package.json +1 -1
- package/dist/agent/runtime-context.d.ts +0 -27
- package/dist/agent/runtime-context.d.ts.map +0 -1
- package/dist/agent/runtime-context.js +0 -60
- package/dist/agent/runtime-context.js.map +0 -1
- package/dist/agent/runtime-disclosure-policy.d.ts +0 -6
- package/dist/agent/runtime-disclosure-policy.d.ts.map +0 -1
- package/dist/agent/runtime-disclosure-policy.js +0 -16
- package/dist/agent/runtime-disclosure-policy.js.map +0 -1
- package/dist/conversations/lazy-runtime.d.ts +0 -5
- package/dist/conversations/lazy-runtime.d.ts.map +0 -1
- package/dist/conversations/lazy-runtime.js +0 -12
- package/dist/conversations/lazy-runtime.js.map +0 -1
- package/dist/conversations/runtime.d.ts +0 -17
- package/dist/conversations/runtime.d.ts.map +0 -1
- package/dist/conversations/runtime.js +0 -92
- package/dist/conversations/runtime.js.map +0 -1
- package/dist/conversations/scheduler.d.ts +0 -57
- package/dist/conversations/scheduler.d.ts.map +0 -1
- package/dist/conversations/scheduler.js +0 -175
- package/dist/conversations/scheduler.js.map +0 -1
- package/dist/threads/foreman-business.d.ts +0 -9
- package/dist/threads/foreman-business.d.ts.map +0 -1
- package/dist/threads/foreman-business.js +0 -117
- package/dist/threads/foreman-business.js.map +0 -1
- package/dist/threads/foreman-delivery.d.ts +0 -5
- package/dist/threads/foreman-delivery.d.ts.map +0 -1
- package/dist/threads/foreman-delivery.js +0 -21
- package/dist/threads/foreman-delivery.js.map +0 -1
- package/dist/threads/task-workspace.d.ts +0 -8
- package/dist/threads/task-workspace.d.ts.map +0 -1
- package/dist/threads/task-workspace.js +0 -52
- package/dist/threads/task-workspace.js.map +0 -1
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import { isEmailChannel, presentsAssistantText } from "../channels/interface.js";
|
|
9
9
|
import { isCalendarInterruptMessage } from "./owner-initiated-eligibility.js";
|
|
10
10
|
import { emailAddressesMatch } from "../utils/email.js";
|
|
11
|
-
import { EXTERNAL_WAKE_KIND } from "../channels/queue.js";
|
|
12
11
|
import { nextRecoveryPhase } from "./lifecycle-transitions.js";
|
|
13
12
|
import { COMPACTION_FAILURE_CONTINUATION, CompactionFailureError } from "./compaction-failure.js";
|
|
14
13
|
import { ToolOutputRepairError } from "./transcript-output-repair.js";
|
|
@@ -33,6 +32,8 @@ import path from "path";
|
|
|
33
32
|
import { randomUUID } from "node:crypto";
|
|
34
33
|
import { runContextRefresh } from "./context-refresh.js";
|
|
35
34
|
import { loadToolAbortRecoveryChain, saveToolAbortRecoveryChain } from "./recovery-chain.js";
|
|
35
|
+
import { buildThreadTaskContext, executionEvents, isTaskRelevantMessage, recordExecutionEvent, } from "../threads/thread-task-runtime.js";
|
|
36
|
+
import { isThreadTaskContextBlock } from "../threads/thread-task-context.js";
|
|
36
37
|
import { getWorkerExecutionRuntime } from "../threads/worker-execution-runtime.js";
|
|
37
38
|
const AUTH_PATTERNS = /\b(401|402|403|authentication|billing|unauthorized|forbidden|api.?key)\b/i;
|
|
38
39
|
// Fatal environment/installation problems that won't fix themselves on retry.
|
|
@@ -276,15 +277,15 @@ export function isSharedCredentialFailure(err) {
|
|
|
276
277
|
}
|
|
277
278
|
return classifyError(err) === "provider_failed" && !isEngineScopedFailure(err);
|
|
278
279
|
}
|
|
279
|
-
function formatOwnerErrorNotice(category, consecutiveErrors, errMsg) {
|
|
280
|
+
function formatOwnerErrorNotice(category, consecutiveErrors, sleepMin, errMsg) {
|
|
280
281
|
if (category === "fatal") {
|
|
281
|
-
return
|
|
282
|
+
return `Agent encountered an internal runtime error. Sleeping ${sleepMin}m before retrying.`;
|
|
282
283
|
}
|
|
283
284
|
if (category === "local") {
|
|
284
285
|
// Name the cause. The old text blamed the model provider for an error the
|
|
285
286
|
// provider never saw, which is what made the original alert storm
|
|
286
287
|
// impossible to diagnose from the notification alone.
|
|
287
|
-
return `Agent hit a local session-coordination error (not a provider failure): ${errMsg ?? "unknown cause"}.
|
|
288
|
+
return `Agent hit a local session-coordination error (not a provider failure): ${errMsg ?? "unknown cause"}. Sleeping ${sleepMin}m before retrying.`;
|
|
288
289
|
}
|
|
289
290
|
if (category === "request_invalid") {
|
|
290
291
|
return `Agent stopped this wake because the provider rejected a malformed request (${errMsg ?? "unknown cause"}).`;
|
|
@@ -295,7 +296,7 @@ function formatOwnerErrorNotice(category, consecutiveErrors, errMsg) {
|
|
|
295
296
|
if (category === "empty_turn") {
|
|
296
297
|
return "The assistant returned another empty turn without confirming completion. The task may be incomplete. I stopped automatic continuation to avoid repeating work; existing results should be checked before continuing.";
|
|
297
298
|
}
|
|
298
|
-
return `Agent encountered an internal model/provider error ${consecutiveErrors} times in a row.
|
|
299
|
+
return `Agent encountered an internal model/provider error ${consecutiveErrors} times in a row. Sleeping ${sleepMin}m before retrying.`;
|
|
299
300
|
}
|
|
300
301
|
function isPromptTooLong(err) {
|
|
301
302
|
const terminalReason = getTerminalReason(err);
|
|
@@ -363,6 +364,7 @@ export const MAX_EMPTY_TURN_RETRIES = 1;
|
|
|
363
364
|
const ERROR_RETRY_COMPACT_USED_PCT = 0.7;
|
|
364
365
|
const BASE_DELAY_MS = 5_000;
|
|
365
366
|
const MAX_DELAY_MS = 5 * 60_000;
|
|
367
|
+
const FATAL_SLEEP_MS = 5 * 60_000;
|
|
366
368
|
/** Max times to retry the LLM call on stream silence timeout before aborting. */
|
|
367
369
|
export const MAX_SILENCE_RETRIES = 3;
|
|
368
370
|
/** Bounded retries for transient stream/network disconnects in any wake cycle. */
|
|
@@ -377,6 +379,22 @@ export const MAX_OUTPUT_RECOVERY_ATTEMPTS = 2;
|
|
|
377
379
|
const SILENCE_TIMEOUT_SCHEDULE_MS = [300_000, 600_000, 900_000];
|
|
378
380
|
/** Decreasing effort levels per attempt to reduce thinking overhead on retries. */
|
|
379
381
|
const EFFORT_SCHEDULE = ["xhigh", "high", "medium"];
|
|
382
|
+
/**
|
|
383
|
+
* A wake retried on a reset session re-sends its first message, whose thread
|
|
384
|
+
* task block (#1996) was built before the reset's reconcile. Swap it for a
|
|
385
|
+
* fresh one so the new session sees exactly one, current copy. Without a
|
|
386
|
+
* task runtime this returns the blocks unchanged.
|
|
387
|
+
*/
|
|
388
|
+
export function withFreshThreadTaskBlock(blocks) {
|
|
389
|
+
const fresh = buildThreadTaskContext();
|
|
390
|
+
const index = blocks.findIndex((block) => block.type === "text" && isThreadTaskContextBlock(block.text));
|
|
391
|
+
if (index === -1)
|
|
392
|
+
return fresh ? [...blocks, { type: "text", text: fresh }] : blocks;
|
|
393
|
+
const rest = blocks.filter((_, i) => i !== index);
|
|
394
|
+
if (fresh)
|
|
395
|
+
rest.splice(index, 0, { type: "text", text: fresh });
|
|
396
|
+
return rest;
|
|
397
|
+
}
|
|
380
398
|
export class WakeCycleRunner {
|
|
381
399
|
externalContextRegistry;
|
|
382
400
|
deps;
|
|
@@ -388,12 +406,6 @@ export class WakeCycleRunner {
|
|
|
388
406
|
localCoordinationErrors = 0;
|
|
389
407
|
/** Empty Claude assistant turns in this wake (not counted as network failures). */
|
|
390
408
|
emptyTurnRetries = 0;
|
|
391
|
-
/**
|
|
392
|
-
* Set once a call's silence ceiling is spent. Silence retries live inside
|
|
393
|
-
* the call, so the outer error handler must not spend another backoff on
|
|
394
|
-
* the same call. Cleared with the next wake.
|
|
395
|
-
*/
|
|
396
|
-
silenceRecoveryExhausted = false;
|
|
397
409
|
/** Recovering only while a spendable bucket is in use. Reset when the wake ends. */
|
|
398
410
|
recoveryPhase = "Running";
|
|
399
411
|
/**
|
|
@@ -494,7 +506,6 @@ export class WakeCycleRunner {
|
|
|
494
506
|
const { config, ownerConfig, session, activityTracker, interruptHandler, messageQueue } = this.deps;
|
|
495
507
|
this.malformedRequestRefreshAttempted = false;
|
|
496
508
|
this.emptyTurnRetries = 0;
|
|
497
|
-
this.silenceRecoveryExhausted = false;
|
|
498
509
|
this.recoveryPhase = "Running";
|
|
499
510
|
// --- Capture transcript start lines for post-cycle indexing ---
|
|
500
511
|
// Recovery can rotate the session to a new transcript, so anchor by
|
|
@@ -502,6 +513,7 @@ export class WakeCycleRunner {
|
|
|
502
513
|
// entry.
|
|
503
514
|
const wakeCycleId = generateWakeCycleId();
|
|
504
515
|
/** Numbers model turns within this wake for their task-event keys. */
|
|
516
|
+
let responseSeq = 0;
|
|
505
517
|
let awaitingUser = false;
|
|
506
518
|
/** The model ended the wake with an accepted finish (not a timeout or exhausted recovery). */
|
|
507
519
|
let wakeFinished = false;
|
|
@@ -539,7 +551,10 @@ export class WakeCycleRunner {
|
|
|
539
551
|
// failover. If the session cannot be rotated, stay on the current engine
|
|
540
552
|
// and try again next wake rather than replaying its history elsewhere.
|
|
541
553
|
if (recovered) {
|
|
542
|
-
if (
|
|
554
|
+
if (await this.rotateSessionForEngineSwitch(session, String(activeBefore), recovered.recovered, "recovery")) {
|
|
555
|
+
contentBlocks = withFreshThreadTaskBlock(contentBlocks);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
543
558
|
setFallbackEngine(fallbackBefore);
|
|
544
559
|
}
|
|
545
560
|
}
|
|
@@ -577,7 +592,7 @@ export class WakeCycleRunner {
|
|
|
577
592
|
// Retry this inner business turn only for transient stream/socket failures.
|
|
578
593
|
while (transientStreamRetries <= MAX_TRANSIENT_STREAM_RETRIES) {
|
|
579
594
|
try {
|
|
580
|
-
|
|
595
|
+
for (let silenceAttempt = 1; silenceAttempt <= MAX_SILENCE_RETRIES; silenceAttempt++) {
|
|
581
596
|
const scheduledSilenceMs = SILENCE_TIMEOUT_SCHEDULE_MS[silenceAttempt - 1] ?? SILENCE_TIMEOUT_SCHEDULE_MS[SILENCE_TIMEOUT_SCHEDULE_MS.length - 1];
|
|
582
597
|
// Pass the scheduled bound. Pi auto-compaction starts after the
|
|
583
598
|
// stream is already open (system/compaction_start); processAgentStream
|
|
@@ -600,6 +615,9 @@ export class WakeCycleRunner {
|
|
|
600
615
|
lastReplyText = streamResult.lastAssistantText;
|
|
601
616
|
lastReplyPresented = streamResult.lastAssistantTextPresented === true;
|
|
602
617
|
}
|
|
618
|
+
// One event per model turn with its complete prose; the task
|
|
619
|
+
// sidecar folds it into progress. No-op without a task runtime.
|
|
620
|
+
recordExecutionEvent(executionEvents.response(`${wakeCycleId}:${responseSeq++}`, streamResult.assistantText));
|
|
603
621
|
// A successful SDK envelope can still contain a legitimate empty
|
|
604
622
|
// model turn. Apply the same task-state policy as SDK diagnostics.
|
|
605
623
|
if (!this.deps.singleShot && streamResult.emptyTurn && !streamResult.finishCalled && !streamResult.toolTimeout) {
|
|
@@ -640,37 +658,22 @@ export class WakeCycleRunner {
|
|
|
640
658
|
`skipping the remaining ${MAX_SILENCE_RETRIES - silenceAttempt} silence retries`);
|
|
641
659
|
}
|
|
642
660
|
}
|
|
643
|
-
|
|
644
|
-
// engine does not get the remaining ones: that is Stopping, not
|
|
645
|
-
// another Recovering retry.
|
|
646
|
-
const silencePhase = nextRecoveryPhase({
|
|
647
|
-
from: this.recoveryPhase,
|
|
648
|
-
bucket: "silence",
|
|
649
|
-
spent: engineAnswersProbe ? silenceAttempt : MAX_SILENCE_RETRIES,
|
|
650
|
-
});
|
|
651
|
-
if (silencePhase === "Recovering")
|
|
652
|
-
this.recoveryPhase = "Recovering";
|
|
653
|
-
if (silencePhase === "Recovering" && engineAnswersProbe) {
|
|
661
|
+
if (silenceAttempt < MAX_SILENCE_RETRIES && engineAnswersProbe) {
|
|
654
662
|
const nextTimeoutMs = SILENCE_TIMEOUT_SCHEDULE_MS[silenceAttempt] ?? SILENCE_TIMEOUT_SCHEDULE_MS[SILENCE_TIMEOUT_SCHEDULE_MS.length - 1];
|
|
655
663
|
const nextEffort = tierEffort
|
|
656
664
|
? getLlmRetryEffort(tierEffort, silenceAttempt)
|
|
657
665
|
: effortSchedule[silenceAttempt];
|
|
658
666
|
logger.system(`Stream silence timeout after ${silenceTimeoutMs / 1000}s (attempt ${silenceAttempt}/${MAX_SILENCE_RETRIES}) — engine still answering, retrying LLM call with ${nextTimeoutMs / 1000}s timeout and effort=${nextEffort}...`);
|
|
659
|
-
// Re-send the same messageContent on
|
|
660
|
-
continue
|
|
667
|
+
// Re-send the same messageContent on next iteration
|
|
668
|
+
continue;
|
|
661
669
|
}
|
|
662
670
|
// Retries exhausted, or cut short because the engine failed its
|
|
663
|
-
// health probe.
|
|
664
|
-
// switch or a successful compaction below continues this wake, so
|
|
665
|
-
// the outer handler is only blocked once this call is actually
|
|
666
|
-
// abandoned.
|
|
671
|
+
// health probe.
|
|
667
672
|
logger.err(engineAnswersProbe
|
|
668
673
|
? `Stream silence timeout: all ${MAX_SILENCE_RETRIES} attempts exhausted — aborting`
|
|
669
674
|
: `Stream silence timeout on attempt ${silenceAttempt}/${MAX_SILENCE_RETRIES} with a failed health probe — aborting`);
|
|
670
|
-
if (this.deps.singleShot)
|
|
671
|
-
this.silenceRecoveryExhausted = true;
|
|
675
|
+
if (this.deps.singleShot)
|
|
672
676
|
throw streamErr;
|
|
673
|
-
}
|
|
674
677
|
const locale = resolveLocale(ownerConfig.language);
|
|
675
678
|
// Report what actually happened: a probe-driven short circuit may
|
|
676
679
|
// have spent only one of the three attempts, and telling the owner
|
|
@@ -687,6 +690,7 @@ export class WakeCycleRunner {
|
|
|
687
690
|
const degraded = await this.degradeActiveEngine(engineFallback, "silence_exhausted", session);
|
|
688
691
|
if (degraded === "hot") {
|
|
689
692
|
consecutiveErrors = 0;
|
|
693
|
+
contentBlocks = withFreshThreadTaskBlock(contentBlocks);
|
|
690
694
|
continue wakeLoop;
|
|
691
695
|
}
|
|
692
696
|
if (degraded === "restarting") {
|
|
@@ -705,6 +709,9 @@ export class WakeCycleRunner {
|
|
|
705
709
|
try {
|
|
706
710
|
await activeSession.requestCompaction();
|
|
707
711
|
consecutiveErrors = 0;
|
|
712
|
+
// The compacted session must see the tasks as the compaction
|
|
713
|
+
// reconcile just left them, not the wake-start block (#1996).
|
|
714
|
+
contentBlocks = withFreshThreadTaskBlock(contentBlocks);
|
|
708
715
|
continue wakeLoop;
|
|
709
716
|
}
|
|
710
717
|
catch (compactErr) {
|
|
@@ -721,7 +728,6 @@ export class WakeCycleRunner {
|
|
|
721
728
|
...taskContinuationRouting(this.deps.agentState.currentTaskReplyTarget),
|
|
722
729
|
});
|
|
723
730
|
logger.system("Enqueued interrupted-task recovery message for next wake cycle");
|
|
724
|
-
this.silenceRecoveryExhausted = true;
|
|
725
731
|
throw streamErr; // propagate so the outer handler records the error
|
|
726
732
|
}
|
|
727
733
|
}
|
|
@@ -729,18 +735,7 @@ export class WakeCycleRunner {
|
|
|
729
735
|
}
|
|
730
736
|
catch (streamErr) {
|
|
731
737
|
// TODO: guard retry against simultaneous stop requests and settle the failed input generator before retrying; both are rare stream/stop races.
|
|
732
|
-
|
|
733
|
-
// this turn. Another one is Recovering; the ceiling throws, and
|
|
734
|
-
// the outer handler records it instead of retrying this turn.
|
|
735
|
-
const networkPhase = isTransientStreamFailure(streamErr)
|
|
736
|
-
? nextRecoveryPhase({
|
|
737
|
-
from: this.recoveryPhase,
|
|
738
|
-
bucket: "network",
|
|
739
|
-
spent: transientStreamRetries,
|
|
740
|
-
})
|
|
741
|
-
: null;
|
|
742
|
-
if (networkPhase === "Recovering") {
|
|
743
|
-
this.recoveryPhase = "Recovering";
|
|
738
|
+
if (isTransientStreamFailure(streamErr) && transientStreamRetries < MAX_TRANSIENT_STREAM_RETRIES) {
|
|
744
739
|
transientStreamRetries++;
|
|
745
740
|
logger.system(`Transient stream failure (retry ${transientStreamRetries}/${MAX_TRANSIENT_STREAM_RETRIES}) — retrying the current business turn...`);
|
|
746
741
|
continue;
|
|
@@ -818,16 +813,7 @@ export class WakeCycleRunner {
|
|
|
818
813
|
if (!this.deps.singleShot &&
|
|
819
814
|
endedWithoutLifecycleAction &&
|
|
820
815
|
runningSubagents.length === 0) {
|
|
821
|
-
|
|
822
|
-
// this wake. One more is Recovering; the ceiling is Stopping, and
|
|
823
|
-
// this wake ends instead of starting another continuation.
|
|
824
|
-
const prematurePhase = nextRecoveryPhase({
|
|
825
|
-
from: this.recoveryPhase,
|
|
826
|
-
bucket: "premature_result",
|
|
827
|
-
spent: prematureEndContinuations,
|
|
828
|
-
});
|
|
829
|
-
if (prematurePhase === "Recovering") {
|
|
830
|
-
this.recoveryPhase = "Recovering";
|
|
816
|
+
if (prematureEndContinuations < MAX_PREMATURE_END_CONTINUATIONS) {
|
|
831
817
|
prematureEndContinuations++;
|
|
832
818
|
logger.warn(`Turn ended without finish — continuing (${prematureEndContinuations}/${MAX_PREMATURE_END_CONTINUATIONS})`);
|
|
833
819
|
messageContent = [{
|
|
@@ -894,18 +880,9 @@ export class WakeCycleRunner {
|
|
|
894
880
|
}
|
|
895
881
|
}
|
|
896
882
|
else {
|
|
897
|
-
// The persisted count is this chain's own budget. It survives
|
|
898
|
-
// wakes and restarts, so a new wake must not refill it.
|
|
899
|
-
const toolAbortPhase = nextRecoveryPhase({
|
|
900
|
-
from: this.recoveryPhase,
|
|
901
|
-
bucket: "tool_abort",
|
|
902
|
-
spent: this.toolAbortRecoveries,
|
|
903
|
-
});
|
|
904
883
|
this.toolAbortRecoveryChainId ??= randomUUID();
|
|
905
884
|
this.toolAbortRecoveries += 1;
|
|
906
|
-
const retryable =
|
|
907
|
-
if (retryable)
|
|
908
|
-
this.recoveryPhase = "Recovering";
|
|
885
|
+
const retryable = this.toolAbortRecoveries <= MAX_TOOL_ABORT_RECOVERIES;
|
|
909
886
|
if (!retryable)
|
|
910
887
|
this.toolAbortRecoveryExhausted = true;
|
|
911
888
|
this.persistToolAbortRecoveryChain();
|
|
@@ -966,7 +943,7 @@ export class WakeCycleRunner {
|
|
|
966
943
|
// Resumes, external wakes and calendars may carry a delivery target
|
|
967
944
|
// without requesting a reply. Mid-turn work uses explicit notify_user
|
|
968
945
|
// for its result; a quick acknowledgment does not enable this fallback.
|
|
969
|
-
const replyMessages = messages.filter((message) => message
|
|
946
|
+
const replyMessages = messages.filter((message) => isTaskRelevantMessage(message) && !isCalendarInterruptMessage(message));
|
|
970
947
|
const fallbackEligible = !this.deps.singleShot &&
|
|
971
948
|
!streamResult.toolTimeout &&
|
|
972
949
|
!skipBecauseNotified &&
|
|
@@ -1110,14 +1087,21 @@ export class WakeCycleRunner {
|
|
|
1110
1087
|
if (errorResult.kind === "continue_with_message") {
|
|
1111
1088
|
consecutiveErrors = errorResult.consecutiveErrors;
|
|
1112
1089
|
contentBlocks = [{ type: "text", text: errorResult.message }];
|
|
1090
|
+
// A rebuilt session starts without the thread's tasks (#1996).
|
|
1091
|
+
if (errorResult.newSession)
|
|
1092
|
+
contentBlocks = withFreshThreadTaskBlock(contentBlocks);
|
|
1113
1093
|
continue;
|
|
1114
1094
|
}
|
|
1115
1095
|
if (errorResult.kind === "continue_with_reset") {
|
|
1116
1096
|
consecutiveErrors = 0;
|
|
1097
|
+
contentBlocks = withFreshThreadTaskBlock(contentBlocks);
|
|
1117
1098
|
continue;
|
|
1118
1099
|
}
|
|
1119
1100
|
if (errorResult.kind === "continue_preserve_count") {
|
|
1120
1101
|
consecutiveErrors = errorResult.consecutiveErrors;
|
|
1102
|
+
// Invalid-json recovery may have compacted (#1996): resend the
|
|
1103
|
+
// current task block. A no-op when nothing changed.
|
|
1104
|
+
contentBlocks = withFreshThreadTaskBlock(contentBlocks);
|
|
1121
1105
|
continue;
|
|
1122
1106
|
}
|
|
1123
1107
|
consecutiveErrors = errorResult.consecutiveErrors;
|
|
@@ -1197,12 +1181,6 @@ export class WakeCycleRunner {
|
|
|
1197
1181
|
logger.system(err.message);
|
|
1198
1182
|
return { kind: "done", consecutiveErrors };
|
|
1199
1183
|
}
|
|
1200
|
-
if (this.silenceRecoveryExhausted) {
|
|
1201
|
-
// The call already spent its own silence ceiling and moved to Stopping.
|
|
1202
|
-
// Another backoff here would replay that call instead of ending it.
|
|
1203
|
-
logger.system("Stream silence ceiling already spent — ending this wake cycle");
|
|
1204
|
-
return { kind: "done", consecutiveErrors: consecutiveErrors + 1 };
|
|
1205
|
-
}
|
|
1206
1184
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1207
1185
|
const category = classifyError(err);
|
|
1208
1186
|
// A local coordination error never reached a provider, so it must not
|
|
@@ -1470,15 +1448,16 @@ export class WakeCycleRunner {
|
|
|
1470
1448
|
return { kind: "continue_preserve_count", consecutiveErrors };
|
|
1471
1449
|
}
|
|
1472
1450
|
// Retries exhausted: tell the owner what actually broke, naming the
|
|
1473
|
-
// local cause instead of blaming the model provider.
|
|
1474
|
-
|
|
1451
|
+
// local cause instead of blaming the model provider.
|
|
1452
|
+
const sleepMin = FATAL_SLEEP_MS / 60_000;
|
|
1475
1453
|
logger.warn(`Notifying owner about persistent local coordination error: ${errMsg}`);
|
|
1476
1454
|
try {
|
|
1477
|
-
await notifyOwner(formatOwnerErrorNotice(category, consecutiveErrors, errMsg), config);
|
|
1455
|
+
await notifyOwner(formatOwnerErrorNotice(category, consecutiveErrors, sleepMin, errMsg), config);
|
|
1478
1456
|
}
|
|
1479
1457
|
catch (notifyErr) {
|
|
1480
1458
|
logger.warn(`Failed to send error notification to owner: ${notifyErr instanceof Error ? notifyErr.message : String(notifyErr)}`);
|
|
1481
1459
|
}
|
|
1460
|
+
await new Promise((r) => setTimeout(r, FATAL_SLEEP_MS));
|
|
1482
1461
|
return { kind: "done", consecutiveErrors };
|
|
1483
1462
|
}
|
|
1484
1463
|
// --- Known malformed Responses replay ---
|
|
@@ -1517,7 +1496,7 @@ export class WakeCycleRunner {
|
|
|
1517
1496
|
}
|
|
1518
1497
|
logger.err(`Malformed Responses replay recovery failed — ending wake: ${errMsg}`);
|
|
1519
1498
|
try {
|
|
1520
|
-
await notifyOwner(formatOwnerErrorNotice(category, consecutiveErrors, errMsg), config);
|
|
1499
|
+
await notifyOwner(formatOwnerErrorNotice(category, consecutiveErrors, 0, errMsg), config);
|
|
1521
1500
|
}
|
|
1522
1501
|
catch (notifyErr) {
|
|
1523
1502
|
logger.warn(`Failed to send error notification to owner: ${notifyErr instanceof Error ? notifyErr.message : String(notifyErr)}`);
|
|
@@ -1546,7 +1525,7 @@ export class WakeCycleRunner {
|
|
|
1546
1525
|
if (phase === "Stopping") {
|
|
1547
1526
|
logger.warn(`Empty-turn continuation did not confirm task completion: ${errMsg}`);
|
|
1548
1527
|
try {
|
|
1549
|
-
await notifyOwner(formatOwnerErrorNotice(category, this.emptyTurnRetries, errMsg), config);
|
|
1528
|
+
await notifyOwner(formatOwnerErrorNotice(category, this.emptyTurnRetries, 0, errMsg), config);
|
|
1550
1529
|
}
|
|
1551
1530
|
catch (notifyErr) {
|
|
1552
1531
|
logger.warn(`Failed to send empty-turn notification to owner: ${notifyErr instanceof Error ? notifyErr.message : String(notifyErr)}`);
|
|
@@ -1615,22 +1594,10 @@ export class WakeCycleRunner {
|
|
|
1615
1594
|
logger.system("No alternate engine available for transient network failures; keeping consecutiveErrors and the cooldown");
|
|
1616
1595
|
}
|
|
1617
1596
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
// that holds this slot.
|
|
1623
|
-
const unknownPhase = category === "fatal"
|
|
1624
|
-
? "Stopping"
|
|
1625
|
-
: nextRecoveryPhase({
|
|
1626
|
-
from: this.recoveryPhase,
|
|
1627
|
-
bucket: "unknown",
|
|
1628
|
-
spent: consecutiveErrors,
|
|
1629
|
-
});
|
|
1630
|
-
if (unknownPhase === "Recovering")
|
|
1631
|
-
this.recoveryPhase = "Recovering";
|
|
1632
|
-
if (unknownPhase === "Stopping") {
|
|
1633
|
-
const notice = formatOwnerErrorNotice(category, consecutiveErrors);
|
|
1597
|
+
if (category === "fatal" ||
|
|
1598
|
+
consecutiveErrors >= MAX_RETRIES_BEFORE_NOTIFY) {
|
|
1599
|
+
const sleepMin = FATAL_SLEEP_MS / 60_000;
|
|
1600
|
+
const notice = formatOwnerErrorNotice(category, consecutiveErrors, sleepMin);
|
|
1634
1601
|
logger.warn(`Notifying owner about repeated agent error: ${errMsg}`);
|
|
1635
1602
|
try {
|
|
1636
1603
|
await notifyOwner(notice, config);
|
|
@@ -1639,6 +1606,7 @@ export class WakeCycleRunner {
|
|
|
1639
1606
|
logger.warn(`Failed to send error notification to owner: ${notifyErr instanceof Error ? notifyErr.message : String(notifyErr)}`);
|
|
1640
1607
|
}
|
|
1641
1608
|
consecutiveErrors = 0;
|
|
1609
|
+
await new Promise((r) => setTimeout(r, FATAL_SLEEP_MS));
|
|
1642
1610
|
}
|
|
1643
1611
|
else {
|
|
1644
1612
|
try {
|
|
@@ -1717,15 +1685,8 @@ export class WakeCycleRunner {
|
|
|
1717
1685
|
// Two recovery turns total: repair, then one refresh. The second branch is
|
|
1718
1686
|
// gated by the ceiling, so raising MAX_OUTPUT_RECOVERY_ATTEMPTS is what
|
|
1719
1687
|
// allows another turn. Advancing before I/O keeps a failed repair from
|
|
1720
|
-
// resetting the allowance.
|
|
1721
|
-
|
|
1722
|
-
from: this.recoveryPhase,
|
|
1723
|
-
bucket: recoveryKind === "policy_refused" ? "policy_refusal" : "oversized",
|
|
1724
|
-
spent: attempts[recoveryKind],
|
|
1725
|
-
});
|
|
1726
|
-
if (outputPhase === "Recovering")
|
|
1727
|
-
this.recoveryPhase = "Recovering";
|
|
1728
|
-
if (attempts[recoveryKind] === 0 && outputPhase === "Recovering") {
|
|
1688
|
+
// resetting the allowance.
|
|
1689
|
+
if (attempts[recoveryKind] === 0) {
|
|
1729
1690
|
attempts[recoveryKind]++;
|
|
1730
1691
|
if (!compactionAlreadyFailed) {
|
|
1731
1692
|
try {
|
|
@@ -1744,7 +1705,7 @@ export class WakeCycleRunner {
|
|
|
1744
1705
|
logger.system("SDK auto-compaction already failed — skipping same-session transcript repair and rotating context");
|
|
1745
1706
|
}
|
|
1746
1707
|
}
|
|
1747
|
-
if (attempts[recoveryKind] < MAX_OUTPUT_RECOVERY_ATTEMPTS
|
|
1708
|
+
if (attempts[recoveryKind] < MAX_OUTPUT_RECOVERY_ATTEMPTS) {
|
|
1748
1709
|
attempts[recoveryKind]++;
|
|
1749
1710
|
const previousId = session.activeSession.getSessionId();
|
|
1750
1711
|
try {
|