mixdog 1.2.5 → 1.3.0
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/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +19 -0
- package/package.json +4 -1
- package/scripts/check-model-recommendations.mjs +89 -0
- package/scripts/gate-local.mjs +7 -0
- package/scripts/lib/gate-scheduler.mjs +2 -2
- package/scripts/lib/isolated-test-env.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +5 -14
- package/scripts/provider-pingpong-live.mjs +9 -9
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +5 -4
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +17 -0
- package/src/defaults/skills/browser-use/SKILL.md +7 -1
- package/src/defaults/skills/computer-use/SKILL.md +3 -1
- package/src/defaults/skills/memory-management/SKILL.md +4 -1
- package/src/defaults/skills/setup/references/actions.md +11 -4
- package/src/defaults/skills/setup-guide/SKILL.md +175 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/defaults/skills/visualize/SKILL.md +3 -2
- package/src/lib/rules-builder.cjs +56 -7
- package/src/output-styles/common.md +22 -6
- package/src/output-styles/detailed.md +7 -5
- package/src/output-styles/minimal.md +7 -3
- package/src/output-styles/simple.md +2 -3
- package/src/rules/agent/AGENT.md +7 -1
- package/src/rules/agent-mode/AGENT_MODE.md +24 -0
- package/src/rules/agent-mode/MIXY.md +21 -0
- package/src/rules/agent-mode/ROUTINE.md +6 -0
- package/src/rules/lead/LEAD.md +9 -4
- package/src/rules/shared/10-tool-workflow.md +2 -1
- package/src/rules/shared/60-verification.md +4 -5
- package/src/rules/shared/70-delivery.md +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
- package/src/runtime/agent/orchestrator/config.mjs +6 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +5 -3
- package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +58 -64
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
- package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +41 -19
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +11 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
- package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
- package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +98 -4
- package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +15 -8
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
- package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
- package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +82 -33
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +11 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
- package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
- package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +325 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +84 -21
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
- package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +123 -32
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
- package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
- package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +64 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +10 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +104 -55
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/office-extract.mjs +11 -9
- package/src/runtime/browser-bridge/client.mjs +24 -0
- package/src/runtime/channels/lib/scheduler.mjs +40 -12
- package/src/runtime/channels/lib/schedules-db.mjs +71 -12
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
- package/src/runtime/channels/lib/webhook.mjs +0 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
- package/src/runtime/channels/lib/worker-main.mjs +17 -20
- package/src/runtime/computer-bridge/client.mjs +28 -1
- package/src/runtime/connectors/gmail-app-password.mjs +690 -0
- package/src/runtime/connectors/google-mcp.mjs +446 -0
- package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
- package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
- package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
- package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
- package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
- package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
- package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
- package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
- package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
- package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
- package/src/runtime/memory/lib/memory.mjs +7 -1
- package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
- package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
- package/src/runtime/memory/lib/tool-call-handler.mjs +9 -5
- package/src/runtime/memory/tool-defs.mjs +5 -0
- package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
- package/src/runtime/office/core/tabular.mjs +1 -1
- package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
- package/src/runtime/office/portable/docx-formatting.mjs +1 -1
- package/src/runtime/office/portable/docx-runs.mjs +1 -1
- package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
- package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
- package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
- package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
- package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
- package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
- package/src/runtime/office/portable/portable-opc.mjs +27 -13
- package/src/runtime/office/portable/portable-pivot.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
- package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
- package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
- package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
- package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
- package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
- package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
- package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
- package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
- package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
- package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
- package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
- package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
- package/src/runtime/office/portable/portable-xml.mjs +1 -1
- package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
- package/src/runtime/shared/agent-avatar.d.mts +64 -0
- package/src/runtime/shared/agent-avatar.mjs +320 -0
- package/src/runtime/shared/agent-route-config.d.mts +3 -0
- package/src/runtime/shared/agent-route-config.mjs +16 -0
- package/src/runtime/shared/atomic-file.mjs +36 -14
- package/src/runtime/shared/background-tasks.mjs +60 -20
- package/src/runtime/shared/child-spawn-gate.mjs +26 -16
- package/src/runtime/shared/config.mjs +8 -11
- package/src/runtime/shared/connector-accounts.mjs +15 -0
- package/src/runtime/shared/connector-catalog.d.mts +52 -0
- package/src/runtime/shared/connector-catalog.mjs +230 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +43 -0
- package/src/runtime/shared/file-lock.mjs +7 -1
- package/src/runtime/shared/file-permissions-worker.mjs +38 -0
- package/src/runtime/shared/file-permissions.d.mts +19 -4
- package/src/runtime/shared/file-permissions.mjs +310 -4
- package/src/runtime/shared/git-runner-worker.mjs +6 -78
- package/src/runtime/shared/google-oauth-client.mjs +24 -0
- package/src/runtime/shared/held-request-host.d.mts +12 -0
- package/src/runtime/shared/held-request-host.mjs +71 -0
- package/src/runtime/shared/llm/http-agent.mjs +7 -3
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
- package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
- package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
- package/src/runtime/shared/memory-snapshot.mjs +5 -1
- package/src/runtime/shared/notify-trace.mjs +8 -1
- package/src/runtime/shared/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +28 -0
- package/src/runtime/shared/pristine-execution-contract.json +5 -1
- package/src/runtime/shared/process-runner-worker.mjs +7 -0
- package/src/runtime/shared/process-runner.mjs +38 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -1
- package/src/runtime/shared/provider-api-key.mjs +0 -1
- package/src/runtime/shared/read-row-numbers.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +60 -18
- package/src/runtime/shared/routine-limits.d.mts +11 -0
- package/src/runtime/shared/routine-limits.mjs +21 -0
- package/src/runtime/shared/routine-trigger.d.mts +10 -0
- package/src/runtime/shared/routine-trigger.mjs +44 -0
- package/src/runtime/shared/run-child.mjs +84 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -10
- package/src/runtime/shared/session-activity-signal.mjs +23 -0
- package/src/runtime/shared/shell-output-summary.mjs +23 -0
- package/src/runtime/shared/singleton-owner.mjs +126 -42
- package/src/runtime/shared/slow-span.mjs +4 -12
- package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
- package/src/runtime/shared/tool-output-limit.mjs +4 -2
- package/src/runtime/shared/tool-output-marker.mjs +58 -0
- package/src/runtime/shared/transcript-metadata.mjs +10 -0
- package/src/runtime/shared/turn-changes.mjs +0 -8
- package/src/runtime/shared/usage-readout-totals.mjs +56 -0
- package/src/runtime/shared/user-data-guard.mjs +131 -34
- package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
- package/src/runtime/shared/worktrees/git-head.mjs +20 -2
- package/src/runtime/shared/worktrees/lock.mjs +3 -2
- package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
- package/src/runtime/tidy/runners/biome.mjs +3 -1
- package/src/runtime/tidy/shadow.mjs +2 -1
- package/src/runtime/web-search/index.mjs +5 -7
- package/src/runtime/web-search/lib/formatter.mjs +42 -6
- package/src/runtime/web-search/tool-defs.mjs +6 -1
- package/src/session-runtime/agent-home-delivery.mjs +459 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +92 -0
- package/src/session-runtime/agent-task-sessions.mjs +200 -0
- package/src/session-runtime/boot/apis.mjs +50 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
- package/src/session-runtime/held-requests.mjs +228 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +11 -4
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
- package/src/session-runtime/lifecycle/shared.mjs +25 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +5 -2
- package/src/session-runtime/lifecycle-api.mjs +3 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
- package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +112 -15
- package/src/session-runtime/model-route/set-route.mjs +14 -3
- package/src/session-runtime/owned-automation-run.mjs +229 -0
- package/src/session-runtime/provider-auth/login.mjs +10 -6
- package/src/session-runtime/provider-auth/setup.mjs +19 -2
- package/src/session-runtime/provider-catalog-cache.mjs +101 -25
- package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
- package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
- package/src/session-runtime/provider-models.mjs +76 -10
- package/src/session-runtime/provider-readiness.mjs +4 -0
- package/src/session-runtime/resource-api.mjs +5 -0
- package/src/session-runtime/resource-mcp-api.mjs +107 -13
- package/src/session-runtime/resource-skills-api.mjs +12 -0
- package/src/session-runtime/room-member-gate.mjs +48 -0
- package/src/session-runtime/routine-home-turn.mjs +156 -0
- package/src/session-runtime/routine-owner.mjs +48 -0
- package/src/session-runtime/schedule-session-run.mjs +30 -64
- package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
- package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
- package/src/session-runtime/services/agent-tool.mjs +20 -0
- package/src/session-runtime/services/channel-admin.mjs +93 -24
- package/src/session-runtime/services/memory-access.mjs +37 -0
- package/src/session-runtime/services/provider-admin.mjs +166 -59
- package/src/session-runtime/services/schedule-access.mjs +91 -0
- package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
- package/src/session-runtime/services/usage-dashboard.mjs +27 -69
- package/src/session-runtime/session-create/session-options.mjs +34 -7
- package/src/session-runtime/session-hooks.mjs +16 -8
- package/src/session-runtime/setup-tool/executor.mjs +68 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
- package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/skills-api.mjs +16 -1
- package/src/session-runtime/tool-policy-refresh.mjs +238 -29
- package/src/session-runtime/turn/session-ops.mjs +10 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +11 -2
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
- package/src/session-runtime/usage-stats-api.mjs +6 -1
- package/src/session-runtime/webhook-session-run.mjs +49 -67
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
- package/src/session-runtime/workflow-agents-api.mjs +4 -1
- package/src/standalone/channel-transport/http-routes.mjs +10 -9
- package/src/standalone/daemon-agent-control.mjs +1 -8
- package/src/standalone/daemon-desktop-runtime.mjs +20 -7
- package/src/standalone/daemon-owner.mjs +117 -25
- package/src/standalone/daemon-session-control.mjs +11 -2
- package/src/standalone/daemon.mjs +61 -17
- package/src/standalone/session-call-cache.mjs +6 -0
- package/src/standalone/session-protocol.mjs +28 -1
- package/src/standalone/session-service/retention/busy.mjs +7 -2
- package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/standalone/session-transport/routes.mjs +7 -6
- package/src/tui/app/model-options.mjs +39 -2
- package/src/tui/app/model-picker.mjs +16 -2
- package/src/tui/app/provider-setup-picker.mjs +1 -2
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +487 -128
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +35 -4
- package/src/tui/session/notice-text.mjs +0 -1
- package/src/tui/session/queue-helpers.mjs +2 -1
- package/src/tui/session/session-api/extensions.mjs +4 -0
- package/src/tui/session/session-api/intake/submission.mjs +12 -13
- package/src/tui/session/session-api/integrations.mjs +9 -5
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
- package/src/tui/session/session-api/lifecycle.mjs +17 -1
- package/src/tui/session/session-api/routes.mjs +48 -3
- package/src/tui/session/session-flow/drain.mjs +20 -3
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
- package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
- package/src/tui/session/session-flow/steering.mjs +104 -24
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/tool-approval.mjs +26 -5
- package/src/tui/session/transcript-intake.mjs +6 -2
- package/src/tui/session/transcript-spill.mjs +5 -1
- package/src/tui/session/tui-steering-persist.mjs +65 -42
- package/src/tui/session/turn-live-call.mjs +56 -0
- package/src/tui/session/turn-stream.mjs +33 -0
- package/src/tui/session/turn.mjs +50 -7
- package/src/ui/statusline.mjs +1 -6
- package/src/ui/streaming-markdown-heal.mjs +24 -7
- package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
- package/src/workflows/default/WORKFLOW.md +9 -13
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -135,7 +135,12 @@ export function createContextState({
|
|
|
135
135
|
const ctx = runtime.contextStatus?.() || null;
|
|
136
136
|
if (!ctx) return null;
|
|
137
137
|
syncContextDisplayFields(ctx);
|
|
138
|
-
const stats = {
|
|
138
|
+
const stats = {
|
|
139
|
+
...getState().stats,
|
|
140
|
+
...contextMeasurementStats(ctx),
|
|
141
|
+
// The persisted session totals behind the composer's usage readout.
|
|
142
|
+
usageReadout: ctx.usage?.usageReadout ?? null,
|
|
143
|
+
};
|
|
139
144
|
updateState({ stats });
|
|
140
145
|
return ctx;
|
|
141
146
|
};
|
|
@@ -31,12 +31,43 @@ export function createNoticeSurface({ getState, set, isDisposed, pushItem, repla
|
|
|
31
31
|
return id;
|
|
32
32
|
};
|
|
33
33
|
const pushNotice = (text, tone = 'info', options = {}) => {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
// A routine result is a finished sentence, never a raw error to polish;
|
|
35
|
+
// a group-room row is someone's words, kept verbatim (a pass has none).
|
|
36
|
+
const value =
|
|
37
|
+
options.routine || options.room || options.heldRequest ? String(text ?? '').trim() : polishNoticeText(text);
|
|
38
|
+
if (!value && !options.room) return null;
|
|
36
39
|
const forceTranscript = options.transcript === true;
|
|
37
40
|
if (!forceTranscript) return pushToast(value, tone, options.ttlMs, options);
|
|
38
|
-
const
|
|
39
|
-
|
|
41
|
+
const userRow = options.room?.kind === 'user';
|
|
42
|
+
// A room user row keeps its message id (the sender's submission id), as a
|
|
43
|
+
// turn's own prompt row keeps its submission id.
|
|
44
|
+
const id = (userRow && options.messageId) || nextId();
|
|
45
|
+
// One row per messageId: a routine's live-only run row (running, delivery
|
|
46
|
+
// failed) gives way to the row that follows it (routine-result.mjs).
|
|
47
|
+
if (options.messageId) {
|
|
48
|
+
const current = getState().items;
|
|
49
|
+
const items = current.filter((it) => !(it?.kind === 'notice' && it?.messageId === options.messageId));
|
|
50
|
+
if (items.length !== current.length) set({ items: replaceItems(items, { preserveStreamingTail: true }) });
|
|
51
|
+
}
|
|
52
|
+
pushItem({
|
|
53
|
+
// A group-room row (agent-room.mjs): the user's own words are their
|
|
54
|
+
// bubble; every member row is a notice the app renders from `room`.
|
|
55
|
+
kind: userRow ? 'user' : 'notice',
|
|
56
|
+
id,
|
|
57
|
+
text: value,
|
|
58
|
+
...(userRow ? {} : { tone }),
|
|
59
|
+
// A schedule result posted into a home thread (routine-result.mjs).
|
|
60
|
+
...(options.routine ? { routine: options.routine } : {}),
|
|
61
|
+
...(options.room ? { room: options.room } : {}),
|
|
62
|
+
// A room user row's files, in the fields a prompt row draws them from.
|
|
63
|
+
...(userRow && Array.isArray(options.attachments) && options.attachments.length
|
|
64
|
+
? { attachments: options.attachments }
|
|
65
|
+
: {}),
|
|
66
|
+
...(userRow && Array.isArray(options.images) && options.images.length ? { images: options.images } : {}),
|
|
67
|
+
// A held request of an unattended run (human-gate/held-message.mjs).
|
|
68
|
+
...(options.heldRequest ? { heldRequest: options.heldRequest } : {}),
|
|
69
|
+
...(options.messageId ? { messageId: options.messageId } : {}),
|
|
70
|
+
});
|
|
40
71
|
return id;
|
|
41
72
|
};
|
|
42
73
|
// Remove a transcript notice previously created via pushNotice(...,
|
|
@@ -35,7 +35,6 @@ const FAILED_NOTICE_ACTIONS = new Map([
|
|
|
35
35
|
['oauth login', 'start OAuth login'],
|
|
36
36
|
['output style switch', 'switch output style'],
|
|
37
37
|
['openai usage auth save', 'save OpenAI usage auth'],
|
|
38
|
-
['opencode go usage auth save', 'save OpenCode Go usage auth'],
|
|
39
38
|
['plugin add', 'add plugin'],
|
|
40
39
|
['plugin mcp enable', 'enable plugin MCP'],
|
|
41
40
|
['plugin uninstall', 'uninstall plugin'],
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { agentJobResultText, parseAgentJob, parseSyntheticAgentMessage } from './agent-envelope.mjs';
|
|
7
7
|
import { attachmentTextForPart, isAttachmentReference } from '../../runtime/attachments/store.mjs';
|
|
8
|
+
import { recognisedSlashToken } from '../app/slash-commands.mjs';
|
|
8
9
|
|
|
9
10
|
const QUEUE_PRIORITY = { now: 0, next: 1, later: 2 };
|
|
10
11
|
|
|
@@ -52,7 +53,7 @@ export function isQueuedEntryVisible(entry) {
|
|
|
52
53
|
export function isSlashQueuedEntry(entry) {
|
|
53
54
|
if (entry?.skipSlashCommands) return false;
|
|
54
55
|
const text = promptContentText(entry?.content ?? entry?.text ?? '');
|
|
55
|
-
return text
|
|
56
|
+
return recognisedSlashToken(text) !== null;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
function firstQueueLine(text) {
|
|
@@ -121,6 +121,10 @@ export function createSessionExtensionsApi(bag) {
|
|
|
121
121
|
(input) => runtime.saveSkill?.(input),
|
|
122
122
|
(result, input) => [`skill saved: ${result?.skill?.name || input?.name || 'skill'}`]
|
|
123
123
|
),
|
|
124
|
+
removeSkill: lockedChange(
|
|
125
|
+
(input) => runtime.removeSkill?.(input),
|
|
126
|
+
(result, input) => [`skill removed: ${result?.skill?.name || input?.name || 'skill'}`]
|
|
127
|
+
),
|
|
124
128
|
reloadSkills: lockedChange(
|
|
125
129
|
() => runtime.reloadSkills?.(),
|
|
126
130
|
(status) => [`skills reload: ${status?.count || 0} available`]
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { promptDisplayText } from '../../queue-helpers.mjs';
|
|
5
5
|
|
|
6
6
|
export function createSubmissionIntake(bag) {
|
|
7
|
-
const {
|
|
7
|
+
const { nextId, flags, getState, enqueue, autoClearBeforeSubmit } = bag;
|
|
8
8
|
|
|
9
9
|
const submission = (text, options = {}) => {
|
|
10
10
|
const displayText = promptDisplayText(text, options);
|
|
@@ -14,6 +14,11 @@ export function createSubmissionIntake(bag) {
|
|
|
14
14
|
text,
|
|
15
15
|
queueOptions: {
|
|
16
16
|
...options,
|
|
17
|
+
// A kickoff (a new agent's greeting turn) reaches the model only: no
|
|
18
|
+
// user bubble, no queue row, never restored into the composer.
|
|
19
|
+
...(options.kickoff === true
|
|
20
|
+
? { isMeta: true, suppressDisplay: true, skipSlashCommands: true, restorable: false }
|
|
21
|
+
: {}),
|
|
17
22
|
// Always mint a submission id so daemon retries / dual-path intake
|
|
18
23
|
// can dedupe instead of booking the same prompt twice.
|
|
19
24
|
id: String(options.id || '').trim() || nextId(),
|
|
@@ -25,19 +30,13 @@ export function createSubmissionIntake(bag) {
|
|
|
25
30
|
};
|
|
26
31
|
|
|
27
32
|
const enqueueSubmission = (intake) => {
|
|
33
|
+
// The queue itself wakes a passive `task wait` or shell hold for typed
|
|
34
|
+
// input (not for slash commands, which run after the turn); see enqueue.
|
|
28
35
|
const accepted = enqueue(intake.text, intake.queueOptions);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if ((intake.queueOptions.mode || 'prompt') === 'prompt') {
|
|
34
|
-
bag.cancelQuotaResumeOnUserInput?.();
|
|
35
|
-
bag.cancelQueuedGoalContinuations?.();
|
|
36
|
-
bag.archiveCompletedGoalOnUserInput?.();
|
|
37
|
-
}
|
|
38
|
-
try {
|
|
39
|
-
runtime.interruptTaskWait?.('user-message');
|
|
40
|
-
} catch {}
|
|
36
|
+
if (accepted !== false && (intake.queueOptions.mode || 'prompt') === 'prompt') {
|
|
37
|
+
bag.cancelQuotaResumeOnUserInput?.();
|
|
38
|
+
bag.cancelQueuedGoalContinuations?.();
|
|
39
|
+
bag.archiveCompletedGoalOnUserInput?.();
|
|
41
40
|
}
|
|
42
41
|
return accepted;
|
|
43
42
|
};
|
|
@@ -139,6 +139,7 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
139
139
|
(result) => `custom provider saved: ${result.id}`
|
|
140
140
|
),
|
|
141
141
|
updateCustomProviderModel: (id, modelId, patch) => runtime.updateCustomProviderModel(id, modelId, patch),
|
|
142
|
+
setModelPreferences: (provider, changes) => runtime.setModelPreferences(provider, changes),
|
|
142
143
|
removeCustomProvider: async (id) => {
|
|
143
144
|
const result = await runtime.removeCustomProvider(id);
|
|
144
145
|
refreshRouteStats();
|
|
@@ -148,11 +149,6 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
148
149
|
testCustomProvider: (input) => runtime.testCustomProvider(input),
|
|
149
150
|
checkCustomProviderKeyEnv: (name) => runtime.checkCustomProviderKeyEnv(name),
|
|
150
151
|
discoverCustomProviderModels: (input) => runtime.discoverCustomProviderModels(input),
|
|
151
|
-
saveOpenCodeGoUsageAuth: async (opts) => {
|
|
152
|
-
await runtime.saveOpenCodeGoUsageAuth(opts);
|
|
153
|
-
pushNotice('OpenCode Go usage auth saved', 'info');
|
|
154
|
-
return true;
|
|
155
|
-
},
|
|
156
152
|
saveOpenAIUsageSessionKey: async (secret) => {
|
|
157
153
|
await runtime.saveOpenAIUsageSessionKey(secret);
|
|
158
154
|
pushNotice('OpenAI usage auth saved', 'info');
|
|
@@ -195,6 +191,14 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
195
191
|
(name) => runtime.runScheduleNow(name),
|
|
196
192
|
(_result, name) => `schedule ran: ${name}`
|
|
197
193
|
),
|
|
194
|
+
runWebhookNow: announced(
|
|
195
|
+
(name) => runtime.runWebhookNow(name),
|
|
196
|
+
(_result, name) => `webhook ran: ${name}`
|
|
197
|
+
),
|
|
198
|
+
retryRoutineDelivery: announced(
|
|
199
|
+
(kind, name) => runtime.retryRoutineDelivery(kind, name),
|
|
200
|
+
(_result, kind, name) => `${kind} result delivered: ${name}`
|
|
201
|
+
),
|
|
198
202
|
saveWebhook: announced(
|
|
199
203
|
(entry) => runtime.saveWebhook(entry),
|
|
200
204
|
(result) => `webhook saved: ${result.name}`
|
|
@@ -78,18 +78,28 @@ export function createSessionResetActions(bag) {
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
return {
|
|
81
|
-
|
|
81
|
+
// `archiveAs`: the id the outgoing transcript is kept under (an agent
|
|
82
|
+
// home's fresh start); the clear fails rather than wipe without it.
|
|
83
|
+
// `rebuildPrompt` / `fork: false`: an agent chat's reset (session-ops clear).
|
|
84
|
+
clear: (options = {}) =>
|
|
82
85
|
withResetLock(async () => {
|
|
86
|
+
const archiveAs = typeof options?.archiveAs === 'string' ? options.archiveAs : '';
|
|
87
|
+
const reset = {
|
|
88
|
+
...(options?.rebuildPrompt === true ? { rebuildPrompt: true } : {}),
|
|
89
|
+
...(options?.fork === false ? { fork: false } : {}),
|
|
90
|
+
};
|
|
83
91
|
const clearedId = getState().sessionId;
|
|
84
92
|
// A cleared session has no failed turn left to resume.
|
|
85
93
|
bag.supersedeQuotaResume?.(clearedId);
|
|
86
94
|
const rollbackSnapshot = beginTuiReset();
|
|
87
95
|
set(blankSessionPatch());
|
|
88
96
|
try {
|
|
89
|
-
await runtime.clear({ recoverAgent: true });
|
|
97
|
+
const result = await runtime.clear({ recoverAgent: true, ...(archiveAs ? { archiveAs } : {}), ...reset });
|
|
98
|
+
if (result === false && (archiveAs || reset.rebuildPrompt))
|
|
99
|
+
throw new Error('The conversation could not be cleared.');
|
|
90
100
|
commitEmptySession(rollbackSnapshot);
|
|
91
101
|
flags.lastUserActivityAt = Date.now();
|
|
92
|
-
return true;
|
|
102
|
+
return reset.rebuildPrompt ? result : true;
|
|
93
103
|
} catch (error) {
|
|
94
104
|
restoreTuiAfterFailedSessionReset(rollbackSnapshot);
|
|
95
105
|
throw error;
|
|
@@ -9,6 +9,17 @@ import { createInheritanceActions } from './lifecycle/inheritance.mjs';
|
|
|
9
9
|
import { createResumeAction } from './lifecycle/resume.mjs';
|
|
10
10
|
import { createDisposeAction } from './lifecycle/dispose.mjs';
|
|
11
11
|
import { publishModelSwitch } from './routes.mjs';
|
|
12
|
+
import { resolveHeldRequest } from '../../../runtime/shared/held-request-host.mjs';
|
|
13
|
+
|
|
14
|
+
/** The human-response fields of a decision (never a value), or null. */
|
|
15
|
+
function humanDecisionFields(decision) {
|
|
16
|
+
if (!decision || typeof decision !== 'object') return null;
|
|
17
|
+
const fields = {};
|
|
18
|
+
for (const key of ['response', 'editedArgs', 'remember', 'scope']) {
|
|
19
|
+
if (decision[key] !== undefined) fields[key] = decision[key];
|
|
20
|
+
}
|
|
21
|
+
return Object.keys(fields).length ? fields : null;
|
|
22
|
+
}
|
|
12
23
|
|
|
13
24
|
export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFlows }) {
|
|
14
25
|
const { runtime, pushNotice, removeNotice, setProgressHint, finishToolApproval } = bag;
|
|
@@ -52,14 +63,19 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
52
63
|
return {
|
|
53
64
|
isSessionTerminal: () => bag.flags?.admission === 'terminal' || runtime.isSessionTerminal?.() === true,
|
|
54
65
|
resolveToolApproval: (id, decision = {}) => {
|
|
66
|
+
// A held request of an unattended run is answered from its owner's home
|
|
67
|
+
// thread, wherever the run itself lives (session-runtime/held-requests.mjs).
|
|
68
|
+
if (resolveHeldRequest(id, decision)) return true;
|
|
55
69
|
const approved = decision === true || decision?.approved === true;
|
|
70
|
+
const extra = humanDecisionFields(decision);
|
|
56
71
|
return finishToolApproval(
|
|
57
72
|
id,
|
|
58
73
|
approved,
|
|
59
74
|
decision?.reason || (approved ? 'approved by user' : 'denied by user'),
|
|
60
75
|
typeof decision?.device === 'string' ? decision.device : '',
|
|
61
76
|
decision?.answers,
|
|
62
|
-
typeof decision?.reply === 'string' ? decision.reply : undefined
|
|
77
|
+
typeof decision?.reply === 'string' ? decision.reply : undefined,
|
|
78
|
+
...(extra ? [extra] : [])
|
|
63
79
|
);
|
|
64
80
|
},
|
|
65
81
|
pushNotice,
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
* the serialized optimistic setRoute, web-search route, workflows, agent
|
|
4
4
|
* definitions, output style and orchestration mode.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
modelSwitchItem,
|
|
8
|
+
workflowSwitchItem,
|
|
9
|
+
} from '../../../runtime/agent/orchestrator/session/transcript-restore/restore.mjs';
|
|
7
10
|
import { selectedModel } from '../../../session-runtime/model-route/model-switch-target.mjs';
|
|
8
11
|
import { createApiHelpers } from './shared.mjs';
|
|
9
12
|
|
|
@@ -272,8 +275,48 @@ export function createSessionRouteApi(bag) {
|
|
|
272
275
|
createWorkflow: async (payload) => runtime.createWorkflow?.(payload) ?? null,
|
|
273
276
|
deleteWorkflow: async (workflowId) => runtime.deleteWorkflow?.(workflowId) ?? null,
|
|
274
277
|
getAgentDefinition: (agentId) => runtime.getAgentDefinition?.(agentId) ?? null,
|
|
278
|
+
getAgentAvatarImage: (agentId) => runtime.getAgentAvatarImage?.(agentId) ?? null,
|
|
279
|
+
getAgentConnectors: (agentId) => runtime.getAgentConnectors?.(agentId) ?? [],
|
|
280
|
+
listConnectors: () => runtime.listConnectors?.() ?? [],
|
|
281
|
+
listConnectorTools: (connectorId) => runtime.listConnectorTools?.(connectorId) ?? [],
|
|
282
|
+
setAgentConnectors: async (agentId, connectors) => runtime.setAgentConnectors?.(agentId, connectors) ?? null,
|
|
283
|
+
setAgentConnectorEnabled: async (agentId, connectorId, enabled) =>
|
|
284
|
+
runtime.setAgentConnectorEnabled?.(agentId, connectorId, enabled) ?? [],
|
|
285
|
+
getProjectConnectors: (projectPath) => runtime.getProjectConnectors?.(projectPath) ?? [],
|
|
286
|
+
setProjectConnectorEnabled: async (projectPath, connectorId, enabled) =>
|
|
287
|
+
runtime.setProjectConnectorEnabled?.(projectPath, connectorId, enabled) ?? [],
|
|
288
|
+
setAgentConnectorToolPermission: async (agentId, connectorId, toolName, permission) =>
|
|
289
|
+
runtime.setAgentConnectorToolPermission?.(agentId, connectorId, toolName, permission) ?? null,
|
|
290
|
+
// Per-agent action-kind permissions (ask / allow / block) for the profile.
|
|
291
|
+
getAgentPermissions: async (agentId) =>
|
|
292
|
+
(await import('../../../runtime/agent/orchestrator/session/human-gate/store.mjs')).agentPermissions(agentId),
|
|
293
|
+
setAgentPermission: async (agentId, action, mode) =>
|
|
294
|
+
(await import('../../../runtime/agent/orchestrator/session/human-gate/store.mjs')).setAgentPermission(
|
|
295
|
+
agentId,
|
|
296
|
+
action,
|
|
297
|
+
mode
|
|
298
|
+
),
|
|
299
|
+
getLeadPersona: () => runtime.getLeadPersona?.() ?? '',
|
|
300
|
+
saveLeadPersona: async (text) => runtime.saveLeadPersona?.(text) ?? '',
|
|
301
|
+
getLeadAgentBody: () => runtime.getLeadAgentBody?.() ?? '',
|
|
302
|
+
saveLeadAgentBody: async (text) => runtime.saveLeadAgentBody?.(text) ?? '',
|
|
303
|
+
getLeadStatus: () => runtime.getLeadStatus?.() ?? { created: null, name: '', avatar: null },
|
|
304
|
+
saveLeadIdentity: async (payload) => runtime.saveLeadIdentity?.(payload) ?? null,
|
|
305
|
+
setLeadCreated: async (created, description) => runtime.setLeadCreated?.(created, description) ?? null,
|
|
275
306
|
saveAgentDefinition: async (payload) => runtime.saveAgentDefinition?.(payload) ?? null,
|
|
276
307
|
deleteAgentDefinition: async (agentId) => runtime.deleteAgentDefinition?.(agentId) ?? null,
|
|
308
|
+
agentDefinitionPresence: (agentIds) => runtime.agentDefinitionPresence?.(agentIds) ?? null,
|
|
309
|
+
restoreAgentDefinition: async (agentId) => runtime.restoreAgentDefinition?.(agentId) ?? null,
|
|
310
|
+
purgeAgentDefinition: async (agentId) => runtime.purgeAgentDefinition?.(agentId) ?? null,
|
|
311
|
+
archivedAgentIdentities: (agentIds) => runtime.archivedAgentIdentities?.(agentIds) ?? null,
|
|
312
|
+
// Group-room rows posted by the desktop host into a room's log session.
|
|
313
|
+
appendRoomRows: async (sessionId, rows) =>
|
|
314
|
+
(await import('../../../session-runtime/agent-room-delivery.mjs')).appendRoomRows(sessionId, rows),
|
|
315
|
+
// One group-room supervisor step on the Maintainer route.
|
|
316
|
+
decideRoomTurn: async (input) =>
|
|
317
|
+
(await import('../../../runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs')).decideRoomTurn(
|
|
318
|
+
input
|
|
319
|
+
),
|
|
277
320
|
getOutputStyle: () => {
|
|
278
321
|
return runtime.getOutputStyle?.() || runtime.listOutputStyles?.() || null;
|
|
279
322
|
},
|
|
@@ -291,8 +334,10 @@ export function createSessionRouteApi(bag) {
|
|
|
291
334
|
deferStatsRefresh();
|
|
292
335
|
return result;
|
|
293
336
|
}),
|
|
294
|
-
setWorkflow: withCommandLock(async (workflowId) => {
|
|
295
|
-
const result = await runtime.setWorkflow?.(workflowId);
|
|
337
|
+
setWorkflow: withCommandLock(async (workflowId, options) => {
|
|
338
|
+
const result = await runtime.setWorkflow?.(workflowId, options);
|
|
339
|
+
// A switch of this conversation leaves a divider (restored from message meta).
|
|
340
|
+
if (result?.workflowSwitch) bag.pushItem(workflowSwitchItem(bag.nextId(), result.workflowSwitch));
|
|
296
341
|
publishRoute();
|
|
297
342
|
return result;
|
|
298
343
|
}),
|
|
@@ -52,6 +52,13 @@ function renderBatchItems(batch, pushUserOrSyntheticItem) {
|
|
|
52
52
|
}
|
|
53
53
|
continue;
|
|
54
54
|
}
|
|
55
|
+
// A routine fire paints as the routine's marker row, not a user bubble.
|
|
56
|
+
if (entry.mode === 'routine') {
|
|
57
|
+
pushUserOrSyntheticItem(entry.text, entry.id, 'routine', {
|
|
58
|
+
routineTrigger: entry.transcriptMeta?.routineTrigger,
|
|
59
|
+
});
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
55
62
|
const sender = String(entry.transcriptMeta?.sender || '')
|
|
56
63
|
.trim()
|
|
57
64
|
.toLowerCase();
|
|
@@ -106,6 +113,10 @@ export function turnOptionsForBatch(batch, steering) {
|
|
|
106
113
|
Array.isArray(entry?.resumeCompletionKeys) ? entry.resumeCompletionKeys : []
|
|
107
114
|
),
|
|
108
115
|
transcriptMeta: batch[0]?.transcriptMeta || null,
|
|
116
|
+
// Only a routine turn names its selection text (never its payload).
|
|
117
|
+
...(batch[0]?.mode === 'routine' && typeof batch[0].skillSelection === 'string'
|
|
118
|
+
? { skillSelection: batch[0].skillSelection }
|
|
119
|
+
: {}),
|
|
109
120
|
context:
|
|
110
121
|
batch
|
|
111
122
|
.map((entry) => String(entry.context || '').trim())
|
|
@@ -191,9 +202,7 @@ export function createDrainLoop(
|
|
|
191
202
|
clearBlockedDrainRetry();
|
|
192
203
|
if (entries.length === 0) return;
|
|
193
204
|
queue.removeQueuedEntries(entries);
|
|
194
|
-
const mirrored = entries.filter(
|
|
195
|
-
(entry) => steering.shouldMirrorSteeringEntry(entry) && !entry.steeringPersistRestored
|
|
196
|
-
);
|
|
205
|
+
const mirrored = entries.filter((entry) => steering.shouldMirrorSteeringEntry(entry) && entry.steeringPersistId);
|
|
197
206
|
if (mirrored.length > 0) {
|
|
198
207
|
void Promise.resolve(dropTuiSteeringPersist(steering.leadSessionId(), mirrored)).catch(() => {});
|
|
199
208
|
}
|
|
@@ -332,6 +341,14 @@ export function createDrainLoop(
|
|
|
332
341
|
}
|
|
333
342
|
submissions.remember(submissionId);
|
|
334
343
|
pending.push(entry);
|
|
344
|
+
// Typed input or a deliverable notification ends a passive task wait or
|
|
345
|
+
// shell hold so the next boundary hands it to the model now.
|
|
346
|
+
const wake = steering.taskWaitWakeForEntry(entry);
|
|
347
|
+
if (wake) {
|
|
348
|
+
try {
|
|
349
|
+
bag.runtime?.interruptTaskWait?.(wake, wake === 'notification' ? entry.execution?.id || null : null);
|
|
350
|
+
} catch {}
|
|
351
|
+
}
|
|
335
352
|
const needsDurableSteering =
|
|
336
353
|
(getState().busy || getState().commandBusy || flags.autoClearRunning || flags.quotaResumePending) &&
|
|
337
354
|
steering.shouldMirrorSteeringEntry(entry);
|
|
@@ -43,8 +43,9 @@ export function makeQueueEntry(text, options = {}, nextId) {
|
|
|
43
43
|
? options.resumeCompletionKeys.filter((key) => key != null && String(key).trim())
|
|
44
44
|
: [],
|
|
45
45
|
steeringPersistId: options.steeringPersistId || null,
|
|
46
|
-
steeringPersistRestored: options.steeringPersistRestored === true,
|
|
47
46
|
isMeta: options.isMeta === true,
|
|
47
|
+
// A routine turn's trusted skill-selection text (its instructions only).
|
|
48
|
+
skillSelection: typeof options.skillSelection === 'string' ? options.skillSelection : null,
|
|
48
49
|
goalId: options.goalId || null,
|
|
49
50
|
// Retry of a failed turn: the transcript and the session rewind the
|
|
50
51
|
// failed turn's unanswered prompt before this entry runs.
|
|
@@ -43,7 +43,8 @@ export function createTakeEntriesOps({ pending, pendingNotificationKeys, removeQ
|
|
|
43
43
|
batch.push(entry);
|
|
44
44
|
pending.splice(i, 1);
|
|
45
45
|
if (entry.mode === 'task-notification' && entry.key) pendingNotificationKeys.delete(entry.key);
|
|
46
|
-
|
|
46
|
+
// A routine fire is a turn of its own, never merged with another.
|
|
47
|
+
if (entry.retryTurnId || entry.mode === 'routine' || batch.length >= limit) break;
|
|
47
48
|
} else {
|
|
48
49
|
i += 1;
|
|
49
50
|
}
|
|
@@ -73,7 +74,7 @@ export function createTakeEntriesOps({ pending, pendingNotificationKeys, removeQ
|
|
|
73
74
|
// A reclaimed prompt goes back to the draft, so its durable steering
|
|
74
75
|
// mirror goes with it; otherwise the next runtime restore re-queues a
|
|
75
76
|
// prompt the user already took back.
|
|
76
|
-
const mirrored = queued.filter((entry) => entry.steeringPersistId
|
|
77
|
+
const mirrored = queued.filter((entry) => entry.steeringPersistId);
|
|
77
78
|
if (mirrored.length > 0) void dropTuiSteeringPersist(leadSessionId(), mirrored);
|
|
78
79
|
const queuedText = queued
|
|
79
80
|
.map((item) => item.text)
|
|
@@ -12,10 +12,13 @@ import {
|
|
|
12
12
|
callCommitCallbacks,
|
|
13
13
|
STEERING_SUPPRESSED_DISPLAY,
|
|
14
14
|
} from '../queue-helpers.mjs';
|
|
15
|
-
import { dropTuiSteeringPersist,
|
|
15
|
+
import { dropTuiSteeringPersist, readTuiSteeringPersist } from '../tui-steering-persist.mjs';
|
|
16
16
|
import { getBackgroundTask } from '../../../runtime/shared/background-tasks.mjs';
|
|
17
17
|
|
|
18
18
|
const RESTORE_DEDUP_WINDOW = 80;
|
|
19
|
+
// An older build's process-local item counter: a later process issues the
|
|
20
|
+
// same ids again, so such an id proves nothing about delivery.
|
|
21
|
+
const PROCESS_LOCAL_ITEM_ID = /^it_\d+$/;
|
|
19
22
|
|
|
20
23
|
// Mid-chain drain converts queued prompt/task notification entries into
|
|
21
24
|
// model-visible "queued_command" style steering only at provider continuation
|
|
@@ -65,8 +68,28 @@ function steeringMessageFromEntry(entry) {
|
|
|
65
68
|
return String(content ?? '').trim().length > 0 ? { ...meta, text: displayText, content } : null;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
//
|
|
69
|
-
//
|
|
71
|
+
// The submissions the transcript holds: a turn's prompt (`checkpointId`, plus
|
|
72
|
+
// `submissionIds` for a merged batch) and a steered message's `submissionIds`.
|
|
73
|
+
function deliveredSubmissionIds(session) {
|
|
74
|
+
const out = new Set();
|
|
75
|
+
for (const message of Array.isArray(session?.messages) ? session.messages : []) {
|
|
76
|
+
if (message?.role !== 'user') continue;
|
|
77
|
+
const meta = message.meta || {};
|
|
78
|
+
const transcript = meta.transcript || {};
|
|
79
|
+
for (const id of [
|
|
80
|
+
transcript.checkpointId,
|
|
81
|
+
...(Array.isArray(transcript.submissionIds) ? transcript.submissionIds : []),
|
|
82
|
+
...(Array.isArray(meta.submissionIds) ? meta.submissionIds : []),
|
|
83
|
+
]) {
|
|
84
|
+
if (typeof id === 'string' && id) out.add(id);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Rows of an older build carry no stable submission id; only their text can
|
|
91
|
+
// tell them delivered: substring (not equality) because steering delivery may
|
|
92
|
+
// wrap the raw text.
|
|
70
93
|
function recentUserTexts(session, window) {
|
|
71
94
|
const messages = Array.isArray(session?.messages) ? session.messages : [];
|
|
72
95
|
const out = [];
|
|
@@ -107,7 +130,7 @@ export function createSteeringOps(bag, { queue, submissions }) {
|
|
|
107
130
|
function commitSteeringQueueEntries(entries) {
|
|
108
131
|
callCommitCallbacks(entries);
|
|
109
132
|
const mirrored = (Array.isArray(entries) ? entries : []).filter(
|
|
110
|
-
(entry) => shouldMirrorSteeringEntry(entry) &&
|
|
133
|
+
(entry) => shouldMirrorSteeringEntry(entry) && entry.steeringPersistId
|
|
111
134
|
);
|
|
112
135
|
if (mirrored.length > 0) dropTuiSteeringPersist(leadSessionId(), mirrored);
|
|
113
136
|
}
|
|
@@ -131,6 +154,47 @@ export function createSteeringOps(bag, { queue, submissions }) {
|
|
|
131
154
|
);
|
|
132
155
|
}
|
|
133
156
|
|
|
157
|
+
// Queued input the user typed (editable prompts), not runtime notices.
|
|
158
|
+
function hasPendingUserInput() {
|
|
159
|
+
if (!admissionOpen()) return false;
|
|
160
|
+
return pending.some((entry) => isQueuedEntryEditable(entry) && !isSlashQueuedEntry(entry));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// A notification the next boundary will deliver: a task notification (one
|
|
164
|
+
// the agent already received through task wait/read is not deliverable) or
|
|
165
|
+
// the Goal closeout. `later` entries (scheduled and channel injects) wait
|
|
166
|
+
// for the turn to end, so they are not deliverable mid-turn.
|
|
167
|
+
function isDeliverableNotification(entry) {
|
|
168
|
+
const mode = entry?.mode;
|
|
169
|
+
return (
|
|
170
|
+
admissionOpen() &&
|
|
171
|
+
(mode === 'task-notification' || mode === 'goal-closeout') &&
|
|
172
|
+
queuePriorityValue(entry.priority) <= queuePriorityValue('next') &&
|
|
173
|
+
canDeliverSteeringEntry(entry) &&
|
|
174
|
+
steeringMessageFromEntry(entry) !== null
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function hasPendingNotification() {
|
|
179
|
+
return pending.some(isDeliverableNotification);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// What one queued entry should wake a passive wait or shell hold for: typed
|
|
183
|
+
// input, a deliverable notification, or nothing (slash commands and
|
|
184
|
+
// informational meta prompts run or ride along without ending a wait).
|
|
185
|
+
function taskWaitWakeForEntry(entry) {
|
|
186
|
+
if (!admissionOpen()) return false;
|
|
187
|
+
if (isQueuedEntryEditable(entry) && !isSlashQueuedEntry(entry)) return 'user-message';
|
|
188
|
+
return isDeliverableNotification(entry) ? 'notification' : false;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// What a passive wait or shell hold should wake for right now: user input
|
|
192
|
+
// first, else a deliverable notification.
|
|
193
|
+
function pendingTaskWaitWake() {
|
|
194
|
+
if (hasPendingUserInput()) return 'user-message';
|
|
195
|
+
return hasPendingNotification() ? 'notification' : false;
|
|
196
|
+
}
|
|
197
|
+
|
|
134
198
|
// `later` notifications (scheduled tasks) are skipped unless the runtime
|
|
135
199
|
// explicitly asks for a later flush.
|
|
136
200
|
function drainPendingSteering(_sessionIdOrOptions = null, maybeOptions = null) {
|
|
@@ -164,46 +228,57 @@ export function createSteeringOps(bag, { queue, submissions }) {
|
|
|
164
228
|
async function restoreLeadSteeringFromDisk() {
|
|
165
229
|
// A closed/closing conversation never gets queue work restored into it.
|
|
166
230
|
if (!admissionOpen()) return;
|
|
167
|
-
const rows = await
|
|
231
|
+
const rows = await readTuiSteeringPersist(leadSessionId());
|
|
168
232
|
if (!rows.length) return;
|
|
169
233
|
const livePersistIds = new Set(pending.map((entry) => entry?.steeringPersistId).filter(Boolean));
|
|
170
|
-
// Crash-consumed dedup: a row whose
|
|
171
|
-
// transcript was consumed before the restart — only its disk drop
|
|
172
|
-
// lost (drop is an async fire-and-forget write). Re-queuing it
|
|
173
|
-
// re-injects a stale prompt into the next turn (user report:
|
|
174
|
-
// self-injection after a process restart).
|
|
175
|
-
|
|
176
|
-
const
|
|
234
|
+
// Crash-consumed dedup: a row whose submission already landed in the
|
|
235
|
+
// session transcript was consumed before the restart — only its disk drop
|
|
236
|
+
// was lost (drop is an async fire-and-forget write). Re-queuing it
|
|
237
|
+
// silently re-injects a stale prompt into the next turn (user report:
|
|
238
|
+
// surprise self-injection after a process restart). Identity, never text:
|
|
239
|
+
// the same words can be a new submission.
|
|
240
|
+
const delivered = deliveredSubmissionIds(runtime.session);
|
|
241
|
+
let legacyTexts = null;
|
|
242
|
+
const alreadyDelivered = (row, text) => {
|
|
243
|
+
if (row.submissionId && !PROCESS_LOCAL_ITEM_ID.test(row.submissionId)) return delivered.has(row.submissionId);
|
|
244
|
+
legacyTexts ??= recentUserTexts(runtime.session, RESTORE_DEDUP_WINDOW);
|
|
245
|
+
return legacyTexts.some((body) => body.includes(text));
|
|
246
|
+
};
|
|
177
247
|
const restored = [];
|
|
178
|
-
|
|
248
|
+
const consumed = [];
|
|
179
249
|
for (const row of rows) {
|
|
180
250
|
const text = String(row?.text || '').trim();
|
|
181
251
|
if (!text) continue;
|
|
182
252
|
// Live enqueue already holds this row (id assigned before the async
|
|
183
253
|
// disk write). Replaying it is the classic double-booked queue.
|
|
184
254
|
if (row.steeringPersistId && livePersistIds.has(row.steeringPersistId)) continue;
|
|
185
|
-
if (alreadyDelivered(text)) {
|
|
186
|
-
|
|
255
|
+
if (alreadyDelivered(row, text)) {
|
|
256
|
+
consumed.push(row);
|
|
187
257
|
continue;
|
|
188
258
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
259
|
+
// The row keeps its executable content and attachment links; a row
|
|
260
|
+
// of an older build has only its text.
|
|
261
|
+
const { content, text: displayText, submissionId, submittedAt, ...options } = row;
|
|
262
|
+
const entry = queue.makeQueueEntry(content ?? displayText, {
|
|
263
|
+
...options,
|
|
264
|
+
id: submissionId || undefined,
|
|
265
|
+
submittedAt: submittedAt || undefined,
|
|
266
|
+
displayText,
|
|
194
267
|
});
|
|
195
268
|
pending.push(entry);
|
|
196
|
-
if (
|
|
197
|
-
|
|
269
|
+
if (submissionId) submissions.remember(submissionId);
|
|
270
|
+
livePersistIds.add(entry.steeringPersistId);
|
|
198
271
|
if (isQueuedEntryVisible(entry)) restored.push(entry);
|
|
199
272
|
}
|
|
200
273
|
if (restored.length > 0) set({ queued: [...getState().queued, ...restored] });
|
|
274
|
+
// Reading keeps rows durable; a delivered row's lost drop is completed here.
|
|
275
|
+
if (consumed.length > 0) await dropTuiSteeringPersist(leadSessionId(), consumed);
|
|
201
276
|
// The conversation closed while the rows were being read: settle them
|
|
202
277
|
// explicitly (rejected + durable mirror released), never leave them parked.
|
|
203
278
|
if (bag.flags?.admission === 'terminal') bag.settleClosedQueue?.();
|
|
204
|
-
if (
|
|
279
|
+
if (consumed.length > 0) {
|
|
205
280
|
try {
|
|
206
|
-
process.stderr.write(`[tui] skipped ${
|
|
281
|
+
process.stderr.write(`[tui] skipped ${consumed.length} already-delivered steering row(s) on restore\n`);
|
|
207
282
|
} catch {
|
|
208
283
|
/* best effort */
|
|
209
284
|
}
|
|
@@ -219,6 +294,11 @@ export function createSteeringOps(bag, { queue, submissions }) {
|
|
|
219
294
|
commitSteeringQueueEntries,
|
|
220
295
|
settleSteeredSubmissions,
|
|
221
296
|
hasPendingSteering,
|
|
297
|
+
hasPendingUserInput,
|
|
298
|
+
isDeliverableNotification,
|
|
299
|
+
hasPendingNotification,
|
|
300
|
+
taskWaitWakeForEntry,
|
|
301
|
+
pendingTaskWaitWake,
|
|
222
302
|
drainPendingSteering,
|
|
223
303
|
restoreLeadSteeringFromDisk,
|
|
224
304
|
};
|
|
@@ -39,6 +39,8 @@ export function createSessionFlow(bag) {
|
|
|
39
39
|
enqueue: loop.enqueue,
|
|
40
40
|
settleClosedQueue: loop.settleClosedQueue,
|
|
41
41
|
hasPendingSteering: steering.hasPendingSteering,
|
|
42
|
+
hasPendingUserInput: steering.hasPendingUserInput,
|
|
43
|
+
pendingTaskWaitWake: steering.pendingTaskWaitWake,
|
|
42
44
|
drainPendingSteering: steering.drainPendingSteering,
|
|
43
45
|
restoreLeadSteeringFromDisk: steering.restoreLeadSteeringFromDisk,
|
|
44
46
|
autoClearBeforeSubmit: autoClear.autoClearBeforeSubmit,
|