mixdog 0.9.95 → 0.9.96
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/LICENSES/Apache-2.0.txt +201 -0
- package/LICENSES/MIT.txt +56 -0
- package/LICENSES/codex-NOTICE.txt +6 -0
- package/NOTICE.md +46 -9
- package/package.json +12 -9
- package/scripts/.tmp-coverage-report.mjs +96 -0
- package/scripts/build-tui.mjs +17 -1
- package/scripts/fixtures/patch-replay-corpus.json +98 -0
- package/src/defaults/mixdog-config.template.json +5 -8
- package/src/rules/agent/30-explorer.md +7 -4
- package/src/rules/shared/01-tool.md +20 -29
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +31 -1
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +6 -17
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +12 -1
- package/src/runtime/agent/orchestrator/config.mjs +246 -67
- package/src/runtime/agent/orchestrator/mcp/client.mjs +26 -11
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +23 -0
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +113 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +32 -11
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +89 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +144 -39
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +22 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/openai-transport-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +3 -4
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +67 -7
- package/src/runtime/agent/orchestrator/providers/stream-json-pool.mjs +291 -0
- package/src/runtime/agent/orchestrator/providers/stream-json-worker.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -33
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +0 -24
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +1 -27
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +6 -10
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +142 -84
- package/src/runtime/agent/orchestrator/session/manager/runtime-loaders.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +31 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +29 -9
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +86 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +3 -33
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -5
- package/src/runtime/agent/orchestrator/stall-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +35 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +118 -18
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +8 -9
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +6 -15
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +10 -26
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -23
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +23 -9
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +7 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +17 -39
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +73 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +0 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +3 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +30 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +87 -15
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +6 -15
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/lib/pwsh-standby-pool.mjs +83 -13
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +39 -1
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +29 -1
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +16 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +108 -12
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +10 -10
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +56 -8
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +2 -2
- package/src/runtime/channels/lib/config.mjs +2 -2
- package/src/runtime/channels/lib/inbound-handler.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +2 -2
- package/src/runtime/memory/index.mjs +5 -38
- package/src/runtime/memory/lib/agent-ipc.mjs +145 -81
- package/src/runtime/memory/lib/compact-vector-cache.mjs +88 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +18 -1
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +12 -33
- package/src/runtime/memory/lib/embedding-provider.mjs +47 -26
- package/src/runtime/memory/lib/embedding-worker.mjs +30 -34
- package/src/runtime/memory/lib/http-router.mjs +8 -0
- package/src/runtime/memory/lib/ko-morph.mjs +3 -20
- package/src/runtime/memory/lib/memory-action-handlers.mjs +2 -1
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -0
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +4 -2
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +1 -0
- package/src/runtime/memory/lib/memory-cycle3.mjs +3 -1
- package/src/runtime/memory/lib/pg/process.mjs +32 -9
- package/src/runtime/memory/tool-defs.mjs +1 -5
- package/src/runtime/search/tool-defs.mjs +2 -2
- package/src/runtime/shared/agent-route-config.mjs +119 -0
- package/src/runtime/shared/atomic-file.mjs +80 -4
- package/src/runtime/shared/channel-notification-routing.mjs +2 -2
- package/src/runtime/shared/child-guardian.mjs +204 -108
- package/src/runtime/shared/child-spawn-gate.mjs +60 -31
- package/src/runtime/shared/config.mjs +130 -44
- package/src/runtime/shared/resource-admission.mjs +146 -97
- package/src/runtime/shared/stream-progress.mjs +6 -0
- package/src/runtime/shared/tool-surface.mjs +0 -5
- package/src/runtime/shared/turn-snapshot.mjs +31 -5
- package/src/runtime/shared/turn-worktree-snapshot.mjs +14 -2
- package/src/session-runtime/config-helpers.mjs +39 -37
- package/src/session-runtime/model-route-api.mjs +7 -5
- package/src/session-runtime/provider-auth-api.mjs +0 -7
- package/src/session-runtime/runtime-core.mjs +11 -11
- package/src/session-runtime/runtime-tunables.mjs +4 -4
- package/src/session-runtime/session-lifecycle.mjs +9 -2
- package/src/session-runtime/session-turn-api.mjs +41 -9
- package/src/session-runtime/settings-api.mjs +5 -17
- package/src/session-runtime/tool-defs.mjs +3 -3
- package/src/session-runtime/workflow-agents-api.mjs +55 -81
- package/src/session-runtime/workflow.mjs +14 -24
- package/src/standalone/agent-dispatch-broker.mjs +198 -0
- package/src/standalone/agent-tool/helpers.mjs +2 -2
- package/src/standalone/agent-tool/spawn-flow.mjs +2 -0
- package/src/standalone/agent-tool/spawn-preset.mjs +11 -21
- package/src/standalone/agent-tool/tool-def.mjs +0 -14
- package/src/standalone/backend-daemon.mjs +97 -36
- package/src/standalone/channel-admin.mjs +12 -12
- package/src/standalone/channel-daemon-client.mjs +17 -1
- package/src/standalone/channel-daemon-transport.mjs +90 -8
- package/src/standalone/engine-daemon-client.mjs +380 -205
- package/src/standalone/engine-daemon-protocol.mjs +3 -4
- package/src/standalone/engine-daemon-service.mjs +378 -134
- package/src/standalone/engine-daemon-transport.mjs +268 -77
- package/src/standalone/explore-tool.mjs +187 -70
- package/src/standalone/fair-call-scheduler.mjs +264 -0
- package/src/standalone/session-protocol.mjs +188 -0
- package/src/tui/App.jsx +30 -17
- package/src/tui/app/app-view.jsx +5 -2
- package/src/tui/app/core-memory-picker.mjs +19 -19
- package/src/tui/app/doctor.mjs +5 -11
- package/src/tui/app/message-selector.mjs +103 -0
- package/src/tui/app/onboarding-steps.mjs +1 -2
- package/src/tui/app/project-picker.mjs +80 -56
- package/src/tui/app/prompt-submit.mjs +46 -41
- package/src/tui/app/resume-picker.mjs +2 -2
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker.mjs +6 -8
- package/src/tui/app/transcript-window.mjs +38 -0
- package/src/tui/app/use-prompt-draft-flow.mjs +5 -7
- package/src/tui/app/use-prompt-handlers.mjs +86 -21
- package/src/tui/app/use-prompt-hint.mjs +3 -2
- package/src/tui/app/use-prompt-queue-history.mjs +10 -3
- package/src/tui/app/use-transcript-scroll.mjs +9 -2
- package/src/tui/app/use-transcript-window.mjs +50 -17
- package/src/tui/components/PromptInput.jsx +71 -38
- package/src/tui/components/Spinner.jsx +1 -1
- package/src/tui/components/prompt-input/edit-helpers.mjs +9 -11
- package/src/tui/components/prompt-input/escape-policy.mjs +42 -0
- package/src/tui/components/prompt-input/immediate-render.mjs +0 -10
- package/src/tui/components/prompt-input/interrupt-policy.mjs +10 -0
- package/src/tui/components/prompt-input/restore-policy.mjs +10 -0
- package/src/tui/dist/index.mjs +920 -1592
- package/src/tui/engine/live-share.mjs +34 -0
- package/src/tui/engine/session-api-ext.mjs +1 -4
- package/src/tui/engine/session-api.mjs +103 -33
- package/src/tui/engine/session-flow.mjs +7 -1
- package/src/tui/engine/tool-card-results.mjs +4 -2
- package/src/tui/engine/tool-result-text.mjs +10 -0
- package/src/tui/engine/turn.mjs +9 -69
- package/src/tui/engine-local-session.mjs +47 -31
- package/src/tui/index.jsx +1 -2
- package/src/tui/spinner-meta.mjs +4 -4
- package/src/tui/spinner-verbs.mjs +51 -3
- package/src/standalone/engine-daemon-local-bridge.mjs +0 -20
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"outputStyle": "default",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"targetPath": ""
|
|
8
|
-
}
|
|
3
|
+
"agent": {
|
|
4
|
+
"mcpServers": {},
|
|
5
|
+
"profile": { "title": "", "language": "system" },
|
|
6
|
+
"recap": { "enabled": true }
|
|
9
7
|
},
|
|
8
|
+
"channels": {},
|
|
10
9
|
"memory": {
|
|
11
|
-
"enabled": true,
|
|
12
|
-
"user": { "title": "" },
|
|
13
10
|
"cycle1": { "interval": "10m" },
|
|
14
11
|
"cycle2": { "interval": "1h" }
|
|
15
12
|
}
|
|
@@ -32,11 +32,14 @@ or concept synonym; never a prose phrase. Spaces and non-ASCII are allowed
|
|
|
32
32
|
only in verbatim quoted error/log literals. Translate other non-English
|
|
33
33
|
queries to English identifiers.
|
|
34
34
|
|
|
35
|
-
Scope is
|
|
35
|
+
Scope is every `<roots><root>…</root></roots>` entry when supplied, otherwise
|
|
36
|
+
session cwd. Search every supplied root in the turn-1 batch: grep/glob batch
|
|
37
|
+
`path[]`, while find uses one sibling call per root. Never silently fall back to
|
|
38
|
+
cwd or omit a supplied root. A find result is relative to its exact root; prefix
|
|
39
|
+
that root when returning a path outside cwd. For unverified `src` paths, use
|
|
36
40
|
`find` first; never guess or invent directories or pair `path:"."` with guessed
|
|
37
|
-
`src/**`. Scoped grep/glob may use only an exact find-returned
|
|
38
|
-
|
|
39
|
-
paths.
|
|
41
|
+
`src/**`. Scoped grep/glob may use only a supplied root or an exact find-returned
|
|
42
|
+
path. After zero hits, change tokens or scope, never wording or guessed paths.
|
|
40
43
|
|
|
41
44
|
An anchor is a `path:line` containing a query token or synonym, including a
|
|
42
45
|
code_graph hit. Generic terms without query specificity are zero. Never
|
|
@@ -1,31 +1,22 @@
|
|
|
1
1
|
# Tool Use
|
|
2
2
|
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
`
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Verify in proportion to risk: one decisive probe rides the edit call. A pass
|
|
24
|
-
is final; on failure fix and rerun what failed. Diagnostics non-fatal; report
|
|
25
|
-
verified vs assumed.
|
|
26
|
-
- `apply_patch` is the primary edit tool: once path and content are known it
|
|
27
|
-
joins the current batch — all files and hunks in one call, never one turn per
|
|
28
|
-
file (the format contract lives in its tool description).
|
|
29
|
-
- After a background task starts or reports, end the turn — its notification
|
|
30
|
-
resumes the work. Never poll or block; wait only for what the turn cannot
|
|
31
|
-
proceed without. Long commands whose output the next step ignores go async.
|
|
3
|
+
- Unknown coordinates → one `explore` call with every unknown facet, sent
|
|
4
|
+
alone. Then batch every anchored retrieval needed to determine the complete
|
|
5
|
+
edit: partial path/name→`find`; exact directory entries→`list`; wildcard→
|
|
6
|
+
`glob`; text/regex-anchored source blocks→`grep`; anchorless known file/range→
|
|
7
|
+
`read`; symbol/relation→`code_graph`; web/current→`search`; returned URL body→
|
|
8
|
+
`web_fetch`; prior work→`recall`; durable compact English memory→`memory`;
|
|
9
|
+
explicit project change→`cwd`; explicit user-requested conversation reset→
|
|
10
|
+
`session_manage`; process/env, git, build/run/test→`shell`. Never use shell
|
|
11
|
+
equivalents for file discovery or content retrieval.
|
|
12
|
+
- Use verified paths (cwd, project root, user-provided, or tool-returned);
|
|
13
|
+
guessed fragments use `find`. Merge independent calls per tool in one
|
|
14
|
+
message and fetch all information needed in that batch. Follow up only after
|
|
15
|
+
zero/error or a newly revealed dependency; never re-fetch an unchanged span.
|
|
16
|
+
- Once every final edit is fully determined, send one assistant tool batch
|
|
17
|
+
containing one `apply_patch` for all files/hunks and one `shell` chain for
|
|
18
|
+
verification. The runtime supports this mixed batch. On failure fix and
|
|
19
|
+
rerun only what failed; report verified versus assumed.
|
|
20
|
+
- After a call returns a background `task_id`, end the turn; its completion
|
|
21
|
+
notification resumes work. Never poll; use task control only for recovery or
|
|
22
|
+
a required blocking result.
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
abortAgentProgressWatchdog,
|
|
37
37
|
agentWatchdogPolicyActive,
|
|
38
38
|
evaluateAgentWatchdogAbort,
|
|
39
|
+
partialHandoffTextFromSession,
|
|
39
40
|
resolveAgentWatchdogPolicy,
|
|
40
41
|
resolveHandoffMessageStartIndex,
|
|
41
42
|
watchdogPartialHandoffFromError,
|
|
@@ -65,6 +66,17 @@ function formatCompactElapsedSeconds(ms) {
|
|
|
65
66
|
return `${Math.max(1, Math.ceil(value / 1000))}s`;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
// True when an abort explicitly opted into partial salvage — the error object
|
|
70
|
+
// or the abort reason carries `salvagePartial: true`. A DEADLINE-driven caller
|
|
71
|
+
// (explore hard timeout) sets it so the anchors the sub-agent already produced
|
|
72
|
+
// are returned instead of discarded; user cancellation (ESC) never sets it and
|
|
73
|
+
// keeps the throw-everything behaviour.
|
|
74
|
+
function salvagePartialRequested(error, signal) {
|
|
75
|
+
if (error && typeof error === 'object' && error.salvagePartial === true) return true;
|
|
76
|
+
const reason = signal?.reason;
|
|
77
|
+
return !!(reason && typeof reason === 'object' && reason.salvagePartial === true);
|
|
78
|
+
}
|
|
79
|
+
|
|
68
80
|
function agentCompactEventLabel(event = {}) {
|
|
69
81
|
const status = String(event.status || '').toLowerCase();
|
|
70
82
|
const reactive = String(event.trigger || '').toLowerCase() === 'reactive';
|
|
@@ -229,7 +241,7 @@ export function makeAgentDispatch(opts = {}) {
|
|
|
229
241
|
}
|
|
230
242
|
const agent = opts.agent;
|
|
231
243
|
|
|
232
|
-
return async function agentDispatch({ prompt, preset: presetArg, sourceName: sourceNameArg, parentSignal: callParentSignal, idleTimeoutMs: callIdleTimeoutMs, cwd: callCwd }) {
|
|
244
|
+
return async function agentDispatch({ prompt, preset: presetArg, sourceName: sourceNameArg, parentSignal: callParentSignal, idleTimeoutMs: callIdleTimeoutMs, cwd: callCwd, sessionId: callSessionId }) {
|
|
233
245
|
if (typeof prompt !== 'string' || !prompt) {
|
|
234
246
|
throw new Error(`[agent-dispatch] prompt required for agent "${agent}"`);
|
|
235
247
|
}
|
|
@@ -243,6 +255,7 @@ export function makeAgentDispatch(opts = {}) {
|
|
|
243
255
|
lease = await admission.acquire('agent', {
|
|
244
256
|
signal: admissionAbortLink.signal,
|
|
245
257
|
label: agent,
|
|
258
|
+
ownerKey: callSessionId || opts.ownerSessionId || opts.parentSessionId || opts.sessionId || null,
|
|
246
259
|
});
|
|
247
260
|
} catch (error) {
|
|
248
261
|
admissionAbortLink.dispose();
|
|
@@ -470,7 +483,10 @@ export function makeAgentDispatch(opts = {}) {
|
|
|
470
483
|
try { closeSession(session.id, 'ephemeral-done'); } catch { /* ignore */ }
|
|
471
484
|
return out;
|
|
472
485
|
} catch (err) {
|
|
473
|
-
const partial = watchdogPartialHandoffFromError(err, getSession(session.id), _handoffMsgStart)
|
|
486
|
+
const partial = watchdogPartialHandoffFromError(err, getSession(session.id), _handoffMsgStart)
|
|
487
|
+
?? (salvagePartialRequested(err, _abortLink?.signal)
|
|
488
|
+
? partialHandoffTextFromSession(getSession(session.id), _handoffMsgStart)
|
|
489
|
+
: null);
|
|
474
490
|
if (partial) {
|
|
475
491
|
terminalStatus = 'idle';
|
|
476
492
|
try { closeSession(session.id, 'ephemeral-done'); } catch { /* ignore */ }
|
|
@@ -7,10 +7,26 @@
|
|
|
7
7
|
import { appendAgentTrace } from '../agent-trace-io.mjs';
|
|
8
8
|
import { getHiddenAgent } from '../internal-agents.mjs';
|
|
9
9
|
import {
|
|
10
|
+
PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS,
|
|
11
|
+
PROVIDER_WS_SEMANTIC_IDLE_TIMEOUT_MS,
|
|
12
|
+
STALL_TICK_MS,
|
|
10
13
|
resolveAgentStallThresholds,
|
|
11
14
|
resolveAgentToolThresholdSeconds,
|
|
12
15
|
} from '../stall-policy.mjs';
|
|
13
16
|
|
|
17
|
+
// Ordering guarantee, stated in stall-policy.mjs: the provider layer — which
|
|
18
|
+
// can retry in place or fall back to non-streaming — must fire STRICTLY before
|
|
19
|
+
// the agent watchdog's terminal abort. Role abort budgets (worker/reviewer
|
|
20
|
+
// 300s, explore 240s) sat at or BELOW the provider semantic-idle window
|
|
21
|
+
// (300s), inverting that order: the watchdog aborted the shared signal first,
|
|
22
|
+
// so the provider's recovery never ran and the `agent_stall` failure — which
|
|
23
|
+
// the classifier calls retryable — died on throwIfAborted instead. Hold the
|
|
24
|
+
// role-derived idle budget at one watchdog tick above the provider window.
|
|
25
|
+
const PROVIDER_RECOVERY_FLOOR_MS = Math.max(
|
|
26
|
+
PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS,
|
|
27
|
+
PROVIDER_WS_SEMANTIC_IDLE_TIMEOUT_MS,
|
|
28
|
+
) + STALL_TICK_MS;
|
|
29
|
+
|
|
14
30
|
const WATCHDOG_ABORT_RE = /^agent (?:first (?:transport|semantic response|response) stale|task stale|tool running stale)\s*\(/;
|
|
15
31
|
|
|
16
32
|
/**
|
|
@@ -123,6 +139,16 @@ export function watchdogPartialHandoffFromError(error, session, messageStartInde
|
|
|
123
139
|
return text.trim() ? text : null;
|
|
124
140
|
}
|
|
125
141
|
|
|
142
|
+
// Salvage path for NON-watchdog aborts that explicitly opt in (the abort error
|
|
143
|
+
// / abort reason carries `salvagePartial: true` — e.g. the explore wall-clock
|
|
144
|
+
// hard timeout). Same collection rule as the watchdog handoff: only assistant
|
|
145
|
+
// text appended during this run. Plain user cancellation never opts in, so ESC
|
|
146
|
+
// still discards the run.
|
|
147
|
+
export function partialHandoffTextFromSession(session, messageStartIndex = 0) {
|
|
148
|
+
const text = collectSessionAssistantHandoffText(session, messageStartIndex);
|
|
149
|
+
return text.trim() ? text : null;
|
|
150
|
+
}
|
|
151
|
+
|
|
126
152
|
function resolveWatchdogAbortElapsedMs({ error, snapshot, policy, now, anchorTs, lastProgressAt }) {
|
|
127
153
|
if (snapshot && policy) {
|
|
128
154
|
if (snapshot.waitingForFirstActivity) {
|
|
@@ -223,7 +249,8 @@ export function resolveAgentWatchdogPolicy(agent, overrides = {}) {
|
|
|
223
249
|
idleStaleMs = Math.floor(overrides.idleTimeoutMs);
|
|
224
250
|
} else if (getHiddenAgent(agent)) {
|
|
225
251
|
const { abort } = resolveAgentStallThresholds(agent);
|
|
226
|
-
|
|
252
|
+
// Role budget, floored so the provider recovery window always wins.
|
|
253
|
+
idleStaleMs = Math.max(abort * 1000, PROVIDER_RECOVERY_FLOOR_MS);
|
|
227
254
|
} else {
|
|
228
255
|
// Part B: the primary mid-stream stall catch is now the provider-level
|
|
229
256
|
// SEMANTIC idle abort (~120s, ping-immune). This public-agent idle is a
|
|
@@ -238,6 +265,9 @@ export function resolveAgentWatchdogPolicy(agent, overrides = {}) {
|
|
|
238
265
|
idleStaleMs = backstopMs > 0
|
|
239
266
|
? Math.min(DEFAULT_STALE_TIMEOUT_MS, backstopMs)
|
|
240
267
|
: DEFAULT_STALE_TIMEOUT_MS;
|
|
268
|
+
// Same floor for the public backstop: a workflow role (worker 300s,
|
|
269
|
+
// explore 240s) must not undercut the provider window either.
|
|
270
|
+
idleStaleMs = Math.max(idleStaleMs, PROVIDER_RECOVERY_FLOOR_MS);
|
|
241
271
|
}
|
|
242
272
|
|
|
243
273
|
const idleSec = idleStaleMs / 1000;
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { configuredAgentRouteCandidates } from '../../../shared/agent-route-config.mjs';
|
|
2
2
|
import { loadConfig } from '../config.mjs';
|
|
3
3
|
import { getHiddenAgent } from '../internal-agents.mjs';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function normalizeMaintenanceCandidate(candidate, config) {
|
|
5
|
+
function normalizeMaintenanceCandidate(candidate) {
|
|
8
6
|
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) return candidate || null;
|
|
9
|
-
const
|
|
10
|
-
const fallbackProvider = isKnownProvider(configuredProvider)
|
|
11
|
-
? configuredProvider
|
|
12
|
-
: DEFAULT_AGENT_ROUTE_PROVIDER;
|
|
13
|
-
const provider = String(candidate.provider || fallbackProvider).trim();
|
|
7
|
+
const provider = String(candidate.provider || '').trim();
|
|
14
8
|
const model = String(candidate.model || '').trim();
|
|
15
9
|
if (!provider || !model) return null;
|
|
16
10
|
return {
|
|
@@ -34,20 +28,15 @@ export function resolveMaintenanceRoute({ preset, optsPreset, agent, config: cfg
|
|
|
34
28
|
if (hidden) {
|
|
35
29
|
try {
|
|
36
30
|
const config = cfgIn || loadConfig({ secrets: false });
|
|
37
|
-
const maint = config?.maintenance || {};
|
|
38
31
|
const key = hidden.maintKey || hidden.slot;
|
|
39
32
|
const role = key === 'explore' ? 'explore' : (key === 'memory' ? 'maintainer' : '');
|
|
40
|
-
|
|
41
|
-
if (!role) return maint[key] ?? null;
|
|
33
|
+
if (!role) return config?.maintenance?.[key] ?? null;
|
|
42
34
|
const candidates = [
|
|
43
|
-
|
|
44
|
-
key === 'memory' ? config?.agents?.maintenance : null,
|
|
45
|
-
workflowSlot ? config?.workflowRoutes?.[workflowSlot] : null,
|
|
46
|
-
maint[key],
|
|
35
|
+
...configuredAgentRouteCandidates(config, role),
|
|
47
36
|
role ? config?.default : null,
|
|
48
37
|
];
|
|
49
38
|
for (const candidate of candidates) {
|
|
50
|
-
const route = normalizeMaintenanceCandidate(candidate
|
|
39
|
+
const route = normalizeMaintenanceCandidate(candidate);
|
|
51
40
|
if (route) return route;
|
|
52
41
|
}
|
|
53
42
|
return null;
|
|
@@ -31,7 +31,16 @@ function compactRecoveredErrorMessage(value) {
|
|
|
31
31
|
: message;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function traceAgentLoop({
|
|
34
|
+
function traceAgentLoop({
|
|
35
|
+
sessionId,
|
|
36
|
+
iteration,
|
|
37
|
+
sendMs,
|
|
38
|
+
preSendMs,
|
|
39
|
+
toolResumeMs,
|
|
40
|
+
messageCount,
|
|
41
|
+
bodyBytesEst,
|
|
42
|
+
agent = null,
|
|
43
|
+
}) {
|
|
35
44
|
// Two emit modes, no behavior change either way:
|
|
36
45
|
// VERBOSE=1 → full loop row incl. body_bytes_est (payload serialized).
|
|
37
46
|
// TIMING=1 → lightweight send-latency attribution for high-fanout
|
|
@@ -45,6 +54,8 @@ function traceAgentLoop({ sessionId, iteration, sendMs, messageCount, bodyBytesE
|
|
|
45
54
|
kind: 'loop',
|
|
46
55
|
agent: agent || null,
|
|
47
56
|
send_ms: sendMs,
|
|
57
|
+
pre_send_ms: preSendMs ?? null,
|
|
58
|
+
tool_resume_ms: toolResumeMs ?? null,
|
|
48
59
|
message_count: messageCount,
|
|
49
60
|
body_bytes_est: bodyBytesEst ?? null,
|
|
50
61
|
});
|