mixdog 0.8.1 → 0.9.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/README.md +47 -23
- package/package.json +34 -28
- package/scripts/_test-folder-dialog.mjs +30 -0
- package/scripts/agent-parallel-smoke.mjs +388 -0
- package/scripts/agent-tag-reuse-smoke.mjs +183 -0
- package/scripts/background-task-meta-smoke.mjs +38 -0
- package/scripts/boot-smoke.mjs +52 -9
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/compact-active-turn-test.mjs +68 -0
- package/scripts/compact-smoke.mjs +859 -129
- package/scripts/compact-trigger-migration-smoke.mjs +187 -0
- package/scripts/fix-brief-fn.mjs +35 -0
- package/scripts/fix-format-tool-surface.mjs +24 -0
- package/scripts/fix-tool-exec-visible.mjs +42 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/hook-bus-test.mjs +330 -0
- package/scripts/lead-workflow-smoke.mjs +33 -39
- package/scripts/live-worker-smoke.mjs +43 -37
- package/scripts/llm-trace-summary.mjs +315 -0
- package/scripts/memory-meta-concurrency-test.mjs +20 -0
- package/scripts/output-style-smoke.mjs +56 -15
- package/scripts/parent-abort-link-test.mjs +44 -0
- package/scripts/patch-agent-brief.mjs +48 -0
- package/scripts/patch-app.mjs +21 -0
- package/scripts/patch-app2.mjs +18 -0
- package/scripts/patch-dist-brief.mjs +96 -0
- package/scripts/patch-tool-exec.mjs +70 -0
- package/scripts/pretool-ask-runtime-test.mjs +54 -0
- package/scripts/provider-toolcall-test.mjs +376 -0
- package/scripts/reactive-compact-persist-smoke.mjs +124 -0
- package/scripts/sanitize-tool-pairs-test.mjs +260 -0
- package/scripts/session-context-bench.mjs +205 -33
- package/scripts/session-ingest-smoke.mjs +177 -0
- package/scripts/set-effort-config-test.mjs +41 -0
- package/scripts/smoke-runtime-negative.ps1 +106 -0
- package/scripts/smoke-runtime-negative.sh +97 -0
- package/scripts/smoke.mjs +25 -0
- package/scripts/tool-result-hook-test.mjs +48 -0
- package/scripts/tool-smoke.mjs +1222 -90
- package/scripts/toolcall-args-test.mjs +150 -0
- package/scripts/tui-background-failure-smoke.mjs +73 -0
- package/scripts/usage-metrics-epoch-smoke.mjs +114 -0
- package/src/agents/debugger/AGENT.md +8 -0
- package/src/agents/explore/AGENT.md +4 -0
- package/src/agents/heavy-worker/AGENT.md +9 -3
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +8 -0
- package/src/agents/scheduler-task/AGENT.md +12 -0
- package/src/agents/scheduler-task/agent.json +6 -0
- package/src/agents/webhook-handler/AGENT.md +12 -0
- package/src/agents/webhook-handler/agent.json +6 -0
- package/src/agents/worker/AGENT.md +9 -3
- package/src/app.mjs +77 -3
- package/src/defaults/hidden-roles.json +17 -12
- package/src/headless-role.mjs +117 -0
- package/src/help.mjs +30 -0
- package/src/hooks/lib/permission-evaluator.cjs +11 -475
- package/src/lib/keychain-cjs.cjs +9 -1
- package/src/lib/mixdog-debug.cjs +0 -29
- package/src/lib/plugin-paths.cjs +1 -7
- package/src/lib/rules-builder.cjs +242 -98
- package/src/lib/text-utils.cjs +1 -1
- package/src/mixdog-session-runtime.mjs +2211 -446
- package/src/output-styles/default.md +12 -28
- package/src/output-styles/extreme-simple.md +9 -6
- package/src/output-styles/simple.md +22 -9
- package/src/repl.mjs +108 -59
- package/src/rules/agent/00-common.md +15 -0
- package/src/rules/{bridge → agent}/20-skip-protocol.md +1 -2
- package/src/rules/agent/30-explorer.md +22 -0
- package/src/rules/{bridge → agent}/40-cycle1-agent.md +7 -0
- package/src/rules/{bridge → agent}/41-cycle2-agent.md +7 -0
- package/src/rules/{bridge → agent}/42-cycle3-agent.md +7 -0
- package/src/rules/lead/01-general.md +9 -5
- package/src/rules/lead/04-workflow.md +51 -12
- package/src/rules/lead/lead-tool.md +6 -0
- package/src/rules/shared/01-tool.md +12 -1
- package/src/runtime/agent/orchestrator/activity-bus.mjs +7 -18
- package/src/runtime/agent/orchestrator/agent-owner.mjs +11 -0
- package/src/runtime/agent/orchestrator/{smart-bridge/bridge-llm.mjs → agent-runtime/agent-dispatch.mjs} +138 -111
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +94 -0
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/cache-strategy.mjs +32 -23
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/session-builder.mjs +33 -27
- package/src/runtime/agent/orchestrator/{bridge-trace.mjs → agent-trace.mjs} +132 -81
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +0 -21
- package/src/runtime/agent/orchestrator/config.mjs +174 -55
- package/src/runtime/agent/orchestrator/context/collect.mjs +195 -487
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-roles.mjs +77 -29
- package/src/runtime/agent/orchestrator/internal-tools.mjs +5 -6
- package/src/runtime/agent/orchestrator/mcp/client.mjs +15 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +380 -268
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +131 -93
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +236 -4
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +49 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +58 -13
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +67 -149
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +132 -2
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +61 -116
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +25 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +79 -255
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +203 -71
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +512 -312
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +343 -518
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/registry.mjs +88 -51
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +289 -11
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +41 -8
- package/src/runtime/agent/orchestrator/session/compact.mjs +1173 -267
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +199 -36
- package/src/runtime/agent/orchestrator/session/loop.mjs +840 -612
- package/src/runtime/agent/orchestrator/session/manager.mjs +1574 -459
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +107 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +67 -29
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +31 -16
- package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +3 -219
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +35 -8
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +19 -8
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -53
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +60 -37
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +21 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -7
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -3
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +36 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +5 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -36
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +2 -40
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +148 -27
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +43 -75
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +90 -20
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -5
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +86 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4106 -4019
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +33 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +90 -6
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +6 -4
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +8 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -4
- package/src/runtime/channels/index.mjs +149 -51
- package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
- package/src/runtime/channels/lib/config.mjs +0 -1
- package/src/runtime/channels/lib/drop-trace.mjs +1 -1
- package/src/runtime/channels/lib/executor.mjs +0 -3
- package/src/runtime/channels/lib/memory-client.mjs +0 -38
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -8
- package/src/runtime/channels/lib/runtime-paths.mjs +0 -6
- package/src/runtime/channels/lib/scheduler.mjs +18 -14
- package/src/runtime/channels/lib/session-discovery.mjs +3 -6
- package/src/runtime/channels/lib/tool-format.mjs +0 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -12
- package/src/runtime/channels/lib/webhook.mjs +1 -1
- package/src/runtime/channels/tool-defs.mjs +29 -29
- package/src/runtime/lib/keychain-cjs.cjs +0 -1
- package/src/runtime/memory/data/runtime-manifest.json +6 -7
- package/src/runtime/memory/index.mjs +519 -118
- package/src/runtime/memory/lib/agent-ipc.mjs +29 -12
- package/src/runtime/memory/lib/core-memory-store.mjs +2 -2
- package/src/runtime/memory/lib/embedding-model-config.mjs +55 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +31 -4
- package/src/runtime/memory/lib/embedding-worker.mjs +19 -10
- package/src/runtime/memory/lib/llm-worker-host.mjs +0 -4
- package/src/runtime/memory/lib/memory-cycle1.mjs +28 -7
- package/src/runtime/memory/lib/memory-cycle2.mjs +4 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +2 -2
- package/src/runtime/memory/lib/memory-ops-policy.mjs +2 -2
- package/src/runtime/memory/lib/memory-session-merge.mjs +38 -0
- package/src/runtime/memory/lib/memory.mjs +88 -9
- package/src/runtime/memory/lib/model-profile.mjs +1 -1
- package/src/runtime/memory/lib/pg/adapter.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +12 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +80 -21
- package/src/runtime/memory/lib/session-ingest.mjs +196 -0
- package/src/runtime/memory/lib/trace-store.mjs +96 -51
- package/src/runtime/memory/tool-defs.mjs +46 -37
- package/src/runtime/search/index.mjs +104 -473
- package/src/runtime/search/lib/config.mjs +0 -4
- package/src/runtime/search/lib/state.mjs +1 -15
- package/src/runtime/search/lib/web-tools.mjs +44 -25
- package/src/runtime/search/tool-defs.mjs +16 -23
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +4 -3
- package/src/runtime/shared/background-tasks.mjs +122 -11
- package/src/runtime/shared/child-spawn-gate.mjs +139 -0
- package/src/runtime/shared/config.mjs +7 -4
- package/src/runtime/shared/err-text.mjs +131 -4
- package/src/runtime/shared/llm/cost.mjs +2 -2
- package/src/runtime/shared/llm/http-agent.mjs +23 -7
- package/src/runtime/shared/llm/index.mjs +34 -11
- package/src/runtime/shared/llm/usage-log.mjs +4 -4
- package/src/runtime/shared/markdown-frontmatter.mjs +56 -0
- package/src/runtime/shared/singleton-owner.mjs +104 -0
- package/src/runtime/shared/tool-execution-contract.mjs +199 -20
- package/src/runtime/shared/tool-execution-contract.test.mjs +183 -0
- package/src/runtime/shared/tool-surface.mjs +624 -95
- package/src/runtime/shared/user-data-guard.mjs +0 -2
- package/src/standalone/agent-task-status.mjs +203 -0
- package/src/standalone/agent-task-status.test.mjs +76 -0
- package/src/standalone/agent-tool.mjs +1913 -0
- package/src/standalone/channel-worker.mjs +370 -14
- package/src/standalone/explore-tool.mjs +165 -70
- package/src/standalone/folder-dialog.mjs +314 -0
- package/src/standalone/hook-bus.mjs +898 -22
- package/src/standalone/memory-runtime-proxy.mjs +320 -0
- package/src/standalone/projects.mjs +226 -0
- package/src/standalone/provider-admin.mjs +41 -24
- package/src/standalone/seeds.mjs +1 -78
- package/src/standalone/usage-dashboard.mjs +96 -8
- package/src/tui/App.jsx +4800 -2140
- package/src/tui/components/AnsiText.jsx +39 -28
- package/src/tui/components/ContextPanel.jsx +14 -4
- package/src/tui/components/Markdown.jsx +43 -77
- package/src/tui/components/MarkdownTable.jsx +9 -184
- package/src/tui/components/Message.jsx +28 -11
- package/src/tui/components/Picker.jsx +95 -56
- package/src/tui/components/PromptInput.jsx +428 -239
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +27 -21
- package/src/tui/components/Spinner.jsx +67 -38
- package/src/tui/components/StatusLine.jsx +606 -38
- package/src/tui/components/TextEntryPanel.jsx +128 -9
- package/src/tui/components/ToolExecution.jsx +597 -362
- package/src/tui/components/TurnDone.jsx +3 -3
- package/src/tui/components/UsagePanel.jsx +3 -5
- package/src/tui/components/tool-output-format.mjs +499 -0
- package/src/tui/components/tool-output-format.test.mjs +312 -0
- package/src/tui/dist/index.mjs +9192 -2399
- package/src/tui/engine-runtime-notification.test.mjs +115 -0
- package/src/tui/engine-tool-result-text.test.mjs +75 -0
- package/src/tui/engine.mjs +1455 -279
- package/src/tui/figures.mjs +21 -40
- package/src/tui/index.jsx +75 -31
- package/src/tui/input-editing.mjs +25 -0
- package/src/tui/markdown/format-token.mjs +671 -69
- package/src/tui/markdown/format-token.test.mjs +312 -0
- package/src/tui/markdown/render-ansi.mjs +94 -0
- package/src/tui/markdown/render-ansi.test.mjs +108 -0
- package/src/tui/markdown/stream-fence.mjs +34 -0
- package/src/tui/markdown/stream-fence.test.mjs +26 -0
- package/src/tui/markdown/table-layout.mjs +250 -0
- package/src/tui/paste-attachments.mjs +0 -7
- package/src/tui/spinner-verbs.mjs +1 -2
- package/src/tui/statusline-ansi-bridge.mjs +172 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +159 -0
- package/src/tui/theme.mjs +756 -24
- package/src/tui/time-format.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +67 -0
- package/src/tui/transcript-tool-failures.test.mjs +111 -0
- package/src/ui/ansi.mjs +1 -2
- package/src/ui/markdown.mjs +85 -26
- package/src/ui/markdown.test.mjs +70 -0
- package/src/ui/model-display.mjs +121 -0
- package/src/ui/session-stats.mjs +44 -0
- package/src/ui/statusline-context-label.test.mjs +15 -0
- package/src/ui/statusline.mjs +386 -178
- package/src/ui/tool-card.mjs +2 -13
- package/src/vendor/statusline/bin/statusline-lib.mjs +1 -620
- package/src/vendor/statusline/bin/statusline-route.mjs +169 -37
- package/src/vendor/statusline/bin/statusline-route.test.mjs +80 -0
- package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +3 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +1 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +44 -6
- package/src/vendor/statusline/src/gateway/session-routes.mjs +1 -1
- package/src/workflows/default/WORKFLOW.md +12 -5
- package/src/workflows/default/workflow.json +0 -1
- package/src/workflows/solo/WORKFLOW.md +15 -0
- package/src/workflows/solo/workflow.json +7 -0
- package/vendor/ink/build/ink.js +54 -8
- package/vendor/ink/build/output.js +6 -1
- package/src/agents/scheduler-task.md +0 -3
- package/src/agents/web-researcher/AGENT.md +0 -3
- package/src/agents/web-researcher/agent.json +0 -6
- package/src/agents/webhook-handler.md +0 -3
- package/src/hooks/lib/permission-rules.cjs +0 -170
- package/src/hooks/lib/settings-loader.cjs +0 -112
- package/src/lib/hook-pipe-path.cjs +0 -10
- package/src/rules/bridge/00-common.md +0 -5
- package/src/rules/bridge/30-explorer.md +0 -4
- package/src/rules/lead/00-tool-lead.md +0 -5
- package/src/rules/shared/00-language.md +0 -3
- package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
- package/src/runtime/agent/orchestrator/tools/mutation-content-cache.mjs +0 -67
- package/src/runtime/channels/lib/hook-pipe-server.mjs +0 -671
- package/src/runtime/memory/lib/bridge-trace-queries.mjs +0 -120
- package/src/runtime/shared/llm/pid-cleanup.mjs +0 -27
- package/src/standalone/bridge-tool.mjs +0 -1414
- package/src/tui/runtime/shared/process-shutdown.mjs +0 -1
|
@@ -24,7 +24,6 @@ const RECOVERY_NOTICE = 'RECOVERY-REQUIRED.txt';
|
|
|
24
24
|
|
|
25
25
|
const USER_DATA_FILES = [
|
|
26
26
|
'mixdog-config.json',
|
|
27
|
-
'user-workflow.json',
|
|
28
27
|
'user-workflow.md',
|
|
29
28
|
'history/user.md',
|
|
30
29
|
'history/bot.md',
|
|
@@ -33,7 +32,6 @@ const USER_DATA_FILES = [
|
|
|
33
32
|
const USER_DATA_DIRS = [
|
|
34
33
|
'schedules',
|
|
35
34
|
'webhooks',
|
|
36
|
-
'roles',
|
|
37
35
|
'workflows',
|
|
38
36
|
];
|
|
39
37
|
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import {
|
|
2
|
+
agentWatchdogPolicyActive,
|
|
3
|
+
evaluateAgentWatchdogAbort,
|
|
4
|
+
} from '../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
5
|
+
|
|
6
|
+
const ACTIVE_RUNTIME_STAGES = new Set([
|
|
7
|
+
'connecting',
|
|
8
|
+
'requesting',
|
|
9
|
+
'streaming',
|
|
10
|
+
'tool_running',
|
|
11
|
+
'running',
|
|
12
|
+
'cancelling',
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
function positiveSeconds(now, ts) {
|
|
16
|
+
const n = Number(ts);
|
|
17
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
18
|
+
return Math.max(0, Math.floor((now - n) / 1000));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function formatAgentWatchdogSummary(policy) {
|
|
22
|
+
if (!policy || !agentWatchdogPolicyActive(policy)) return null;
|
|
23
|
+
const parts = [];
|
|
24
|
+
if (policy.firstResponseMs > 0) parts.push(`first=${Math.round(policy.firstResponseMs / 1000)}s`);
|
|
25
|
+
if (policy.idleStaleMs > 0) parts.push(`idle=${Math.round(policy.idleStaleMs / 1000)}s`);
|
|
26
|
+
if (policy.toolRunningMs > 0) parts.push(`tool=${Math.round(policy.toolRunningMs / 1000)}s`);
|
|
27
|
+
return parts.length ? `armed ${parts.join(' ')}` : null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function resolveSilentForSeconds(now, snapshot, runtime) {
|
|
31
|
+
const last = Math.max(
|
|
32
|
+
snapshot?.lastProgressAt || 0,
|
|
33
|
+
runtime?.lastProgressAt || 0,
|
|
34
|
+
snapshot?.lastStreamDeltaAt || 0,
|
|
35
|
+
runtime?.lastStreamDeltaAt || 0,
|
|
36
|
+
snapshot?.toolStartedAt || 0,
|
|
37
|
+
runtime?.toolStartedAt || 0,
|
|
38
|
+
snapshot?.askStartedAt || 0,
|
|
39
|
+
runtime?.askStartedAt || 0,
|
|
40
|
+
);
|
|
41
|
+
return positiveSeconds(now, last);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function buildAgentTaskProgressFields({
|
|
45
|
+
now = Date.now(),
|
|
46
|
+
sessionStatus = null,
|
|
47
|
+
runtimeStage = null,
|
|
48
|
+
snapshot = null,
|
|
49
|
+
runtime = null,
|
|
50
|
+
policy = null,
|
|
51
|
+
queuedFollowups = null,
|
|
52
|
+
taskStatus = null,
|
|
53
|
+
lastToolCall = null,
|
|
54
|
+
} = {}) {
|
|
55
|
+
const stage = cleanStage(runtimeStage || snapshot?.stage || sessionStatus || 'unknown');
|
|
56
|
+
const workerStage = stage;
|
|
57
|
+
const silentFor = resolveSilentForSeconds(now, snapshot, runtime);
|
|
58
|
+
const watchdog = formatAgentWatchdogSummary(policy);
|
|
59
|
+
const queued = Number.isFinite(Number(queuedFollowups)) && Number(queuedFollowups) > 0
|
|
60
|
+
? Math.floor(Number(queuedFollowups))
|
|
61
|
+
: null;
|
|
62
|
+
|
|
63
|
+
const lastProgress = describeLastProgress({
|
|
64
|
+
stage,
|
|
65
|
+
snapshot,
|
|
66
|
+
runtime,
|
|
67
|
+
silentFor,
|
|
68
|
+
lastToolCall: lastToolCall || runtime?.lastToolCall || null,
|
|
69
|
+
now,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const diagnostic = describeAgentDiagnostic({
|
|
73
|
+
taskStatus,
|
|
74
|
+
sessionStatus,
|
|
75
|
+
stage,
|
|
76
|
+
snapshot,
|
|
77
|
+
silentFor,
|
|
78
|
+
queued,
|
|
79
|
+
policy,
|
|
80
|
+
now,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const out = {
|
|
84
|
+
worker_stage: workerStage,
|
|
85
|
+
last_progress: lastProgress,
|
|
86
|
+
diagnostic,
|
|
87
|
+
};
|
|
88
|
+
if (silentFor != null && ACTIVE_RUNTIME_STAGES.has(stage)) out.silent_for = silentFor;
|
|
89
|
+
if (watchdog) out.watchdog = watchdog;
|
|
90
|
+
if (queued != null) out.queued_followups = queued;
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function cleanStage(value) {
|
|
95
|
+
return String(value ?? '').trim() || 'unknown';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function describeLastProgress({ stage, snapshot, runtime, silentFor, lastToolCall, now }) {
|
|
99
|
+
if (snapshot?.waitingForFirstActivity) return 'awaiting first model response';
|
|
100
|
+
if (stage === 'tool_running') {
|
|
101
|
+
const tool = cleanStage(lastToolCall);
|
|
102
|
+
return tool && tool !== 'unknown' ? `tool: ${tool}` : 'tool running';
|
|
103
|
+
}
|
|
104
|
+
if (stage === 'connecting' || stage === 'requesting') return 'connecting to model';
|
|
105
|
+
if (stage === 'streaming') {
|
|
106
|
+
const streamSilent = positiveSeconds(
|
|
107
|
+
now,
|
|
108
|
+
snapshot?.lastStreamDeltaAt || runtime?.lastStreamDeltaAt || 0,
|
|
109
|
+
);
|
|
110
|
+
if (streamSilent != null && streamSilent >= 5) {
|
|
111
|
+
return `streaming (no stream delta for ${streamSilent}s)`;
|
|
112
|
+
}
|
|
113
|
+
return 'streaming';
|
|
114
|
+
}
|
|
115
|
+
if (stage === 'cancelling') return 'cancelling';
|
|
116
|
+
if (stage === 'done' || stage === 'idle') {
|
|
117
|
+
if (runtime?.emptyFinal) return 'finished empty';
|
|
118
|
+
return 'idle';
|
|
119
|
+
}
|
|
120
|
+
if (stage === 'error') return 'error';
|
|
121
|
+
if (stage === 'closed') return 'closed';
|
|
122
|
+
if (silentFor != null && ACTIVE_RUNTIME_STAGES.has(stage)) {
|
|
123
|
+
return `active (${silentFor}s since last progress)`;
|
|
124
|
+
}
|
|
125
|
+
return stage;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function describeAgentDiagnostic({
|
|
129
|
+
taskStatus,
|
|
130
|
+
sessionStatus,
|
|
131
|
+
stage,
|
|
132
|
+
snapshot,
|
|
133
|
+
silentFor,
|
|
134
|
+
queued,
|
|
135
|
+
policy,
|
|
136
|
+
now,
|
|
137
|
+
}) {
|
|
138
|
+
const normalizedTask = cleanStage(taskStatus).toLowerCase();
|
|
139
|
+
if (normalizedTask === 'cancelled' || normalizedTask === 'canceled') return 'task cancelled';
|
|
140
|
+
if (normalizedTask === 'failed' || normalizedTask === 'error') return 'task failed';
|
|
141
|
+
if (normalizedTask === 'completed') {
|
|
142
|
+
return sessionStatus === 'error' ? 'task completed (worker error)' : 'task completed; worker idle';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (queued) {
|
|
146
|
+
if (ACTIVE_RUNTIME_STAGES.has(stage)) {
|
|
147
|
+
return `${stage}, ${queued} follow-up${queued === 1 ? '' : 's'} queued`;
|
|
148
|
+
}
|
|
149
|
+
return `idle, ${queued} follow-up${queued === 1 ? '' : 's'} queued`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (snapshot?.waitingForFirstActivity) return 'waiting for first response';
|
|
153
|
+
|
|
154
|
+
if (stage === 'streaming') {
|
|
155
|
+
const streamSilent = positiveSeconds(
|
|
156
|
+
now,
|
|
157
|
+
snapshot?.lastStreamDeltaAt || 0,
|
|
158
|
+
);
|
|
159
|
+
if (streamSilent != null && streamSilent >= 5) {
|
|
160
|
+
return `streaming, no visible output yet (${streamSilent}s)`;
|
|
161
|
+
}
|
|
162
|
+
return 'streaming';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (stage === 'tool_running') return 'tool running';
|
|
166
|
+
if (stage === 'connecting' || stage === 'requesting') return 'waiting for first response';
|
|
167
|
+
|
|
168
|
+
if (silentFor != null && policy && ACTIVE_RUNTIME_STAGES.has(stage)) {
|
|
169
|
+
const abortErr = evaluateAgentWatchdogAbort(
|
|
170
|
+
snapshot || { stage, lastProgressAt: now - silentFor * 1000 },
|
|
171
|
+
now,
|
|
172
|
+
policy,
|
|
173
|
+
);
|
|
174
|
+
if (abortErr) {
|
|
175
|
+
return `stale: ${abortErr.message.replace(/^agent /i, '')}`;
|
|
176
|
+
}
|
|
177
|
+
if (silentFor >= 30) {
|
|
178
|
+
return `stale: no stream/tool progress for ${silentFor}s`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (normalizedTask === 'running' && (stage === 'idle' || stage === 'done')) {
|
|
183
|
+
return 'task running; worker turn finished, awaiting job reconciliation';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (stage === 'idle' || stage === 'done') return 'idle';
|
|
187
|
+
if (stage === 'cancelling') return 'cancelling';
|
|
188
|
+
if (stage === 'error') return 'worker error';
|
|
189
|
+
if (stage === 'closed') return 'closed';
|
|
190
|
+
|
|
191
|
+
return stage;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function appendAgentProgressKv(line, fields = {}) {
|
|
195
|
+
const parts = [line];
|
|
196
|
+
if (fields.worker_stage) parts.push(`stage=${fields.worker_stage}`);
|
|
197
|
+
if (fields.last_progress) parts.push(`last_progress=${fields.last_progress}`);
|
|
198
|
+
if (Number.isFinite(fields.silent_for)) parts.push(`silent_for=${fields.silent_for}s`);
|
|
199
|
+
if (fields.watchdog) parts.push(`watchdog=${fields.watchdog}`);
|
|
200
|
+
if (Number.isFinite(fields.queued_followups)) parts.push(`queued_followups=${fields.queued_followups}`);
|
|
201
|
+
if (fields.diagnostic) parts.push(`hint=${fields.diagnostic}`);
|
|
202
|
+
return parts.join(' ');
|
|
203
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import {
|
|
4
|
+
appendAgentProgressKv,
|
|
5
|
+
buildAgentTaskProgressFields,
|
|
6
|
+
resolveSilentForSeconds,
|
|
7
|
+
} from './agent-task-status.mjs';
|
|
8
|
+
|
|
9
|
+
test('waiting for first activity explains silence', () => {
|
|
10
|
+
const now = 1_000_000;
|
|
11
|
+
const fields = buildAgentTaskProgressFields({
|
|
12
|
+
now,
|
|
13
|
+
sessionStatus: 'running',
|
|
14
|
+
runtimeStage: 'requesting',
|
|
15
|
+
snapshot: {
|
|
16
|
+
stage: 'requesting',
|
|
17
|
+
waitingForFirstActivity: true,
|
|
18
|
+
modelRequestStartedAt: now - 12_000,
|
|
19
|
+
askStartedAt: now - 12_000,
|
|
20
|
+
lastProgressAt: now - 12_000,
|
|
21
|
+
},
|
|
22
|
+
policy: { firstResponseMs: 120_000, idleStaleMs: 1_800_000, toolRunningMs: 600_000 },
|
|
23
|
+
taskStatus: 'running',
|
|
24
|
+
});
|
|
25
|
+
assert.equal(fields.last_progress, 'awaiting first model response');
|
|
26
|
+
assert.match(fields.diagnostic, /waiting for first response/);
|
|
27
|
+
assert.match(fields.watchdog, /first=120s/);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('streaming without recent deltas is called out', () => {
|
|
31
|
+
const now = 2_000_000;
|
|
32
|
+
const fields = buildAgentTaskProgressFields({
|
|
33
|
+
now,
|
|
34
|
+
sessionStatus: 'running',
|
|
35
|
+
runtimeStage: 'streaming',
|
|
36
|
+
snapshot: {
|
|
37
|
+
stage: 'streaming',
|
|
38
|
+
waitingForFirstActivity: false,
|
|
39
|
+
lastStreamDeltaAt: now - 23_000,
|
|
40
|
+
lastProgressAt: now - 23_000,
|
|
41
|
+
},
|
|
42
|
+
taskStatus: 'running',
|
|
43
|
+
});
|
|
44
|
+
assert.match(fields.last_progress, /no stream delta for 23s/);
|
|
45
|
+
assert.match(fields.diagnostic, /no visible output yet \(23s\)/);
|
|
46
|
+
assert.equal(fields.silent_for, 23);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('queued follow-ups surface on idle worker', () => {
|
|
50
|
+
const fields = buildAgentTaskProgressFields({
|
|
51
|
+
sessionStatus: 'idle',
|
|
52
|
+
runtimeStage: 'streaming',
|
|
53
|
+
queuedFollowups: 2,
|
|
54
|
+
taskStatus: 'running',
|
|
55
|
+
});
|
|
56
|
+
assert.equal(fields.queued_followups, 2);
|
|
57
|
+
assert.match(fields.diagnostic, /2 follow-ups queued/);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('resolveSilentForSeconds uses latest progress signal', () => {
|
|
61
|
+
const now = 10_000;
|
|
62
|
+
const silent = resolveSilentForSeconds(now, { lastProgressAt: now - 5_000 }, { lastStreamDeltaAt: now - 9_000 });
|
|
63
|
+
assert.equal(silent, 5);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('appendAgentProgressKv keeps base line first', () => {
|
|
67
|
+
const line = appendAgentProgressKv('- job1 spawn running', {
|
|
68
|
+
worker_stage: 'streaming',
|
|
69
|
+
silent_for: 4,
|
|
70
|
+
diagnostic: 'streaming',
|
|
71
|
+
});
|
|
72
|
+
assert.match(line, /^- job1 spawn running /);
|
|
73
|
+
assert.match(line, /stage=streaming/);
|
|
74
|
+
assert.match(line, /hint=streaming/);
|
|
75
|
+
});
|
|
76
|
+
|