mixdog 1.3.1 → 1.3.3
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 +8 -4
- package/package.json +8 -8
- package/scripts/native-release-status.mjs +238 -0
- package/scripts/verify-runtime-dependency-versions.mjs +158 -0
- package/src/agents/reviewer/AGENT.md +5 -7
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +9 -1
- package/src/defaults/skills/browser-use/SKILL.md +6 -3
- package/src/defaults/skills/local-provider/SKILL.md +33 -6
- package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
- package/src/defaults/skills/setup/SKILL.md +23 -1
- package/src/defaults/skills/setup/references/actions.md +50 -3
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +7 -3
- package/src/defaults/skills/visualize/SKILL.md +9 -6
- package/src/defaults/skills/visualize/references/craft.md +8 -1
- package/src/help.mjs +1 -1
- package/src/lib/keychain-cjs.cjs +4 -1
- package/src/lib/rules-builder.cjs +14 -7
- package/src/rules/agent-mode/AGENT_MODE.md +8 -5
- package/src/rules/agent-mode/MIXY.md +6 -8
- package/src/rules/lead/LEAD.md +7 -10
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- package/src/rules/shared/45-destructive.md +5 -1
- package/src/rules/shared/60-verification.md +6 -4
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
- package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
- package/src/runtime/agent/orchestrator/config.mjs +11 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +84 -32
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +38 -11
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +15 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +84 -42
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
- package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +13 -1
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
- package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +5 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +10 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +4 -6
- package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +52 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +35 -13
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +196 -45
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/continuation.mjs +15 -6
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +45 -19
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +44 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +185 -37
- package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
- package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +240 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +102 -35
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +19 -9
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +199 -109
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/empty-nudge.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +62 -13
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +22 -6
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +33 -8
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/call-prep.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/manager/agent-listing-notice.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +27 -14
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +32 -1
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +115 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +28 -9
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +4 -9
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +14 -1
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +52 -11
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +18 -3
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +126 -12
- package/src/runtime/agent/orchestrator/session/runtime-user-context.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +16 -3
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +140 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +15 -5
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +49 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +80 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +33 -1
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.d.mts +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +37 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +35 -5
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +47 -14
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +127 -20
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +557 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +10 -12
- package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +42 -23
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
- package/src/runtime/attachments/attachment-reference.mjs +155 -0
- package/src/runtime/attachments/legacy-office.mjs +110 -0
- package/src/runtime/attachments/limits.mjs +5 -1
- package/src/runtime/attachments/office-extract.mjs +3 -6
- package/src/runtime/attachments/pdf-extract.mjs +84 -10
- package/src/runtime/attachments/prompt-restore.mjs +70 -0
- package/src/runtime/attachments/store.mjs +109 -33
- package/src/runtime/browser-bridge/client.mjs +73 -20
- package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +14 -7
- package/src/runtime/channels/lib/state-file.mjs +15 -15
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
- package/src/runtime/channels/lib/worker-main.mjs +3 -2
- package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
- package/src/runtime/effort-judge/judge-client.mjs +66 -16
- package/src/runtime/effort-judge/model-install.mjs +47 -7
- package/src/runtime/local-provider/asset-installer.mjs +10 -4
- package/src/runtime/local-provider/catalog.mjs +5 -2
- package/src/runtime/local-provider/registered-models.mjs +64 -27
- package/src/runtime/local-provider/server.mjs +2 -3
- package/src/runtime/media/adapters/image-api.mjs +89 -0
- package/src/runtime/media/auth.mjs +64 -1
- package/src/runtime/media/catalog.mjs +66 -4
- package/src/runtime/media/jobs.mjs +4 -0
- package/src/runtime/media/lanes.mjs +46 -5
- package/src/runtime/media/media-usage.mjs +17 -0
- package/src/runtime/media/renditions.mjs +15 -15
- package/src/runtime/media/store.mjs +36 -35
- package/src/runtime/media/tool.mjs +8 -1
- package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
- package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
- package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +14 -2
- package/src/runtime/memory/lib/pg/process.mjs +8 -4
- package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
- package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
- package/src/runtime/office/core/journal.mjs +7 -14
- package/src/runtime/office/design/library/design-library-core.mjs +4 -16
- package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
- package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
- package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
- package/src/runtime/office/pdf/pdf-render.mjs +30 -18
- package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +135 -29
- package/src/runtime/shared/agent-avatar-sprites.mjs +23 -8
- package/src/runtime/shared/agent-avatar.mjs +3 -2
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
- package/src/runtime/shared/agent-message-envelope.mjs +44 -0
- package/src/runtime/shared/agent-reap-state.d.mts +4 -0
- package/src/runtime/shared/agent-room-host.d.mts +31 -0
- package/src/runtime/shared/agent-room-host.mjs +58 -0
- package/src/runtime/shared/agent-store.mjs +24 -7
- package/src/runtime/shared/agent-task-starts.mjs +27 -0
- package/src/runtime/shared/atomic-file.d.mts +50 -0
- package/src/runtime/shared/atomic-file.mjs +394 -132
- package/src/runtime/shared/background-tasks.mjs +7 -4
- package/src/runtime/shared/bot-hops.mjs +35 -0
- package/src/runtime/shared/bot-split-migration.mjs +1 -1
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/defaults-separation.mjs +6 -2
- package/src/runtime/shared/delegated-approval-host.mjs +74 -0
- package/src/runtime/shared/err-text.mjs +4 -0
- package/src/runtime/shared/error-presentation.mjs +22 -4
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/process-lifecycle.mjs +8 -12
- package/src/runtime/shared/projects.mjs +50 -41
- package/src/runtime/shared/provider-accounts.mjs +17 -12
- package/src/runtime/shared/redact-directories.mjs +18 -0
- package/src/runtime/shared/remove-directory.mjs +28 -0
- package/src/runtime/shared/routine-trigger.d.mts +6 -1
- package/src/runtime/shared/routine-trigger.mjs +14 -6
- package/src/runtime/shared/run-child.d.mts +3 -0
- package/src/runtime/shared/run-child.mjs +24 -3
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- package/src/runtime/shared/session-sidebar-host.d.mts +11 -2
- package/src/runtime/shared/session-sidebar-host.mjs +16 -3
- package/src/runtime/shared/singleton-owner.mjs +7 -6
- package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
- package/src/runtime/shared/staged-update.mjs +4 -2
- package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
- package/src/runtime/shared/tool-execution-contract.mjs +10 -0
- package/src/runtime/shared/tool-work-units.mjs +12 -9
- package/src/runtime/shared/transcript-metadata.mjs +28 -3
- package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
- package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
- package/src/runtime/shared/turn-snapshot.mjs +277 -124
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +92 -61
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +251 -61
- package/src/runtime/shared/worktrees/contract.mjs +11 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +11 -2
- package/src/runtime/shared/worktrees/manager.mjs +419 -52
- package/src/runtime/shared/worktrees/registry.mjs +29 -27
- package/src/runtime/shared/worktrees/tool-host.mjs +39 -0
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/tidy/process.mjs +41 -8
- package/src/runtime/tidy/resolve.mjs +10 -7
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +542 -204
- package/src/session-runtime/agent-profile-changes.mjs +16 -0
- package/src/session-runtime/agent-room-delivery.mjs +81 -35
- package/src/session-runtime/agent-task-sessions.mjs +811 -179
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +48 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +16 -7
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +2 -2
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +23 -3
- package/src/session-runtime/bot-status.mjs +432 -0
- package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
- package/src/session-runtime/config-lifecycle.mjs +60 -55
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/held-requests.mjs +31 -33
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +24 -26
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown.mjs +11 -3
- package/src/session-runtime/mcp-glue/connect.mjs +100 -186
- package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
- package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
- package/src/session-runtime/media-api.mjs +5 -2
- package/src/session-runtime/model-recency.mjs +1 -0
- package/src/session-runtime/model-route/route-tuning.mjs +4 -1
- package/src/session-runtime/model-route/set-route.mjs +61 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +8 -1
- package/src/session-runtime/quick-model-rows/model-meta.mjs +2 -0
- package/src/session-runtime/quick-model-rows/provider-rows.mjs +7 -1
- package/src/session-runtime/route-resolution.mjs +16 -8
- package/src/session-runtime/route-state.mjs +1 -59
- package/src/session-runtime/routine-home-turn.mjs +5 -3
- package/src/session-runtime/runtime-bootstrap.mjs +5 -3
- package/src/session-runtime/runtime-paths.mjs +11 -5
- package/src/session-runtime/runtime-review-api.mjs +4 -1
- package/src/session-runtime/runtime-tunables.mjs +6 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
- package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
- package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +34 -19
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +7 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +8 -5
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
- package/src/session-runtime/services/agent-tool.mjs +6 -0
- package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
- package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
- package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
- package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
- package/src/session-runtime/services/plugin-admin.mjs +26 -26
- package/src/session-runtime/services/provider-admin.mjs +26 -6
- package/src/session-runtime/services/schedule-access.mjs +33 -4
- package/src/session-runtime/services/seeds.mjs +4 -3
- package/src/session-runtime/services/usage-dashboard.mjs +1 -1
- package/src/session-runtime/services/usage-stats-model.mjs +2 -1
- package/src/session-runtime/services/worktree-access.mjs +27 -0
- package/src/session-runtime/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/session-hooks.mjs +9 -17
- package/src/session-runtime/settings-builtin-tools-api.mjs +65 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +12 -2
- package/src/session-runtime/setup-tool/settings-contract.mjs +34 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
- package/src/session-runtime/skills-api.mjs +12 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +349 -0
- package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
- package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +183 -0
- package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
- package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
- package/src/session-runtime/tool-policy-refresh.mjs +48 -369
- package/src/session-runtime/tool-surface.mjs +10 -4
- package/src/session-runtime/turn/session-ops.mjs +8 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +7 -2
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +527 -333
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +85 -63
- package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
- package/src/session-runtime/workspace/transition-steps.mjs +1 -18
- package/src/session-runtime/workspace/transitions.mjs +279 -67
- package/src/session-runtime/workspace/workspace-state.mjs +7 -6
- package/src/session-runtime/workspace/worktree-tool.mjs +194 -0
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-lag-profiler.mjs +3 -1
- package/src/standalone/daemon-session-control.mjs +173 -15
- package/src/standalone/daemon-telemetry.mjs +9 -0
- package/src/standalone/daemon.mjs +33 -10
- package/src/standalone/local-session-runtime.mjs +33 -16
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +8 -0
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +2 -0
- package/src/standalone/session-service/agent-route-follow.mjs +69 -0
- package/src/standalone/session-service/session-calls/session-turns.mjs +33 -4
- package/src/standalone/session-service.mjs +21 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +36 -9
- package/src/standalone/staged-import.mjs +47 -0
- package/src/tui/App.jsx +2 -0
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- package/src/tui/app/message-selector.mjs +15 -2
- package/src/tui/app/model-options.mjs +16 -2
- package/src/tui/app/model-picker.mjs +2 -1
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
- package/src/tui/dist/index.mjs +617 -369
- package/src/tui/paste-attachments.mjs +0 -1
- package/src/tui/paste-text-policy.mjs +4 -5
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/agent-job-feed/execution-delivery.mjs +4 -1
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -0
- package/src/tui/session/session-api/intake/abort.mjs +52 -18
- package/src/tui/session/session-api/intake/rewind.mjs +39 -4
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +76 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -247
- package/src/tui/session/session-api/settings.mjs +14 -1
- package/src/tui/session/session-flow/drain.mjs +28 -3
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +8 -3
- package/src/tui/session/tool-approval.mjs +142 -14
- package/src/tui/session/transcript-intake.mjs +2 -0
- package/src/tui/session/turn.mjs +23 -14
- package/src/tui/transcript-tool-failures.mjs +8 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
- package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
- package/src/rules/agent-mode/ROUTINE.md +0 -6
- package/src/session-runtime/room-member-gate.mjs +0 -48
|
@@ -148,12 +148,12 @@ function request({
|
|
|
148
148
|
}
|
|
149
149
|
);
|
|
150
150
|
req.on('timeout', () => {
|
|
151
|
-
req.destroy(
|
|
151
|
+
req.destroy(sessionTimeoutError(method, urlPath));
|
|
152
152
|
});
|
|
153
153
|
req.on('error', reject);
|
|
154
154
|
if (deadlineMs > 0) {
|
|
155
155
|
deadlineTimer = setTimeout(() => {
|
|
156
|
-
const error =
|
|
156
|
+
const error = sessionTimeoutError(method, urlPath);
|
|
157
157
|
reject(error);
|
|
158
158
|
req.destroy(error);
|
|
159
159
|
}, deadlineMs);
|
|
@@ -163,6 +163,11 @@ function request({
|
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/** No answer within the request's bound: the daemon may be busy with it, not gone. */
|
|
167
|
+
function sessionTimeoutError(method, urlPath) {
|
|
168
|
+
return Object.assign(new Error(`session timeout: ${method} ${urlPath}`), { code: 'ESESSIONTIMEOUT' });
|
|
169
|
+
}
|
|
170
|
+
|
|
166
171
|
/** /health within `timeoutMs` of total duration; null when it does not answer. */
|
|
167
172
|
export async function probeSessionHealth({ port, token, timeoutMs = 800 } = {}) {
|
|
168
173
|
try {
|
|
@@ -15,12 +15,14 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
15
15
|
'getAgentAvatarImage',
|
|
16
16
|
'getAgentConnectors',
|
|
17
17
|
'getProjectConnectors',
|
|
18
|
+
'getAgentAlwaysAllowedTools',
|
|
18
19
|
'getAgentPermissions',
|
|
19
20
|
'listConnectors',
|
|
20
21
|
'listConnectorTools',
|
|
21
22
|
'getLeadPersona',
|
|
22
23
|
'getLeadAgentBody',
|
|
23
24
|
'getLeadStatus',
|
|
25
|
+
'getLeadHomeRoute',
|
|
24
26
|
'getAutoClear',
|
|
25
27
|
'getChannelSettings',
|
|
26
28
|
'getChannelSetup',
|
|
@@ -45,6 +47,8 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
45
47
|
'getQuotaHistory',
|
|
46
48
|
'getRecapSettings',
|
|
47
49
|
'getSessionTitleSettings',
|
|
50
|
+
'getLeadAppearance',
|
|
51
|
+
'getBotOrder',
|
|
48
52
|
'getWebSearchRoute',
|
|
49
53
|
'getSettingsSnapshot',
|
|
50
54
|
'getSystemShell',
|
|
@@ -188,6 +192,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
188
192
|
'setAgentConnectorToolPermission',
|
|
189
193
|
'setProjectConnectorEnabled',
|
|
190
194
|
'setAgentPermission',
|
|
195
|
+
'recordAgentApprovalAudit',
|
|
191
196
|
'saveLeadPersona',
|
|
192
197
|
'saveLeadAgentBody',
|
|
193
198
|
'setLeadCreated',
|
|
@@ -233,6 +238,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
233
238
|
'setProgressHint',
|
|
234
239
|
'setRecapEnabled',
|
|
235
240
|
'setAiSessionTitles',
|
|
241
|
+
'setLeadAppearance',
|
|
242
|
+
'setBotOrder',
|
|
236
243
|
'setRoute',
|
|
237
244
|
'setScheduleEnabled',
|
|
238
245
|
'setWebSearchRoute',
|
|
@@ -241,6 +248,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
241
248
|
'setToolMode',
|
|
242
249
|
'setWebSearchEnabled',
|
|
243
250
|
'setInstructionFiles',
|
|
251
|
+
'setAutoEffortBase',
|
|
244
252
|
'setWebhookConfig',
|
|
245
253
|
'setWebhookEnabled',
|
|
246
254
|
'setWorkflow',
|
|
@@ -57,6 +57,8 @@ export function createInlineBootLoaders({
|
|
|
57
57
|
if (isClosed()) return false;
|
|
58
58
|
try {
|
|
59
59
|
const module = await loadLocalModule();
|
|
60
|
+
// A loop turn between the two graph loads: one piece held the loop.
|
|
61
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
60
62
|
if (isClosed()) return false;
|
|
61
63
|
return (await module.warmLocalSessionRuntime?.()) !== false;
|
|
62
64
|
} catch {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// A bot's saved model route reaches the chats it already has: its home thread
|
|
2
|
+
// and its group-room member sessions, from their next turn (the session route
|
|
3
|
+
// API's deferred pick, the one every model picker uses: a running turn finishes
|
|
4
|
+
// on the model it started on). The latest saved route wins. A thread no
|
|
5
|
+
// runtime hosts keeps its model until it is opened (the desktop refreshes it
|
|
6
|
+
// then, agent-home-sessions.ts).
|
|
7
|
+
import { subscribeAgentRouteChanges } from '../../session-runtime/agent-profile-changes.mjs';
|
|
8
|
+
import { agentHomeSessionId } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
9
|
+
import { roomMemberOfSession } from '../../runtime/agent/orchestrator/session/agent-room.mjs';
|
|
10
|
+
|
|
11
|
+
const ROUTE_KEYS = [
|
|
12
|
+
'provider',
|
|
13
|
+
'model',
|
|
14
|
+
'effort',
|
|
15
|
+
'fast',
|
|
16
|
+
'autoEffort',
|
|
17
|
+
'modelParameters',
|
|
18
|
+
'contextPercent',
|
|
19
|
+
'contextTokens',
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
/** The pick the session route API takes for a saved route. */
|
|
23
|
+
function sessionRoutePick(route) {
|
|
24
|
+
const pick = { sessionOnly: true };
|
|
25
|
+
for (const key of ROUTE_KEYS) if (route?.[key] !== undefined && route[key] !== null) pick[key] = route[key];
|
|
26
|
+
return pick;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createAgentRouteFollow({ sessionsById, sessionOwner, advance, publishStep, log }) {
|
|
30
|
+
// Each chat takes its updates one at a time, in the order they were
|
|
31
|
+
// published: a slow chat never lets an older route land after a newer one.
|
|
32
|
+
const tails = new Map(); // sessionId -> Promise of its last queued update
|
|
33
|
+
|
|
34
|
+
function apply(sessionId, pick) {
|
|
35
|
+
const entry = sessionOwner(sessionId);
|
|
36
|
+
if (typeof entry?.runtime?.setRoute !== 'function') return Promise.resolve();
|
|
37
|
+
return Promise.resolve()
|
|
38
|
+
.then(async () => {
|
|
39
|
+
await entry.runtime.setRoute(pick);
|
|
40
|
+
const step = advance(entry);
|
|
41
|
+
if (step.changed) publishStep(entry, step);
|
|
42
|
+
})
|
|
43
|
+
.catch((error) => {
|
|
44
|
+
// A route the runtime refuses (provider signed out) leaves the chat on its model.
|
|
45
|
+
log(`agent route change not applied to ${sessionId}: ${error?.message || error}`);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function enqueue(sessionId, pick) {
|
|
50
|
+
const queued = (tails.get(sessionId) || Promise.resolve()).then(() => apply(sessionId, pick));
|
|
51
|
+
tails.set(sessionId, queued);
|
|
52
|
+
queued.then(() => {
|
|
53
|
+
if (tails.get(sessionId) === queued) tails.delete(sessionId);
|
|
54
|
+
});
|
|
55
|
+
return queued;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Every matching chat is queued before the first await: publications queue in order.
|
|
59
|
+
function follow(agentId, route) {
|
|
60
|
+
const home = agentHomeSessionId(agentId);
|
|
61
|
+
if (!home || !route?.provider || !route?.model) return Promise.resolve();
|
|
62
|
+
const pick = sessionRoutePick(route);
|
|
63
|
+
const queued = [...sessionsById.keys()]
|
|
64
|
+
.filter((sessionId) => sessionId === home || roomMemberOfSession(sessionId)?.agentId === agentId)
|
|
65
|
+
.map((sessionId) => enqueue(sessionId, pick));
|
|
66
|
+
return Promise.all(queued);
|
|
67
|
+
}
|
|
68
|
+
return subscribeAgentRouteChanges(follow);
|
|
69
|
+
}
|
|
@@ -62,15 +62,43 @@ export function createSessionTurnCalls(ctx) {
|
|
|
62
62
|
return step;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
// Intakes in flight per session: an abort of the session also cancels an
|
|
66
|
+
// attachment conversion that has not yet become a turn.
|
|
67
|
+
const intakeAborts = new Map();
|
|
68
|
+
|
|
69
|
+
async function submitSession({
|
|
70
|
+
sessionId,
|
|
71
|
+
prompt,
|
|
72
|
+
options = {},
|
|
73
|
+
open: openHints = {},
|
|
74
|
+
baseRevision = null,
|
|
75
|
+
signal = null,
|
|
76
|
+
} = {}) {
|
|
66
77
|
const id = String(sessionId || '');
|
|
67
78
|
if (!id) throw new TypeError('sessionId is required');
|
|
68
79
|
const entry = await entryForSession(id, openHints || {});
|
|
69
80
|
const target = entry.runtime.submitAsync;
|
|
70
81
|
if (typeof target !== 'function') throw new TypeError('session runtime must implement submitAsync');
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
const intakeAbort = new AbortController();
|
|
83
|
+
const forwardAbort = () => intakeAbort.abort(signal.reason);
|
|
84
|
+
if (signal?.aborted) forwardAbort();
|
|
85
|
+
else signal?.addEventListener?.('abort', forwardAbort, { once: true });
|
|
86
|
+
if (!intakeAborts.has(id)) intakeAborts.set(id, new Set());
|
|
87
|
+
intakeAborts.get(id).add(intakeAbort);
|
|
88
|
+
let intake;
|
|
89
|
+
try {
|
|
90
|
+
intake = await preparePromptSubmissionForProvider(
|
|
91
|
+
materializePromptSubmission(prompt, options || {}),
|
|
92
|
+
{ nativePdf: providerNativePdf(entry.runtime.provider || entry.runtime.session?.provider || '') },
|
|
93
|
+
{ signal: intakeAbort.signal }
|
|
94
|
+
);
|
|
95
|
+
} finally {
|
|
96
|
+
signal?.removeEventListener?.('abort', forwardAbort);
|
|
97
|
+
intakeAborts.get(id)?.delete(intakeAbort);
|
|
98
|
+
if (!intakeAborts.get(id)?.size) intakeAborts.delete(id);
|
|
99
|
+
}
|
|
100
|
+
// A cancel that landed after the last conversion step must not submit.
|
|
101
|
+
intakeAbort.signal.throwIfAborted();
|
|
74
102
|
// Await intake only: submitAsync resolves once the prompt is represented by
|
|
75
103
|
// the queue/user row, while provider execution remains daemon-owned and
|
|
76
104
|
// detached.
|
|
@@ -131,6 +159,7 @@ export function createSessionTurnCalls(ctx) {
|
|
|
131
159
|
async function abortSession({ sessionId, open: openHints = {}, options = {}, baseRevision = null } = {}) {
|
|
132
160
|
const id = String(sessionId || '');
|
|
133
161
|
if (!id) throw new TypeError('sessionId is required');
|
|
162
|
+
for (const intakeAbort of intakeAborts.get(id) ?? []) intakeAbort.abort();
|
|
134
163
|
const entry = await entryForSession(id, openHints || {});
|
|
135
164
|
const target = entry.runtime.abort;
|
|
136
165
|
if (typeof target !== 'function') throw new TypeError('session action abort is unavailable');
|
|
@@ -23,6 +23,8 @@ import { createViewerRegistry } from './session-service/viewers.mjs';
|
|
|
23
23
|
import { createSessionEntries } from './session-service/entries.mjs';
|
|
24
24
|
import { createSessionCalls } from './session-service/session-calls.mjs';
|
|
25
25
|
import { createQuotaResumeScheduler } from './session-service/quota-resume.mjs';
|
|
26
|
+
import { createAgentRouteFollow } from './session-service/agent-route-follow.mjs';
|
|
27
|
+
import { registerDelegatedApprovalOpener } from '../runtime/shared/delegated-approval-host.mjs';
|
|
26
28
|
|
|
27
29
|
const EXTERNAL_SESSION_ACTIONS = new Set([
|
|
28
30
|
...SESSION_READ_ACTION_SET,
|
|
@@ -205,6 +207,17 @@ export function createSessionService({
|
|
|
205
207
|
retainUnwatched: retention.retainUnwatched,
|
|
206
208
|
createSession: calls.createSession,
|
|
207
209
|
});
|
|
210
|
+
// A sub-agent's approval shows in its top-level chat; one not loaded is
|
|
211
|
+
// brought up so the copy (and its notifications) appear there.
|
|
212
|
+
const unregisterApprovalOpener = registerDelegatedApprovalOpener((sessionId) => calls.materializeSession(sessionId));
|
|
213
|
+
// A bot's saved route reaches its hosted home and room-member chats from their next turn.
|
|
214
|
+
const agentRouteFollow = createAgentRouteFollow({
|
|
215
|
+
sessionsById,
|
|
216
|
+
sessionOwner: projection.sessionOwner,
|
|
217
|
+
advance: projection.advance,
|
|
218
|
+
publishStep: projection.publishStep,
|
|
219
|
+
log,
|
|
220
|
+
});
|
|
208
221
|
const quotaUsableReader = typeof readQuotaUsable === 'function' ? readQuotaUsable : async () => false;
|
|
209
222
|
const quotaResume = quotaResumeStore
|
|
210
223
|
? createQuotaResumeScheduler({
|
|
@@ -219,6 +232,8 @@ export function createSessionService({
|
|
|
219
232
|
function stop(reason = 'service stop') {
|
|
220
233
|
if (stopPromise) return stopPromise;
|
|
221
234
|
closed = true;
|
|
235
|
+
unregisterApprovalOpener();
|
|
236
|
+
agentRouteFollow.unsubscribe();
|
|
222
237
|
quotaResume?.stop();
|
|
223
238
|
stopPromise = Promise.resolve().then(async () => {
|
|
224
239
|
try {
|
|
@@ -243,6 +258,11 @@ export function createSessionService({
|
|
|
243
258
|
return Boolean(owner) && retention.stateBusy(owner.runtime?.getState?.());
|
|
244
259
|
}
|
|
245
260
|
|
|
261
|
+
/** Whether the runtime hosting `sessionId` shows an approval card waiting on the user. */
|
|
262
|
+
function liveSessionAwaitingApproval(sessionId) {
|
|
263
|
+
return Boolean(projection.sessionOwner(sessionId)?.runtime?.getState?.()?.toolApproval);
|
|
264
|
+
}
|
|
265
|
+
|
|
246
266
|
/** Show a transcript notice in the hosted runtime of `sessionId` (no turn)
|
|
247
267
|
* and publish it to its views; false when no runtime hosts it. */
|
|
248
268
|
function pushLiveSessionNotice(sessionId, { text, tone = 'info', ...options } = {}) {
|
|
@@ -300,6 +320,7 @@ export function createSessionService({
|
|
|
300
320
|
methods: {
|
|
301
321
|
...calls,
|
|
302
322
|
liveSessionBusy,
|
|
323
|
+
liveSessionAwaitingApproval,
|
|
303
324
|
pushLiveSessionNotice,
|
|
304
325
|
stop,
|
|
305
326
|
startQuotaResume: () => quotaResume?.start(),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { sanitizeForWire } from './session-wire-values.mjs';
|
|
2
|
+
import { stripAgentMessageEnvelope } from '../runtime/shared/agent-message-envelope.mjs';
|
|
3
|
+
import { transcriptSourceFields } from '../runtime/shared/transcript-metadata.mjs';
|
|
2
4
|
|
|
3
5
|
/** Immutable source fields keep their wire identity until they actually change.
|
|
4
6
|
* In particular, a live tail must not rebuild the settled transcript or resend
|
|
@@ -29,15 +31,23 @@ export function projectSessionState(entry, raw) {
|
|
|
29
31
|
}
|
|
30
32
|
let cloned;
|
|
31
33
|
if (key === 'queued' && Array.isArray(value)) {
|
|
32
|
-
cloned = value.map((item) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
cloned = value.map((item) => {
|
|
35
|
+
// A queued bot message reads like its delivered row: the sender tag
|
|
36
|
+
// and the message without its envelope.
|
|
37
|
+
const source = transcriptSourceFields(item?.transcriptMeta);
|
|
38
|
+
const queuedText = String(item?.displayText ?? item?.text ?? '');
|
|
39
|
+
const text = (source.fromAgent ? stripAgentMessageEnvelope(queuedText) : queuedText).slice(0, 2_000);
|
|
40
|
+
return {
|
|
41
|
+
id: item?.id,
|
|
42
|
+
submittedAt: item?.submittedAt,
|
|
43
|
+
text,
|
|
44
|
+
displayText: text,
|
|
45
|
+
mode: item?.mode || 'prompt',
|
|
46
|
+
priority: item?.priority || 'next',
|
|
47
|
+
...source,
|
|
48
|
+
...(Array.isArray(item?.images) && item.images.length ? { images: item.images } : {}),
|
|
49
|
+
};
|
|
50
|
+
});
|
|
41
51
|
} else if (key === 'items' && Array.isArray(value)) {
|
|
42
52
|
const items = entry.itemCache;
|
|
43
53
|
const nextItems = new Map();
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { encodeCatalogCursor } from '../runtime/agent/orchestrator/session/catalog-db/schema.mjs';
|
|
2
|
+
import { UNTRUSTED_NOTE, sessionBotOf } from '../session-runtime/bot-status.mjs';
|
|
3
|
+
import { escapeHarnessTags } from '../runtime/shared/shell-output-summary.mjs';
|
|
2
4
|
import { truncateToolText } from '../runtime/shared/tool-primitives.mjs';
|
|
3
5
|
import { summarizeToolResult } from '../runtime/shared/tool-result-summary.mjs';
|
|
4
6
|
|
|
@@ -6,18 +8,43 @@ import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../runtime/share
|
|
|
6
8
|
|
|
7
9
|
export const SESSION_TOOL_OUTPUT_BYTES = TOOL_OUTPUT_TAIL_BYTES;
|
|
8
10
|
const MESSAGE_TEXT_LIMIT = 2000;
|
|
11
|
+
const LIST_PREVIEW_LIMIT = 100;
|
|
9
12
|
const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
10
13
|
|
|
11
|
-
/** Keep catalog paging authoritative even when the output budget shortens a page.
|
|
12
|
-
|
|
14
|
+
/** Keep catalog paging authoritative even when the output budget shortens a page.
|
|
15
|
+
* `rich` adds the owning bot, last activity, latest line and working state
|
|
16
|
+
* (never for a background caller: bot-status.mjs scopedBot). */
|
|
17
|
+
export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
13
18
|
const raw = page.sessions;
|
|
14
|
-
const sessions = raw.slice(0, limit).map((row) =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const sessions = raw.slice(0, limit).map((row) => {
|
|
20
|
+
const base = {
|
|
21
|
+
id: row.id,
|
|
22
|
+
...(row.title || row.preview
|
|
23
|
+
? { title: escapeHarnessTags(truncateToolText(row.title || row.preview, 160)) }
|
|
24
|
+
: {}),
|
|
25
|
+
...(row.status ? { status: row.status } : {}),
|
|
26
|
+
...(row.cwd ? { cwd: row.cwd } : {}),
|
|
27
|
+
...(row.archived === true ? { archived: true } : {}),
|
|
28
|
+
};
|
|
29
|
+
if (!rich) return base;
|
|
30
|
+
// The bot it belongs to: its chat, room seat or the task's creator.
|
|
31
|
+
const bot = sessionBotOf(row);
|
|
32
|
+
const lastUsedAt = Number(row.lastUsedAt) || 0;
|
|
33
|
+
const preview = String(row.lastMessagePreview || '').replace(/\s+/g, ' ');
|
|
34
|
+
return {
|
|
35
|
+
...base,
|
|
36
|
+
...(bot ? { bot } : {}),
|
|
37
|
+
...(lastUsedAt ? { lastUsedAt: new Date(lastUsedAt).toISOString() } : {}),
|
|
38
|
+
// The latest user or assistant line, quoted data.
|
|
39
|
+
...(preview.trim() ? { preview: escapeHarnessTags(truncateToolText(preview, LIST_PREVIEW_LIMIT)) } : {}),
|
|
40
|
+
...(row.working === true || row.agentWorking === true ? { working: true } : {}),
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
const result = {
|
|
44
|
+
sessions,
|
|
45
|
+
nextCursor: page.nextCursor ?? null,
|
|
46
|
+
...(sessions.some((row) => row.preview) ? { note: UNTRUSTED_NOTE } : {}),
|
|
47
|
+
};
|
|
21
48
|
for (;;) {
|
|
22
49
|
if (sessions.length < raw.length && sessions.length) {
|
|
23
50
|
result.nextCursor = encodeCatalogCursor(raw[sessions.length - 1]);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Staged dynamic import of a large module graph. Loading a graph (file reads,
|
|
2
|
+
// compilation, evaluation) runs synchronously inside one import() call, so the
|
|
3
|
+
// daemon's session-runtime warm-up held the event loop for ~0.5 s in one
|
|
4
|
+
// piece right after `daemon-ready`. Importing the graph's top-level stages one
|
|
5
|
+
// loop turn apart splits that block without changing what is loaded.
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
|
|
9
|
+
// A static `import … from './x'`, `export … from './x'` or bare `import './x'`
|
|
10
|
+
// at the start of a line, in source order.
|
|
11
|
+
const STATIC_RELATIVE_IMPORT =
|
|
12
|
+
/^(?:import|export)\b[^;]*?\bfrom\s*['"](\.{1,2}\/[^'"]+)['"]|^import\s*['"](\.{1,2}\/[^'"]+)['"]/gm;
|
|
13
|
+
|
|
14
|
+
/** The relative static imports of the module at `url`, resolved, in source order. */
|
|
15
|
+
export function staticRelativeImports(url) {
|
|
16
|
+
const source = readFileSync(fileURLToPath(url), 'utf8');
|
|
17
|
+
return [...source.matchAll(STATIC_RELATIVE_IMPORT)].map((match) => new URL(match[1] || match[2], url).href);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const nextTurn = () => new Promise((resolve) => setImmediate(resolve));
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* import(url), after importing each static relative dependency of `stagesOf`
|
|
24
|
+
* (in its source order, one loop turn apart). Module evaluation order is the
|
|
25
|
+
* one a single import gives — dependencies depth-first in source order — as
|
|
26
|
+
* long as no module of a stage's graph imports `stagesOf` or an importer of it
|
|
27
|
+
* back. Staging stops at the first stage that fails, so no later stage
|
|
28
|
+
* evaluates; the final import then reports the failure as a single import
|
|
29
|
+
* would.
|
|
30
|
+
*/
|
|
31
|
+
export async function importInStages(url, stagesOf) {
|
|
32
|
+
let stages = [];
|
|
33
|
+
try {
|
|
34
|
+
stages = staticRelativeImports(stagesOf);
|
|
35
|
+
} catch {
|
|
36
|
+
// Unreadable source: one import, as before.
|
|
37
|
+
}
|
|
38
|
+
for (const stage of stages) {
|
|
39
|
+
try {
|
|
40
|
+
await import(stage);
|
|
41
|
+
} catch {
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
await nextTurn();
|
|
45
|
+
}
|
|
46
|
+
return import(url);
|
|
47
|
+
}
|
package/src/tui/App.jsx
CHANGED
|
@@ -516,6 +516,8 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
|
|
|
516
516
|
syncPromptLayoutRows,
|
|
517
517
|
showPromptHint,
|
|
518
518
|
clearPromptHint,
|
|
519
|
+
installPastedImages,
|
|
520
|
+
installPastedTexts,
|
|
519
521
|
});
|
|
520
522
|
|
|
521
523
|
// PROMPT HANDLER cluster extracted to app/use-prompt-handlers.mjs.
|
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
// the Advanced list of provider default idle windows edited as text.
|
|
4
4
|
|
|
5
5
|
// Lead BP4 messages cache TTL follows autoClear (cache-strategy.mjs
|
|
6
|
-
// resolveLeadMessagesTtl): off or idle>=1h -> 1h, shorter
|
|
6
|
+
// resolveLeadMessagesTtl): off or idle>=1h (incl. unlimited) -> 1h, shorter
|
|
7
|
+
// idle -> 5m.
|
|
7
8
|
const HOUR_MS = 60 * 60 * 1000;
|
|
9
|
+
// Typed (and shown) for "never auto-clear"; the runtime stores it as 0.
|
|
10
|
+
const UNLIMITED_INPUT = 'unlimited';
|
|
8
11
|
|
|
9
|
-
const formatDurationInput = (ms) => {
|
|
12
|
+
const formatDurationInput = (ms, unlimited = false) => {
|
|
13
|
+
if (unlimited) return UNLIMITED_INPUT;
|
|
10
14
|
const value = Math.max(0, Math.round(Number(ms) || 0));
|
|
11
15
|
if (value > 0 && value % HOUR_MS === 0) return `${value / HOUR_MS}h`;
|
|
12
16
|
if (value > 0 && value % 60_000 === 0) return `${value / 60_000}m`;
|
|
@@ -39,7 +43,7 @@ export function createAutoClearPicker({
|
|
|
39
43
|
label: entry.provider,
|
|
40
44
|
marker: entry.provider === provider ? '✓' : '',
|
|
41
45
|
markerColor: theme.success,
|
|
42
|
-
meta: `${formatDuration(entry.idleMs)}${entry.custom ? ' custom' : ''}`,
|
|
46
|
+
meta: `${entry.unlimited ? 'Unlimited' : formatDuration(entry.idleMs)}${entry.custom ? ' custom' : ''}`,
|
|
43
47
|
description: `Default idle window for ${entry.provider}. Enter to edit as text.`,
|
|
44
48
|
_action: 'provider-default',
|
|
45
49
|
_entry: entry,
|
|
@@ -66,10 +70,10 @@ export function createAutoClearPicker({
|
|
|
66
70
|
store.pushNotice('autoclear unavailable', 'warn');
|
|
67
71
|
return;
|
|
68
72
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
'
|
|
72
|
-
);
|
|
73
|
+
let notice = 'autoclear off';
|
|
74
|
+
if (next.enabled)
|
|
75
|
+
notice = next.unlimited ? 'autoclear on · unlimited' : `autoclear on · idle ${formatDuration(next.idleMs)}`;
|
|
76
|
+
store.pushNotice(notice, 'info');
|
|
73
77
|
})
|
|
74
78
|
.catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, 'error'))
|
|
75
79
|
.finally(settled);
|
|
@@ -80,8 +84,8 @@ export function createAutoClearPicker({
|
|
|
80
84
|
setSettingsPrompt({
|
|
81
85
|
kind: 'autoclear-provider',
|
|
82
86
|
label: `Auto-clear · ${entry.provider}`,
|
|
83
|
-
hint: `Type a duration like 10m, 1h, or 24h. Empty resets to built-in ${formatDurationInput(entry.builtInMs)}.`,
|
|
84
|
-
initialValue: formatDurationInput(entry.idleMs),
|
|
87
|
+
hint: `Type a duration like 10m, 1h, or 24h, or ${UNLIMITED_INPUT} to never auto-clear. Empty resets to built-in ${formatDurationInput(entry.builtInMs, entry.builtInUnlimited)}.`,
|
|
88
|
+
initialValue: formatDurationInput(entry.idleMs, entry.unlimited),
|
|
85
89
|
provider: entry.provider,
|
|
86
90
|
builtInMs: entry.builtInMs,
|
|
87
91
|
returnTo,
|
|
@@ -109,18 +113,20 @@ export function createAutoClearPicker({
|
|
|
109
113
|
const current = await readCurrent();
|
|
110
114
|
const enabled = current?.enabled !== false;
|
|
111
115
|
const idleMs = Number(current?.idleMs || HOUR_MS);
|
|
116
|
+
const unlimited = current?.unlimited === true;
|
|
112
117
|
const cacheTtlLabel = !enabled || idleMs >= HOUR_MS ? '1h' : '5m';
|
|
113
118
|
let sourceLabel = `${current?.provider || 'default'} default`;
|
|
114
119
|
if (current?.providerCustom) sourceLabel = `${current.provider} override`;
|
|
115
120
|
else if (current?.custom) sourceLabel = 'global';
|
|
121
|
+
const clearText = unlimited
|
|
122
|
+
? `Never clear idle sessions (${sourceLabel})`
|
|
123
|
+
: `Clear idle sessions after ${formatDuration(idleMs)} (${sourceLabel})`;
|
|
116
124
|
const items = [
|
|
117
125
|
{
|
|
118
126
|
value: 'toggle',
|
|
119
127
|
label: 'Auto-clear',
|
|
120
128
|
meta: enabled ? 'On' : 'Off',
|
|
121
|
-
description: enabled
|
|
122
|
-
? `Clear idle sessions after ${formatDuration(idleMs)} (${sourceLabel}) · lead cache TTL ${cacheTtlLabel}.`
|
|
123
|
-
: 'Idle auto-clear disabled.',
|
|
129
|
+
description: enabled ? `${clearText} · lead cache TTL ${cacheTtlLabel}.` : 'Idle auto-clear disabled.',
|
|
124
130
|
_action: 'toggle',
|
|
125
131
|
},
|
|
126
132
|
{
|
|
@@ -132,7 +138,7 @@ export function createAutoClearPicker({
|
|
|
132
138
|
];
|
|
133
139
|
own.paint({
|
|
134
140
|
title: 'Auto-clear',
|
|
135
|
-
description: `Clear idle context after ${enabled ? `${formatDuration(idleMs)} (${sourceLabel})` : 'never'} · lead cache TTL ${cacheTtlLabel}.`,
|
|
141
|
+
description: `Clear idle context after ${enabled && !unlimited ? `${formatDuration(idleMs)} (${sourceLabel})` : 'never'} · lead cache TTL ${cacheTtlLabel}.`,
|
|
136
142
|
help: '↑/↓ Select · ←/→ Toggle On/Off · Enter Open/Toggle · Esc Close',
|
|
137
143
|
indexMode: 'always',
|
|
138
144
|
labelWidth: 10,
|
|
@@ -45,6 +45,8 @@ export function useMessageSelector({
|
|
|
45
45
|
syncPromptLayoutRows,
|
|
46
46
|
showPromptHint,
|
|
47
47
|
clearPromptHint,
|
|
48
|
+
installPastedImages,
|
|
49
|
+
installPastedTexts,
|
|
48
50
|
}) {
|
|
49
51
|
// Cheap enough to recompute only when the transcript array identity changes;
|
|
50
52
|
// the prompt asks for this on every Escape, never per keystroke.
|
|
@@ -64,11 +66,22 @@ export function useMessageSelector({
|
|
|
64
66
|
return false;
|
|
65
67
|
}
|
|
66
68
|
clearPromptHint();
|
|
69
|
+
// The prompt's pasted blocks return with it, so its tokens still expand.
|
|
70
|
+
if (restored.pastedImages) installPastedImages?.(restored.pastedImages, { merge: true });
|
|
71
|
+
if (restored.pastedTexts) installPastedTexts?.(restored.pastedTexts, { merge: true });
|
|
67
72
|
syncPromptLayoutRows(text);
|
|
68
73
|
setPromptDraftOverride({ id: Date.now(), value: text });
|
|
74
|
+
if (restored.notice) showPromptHint(restored.notice, 'error');
|
|
69
75
|
return true;
|
|
70
76
|
},
|
|
71
|
-
[
|
|
77
|
+
[
|
|
78
|
+
clearPromptHint,
|
|
79
|
+
syncPromptLayoutRows,
|
|
80
|
+
setPromptDraftOverride,
|
|
81
|
+
showPromptHint,
|
|
82
|
+
installPastedImages,
|
|
83
|
+
installPastedTexts,
|
|
84
|
+
]
|
|
72
85
|
);
|
|
73
86
|
|
|
74
87
|
const openMessageSelector = useCallback(() => {
|
|
@@ -89,7 +102,7 @@ export function useMessageSelector({
|
|
|
89
102
|
own.close();
|
|
90
103
|
let restored;
|
|
91
104
|
try {
|
|
92
|
-
restored = store.rewindToItem?.(value);
|
|
105
|
+
restored = store.rewindToItem?.(value, { restoreFiles: false });
|
|
93
106
|
} catch (error) {
|
|
94
107
|
showPromptHint(`rewind failed: ${error?.message || error}`, 'error');
|
|
95
108
|
return;
|
|
@@ -221,6 +221,18 @@ export const loadProviderDisplayNames = async (store) => {
|
|
|
221
221
|
return names;
|
|
222
222
|
};
|
|
223
223
|
|
|
224
|
+
/** Provider names for the picker: custom rows' own `providerName` first, then
|
|
225
|
+
* setup names over them (setup wins). Works when setup is missing or failed. */
|
|
226
|
+
export const catalogProviderDisplayNames = (models, setupNames = null) => {
|
|
227
|
+
const names = {};
|
|
228
|
+
for (const model of Array.isArray(models) ? models : []) {
|
|
229
|
+
const provider = String(model?.provider || '').trim();
|
|
230
|
+
const name = String(model?.providerName || '').trim();
|
|
231
|
+
if (provider.startsWith('custom-') && name) names[provider] = name;
|
|
232
|
+
}
|
|
233
|
+
return { ...names, ...setupNames };
|
|
234
|
+
};
|
|
235
|
+
|
|
224
236
|
/** `{ id, text }` for each provider whose model list failed, with the reason
|
|
225
237
|
* (the setup row's `catalogError`) and what to do about it. */
|
|
226
238
|
export const loadProviderCatalogFailures = async (store) => {
|
|
@@ -368,9 +380,11 @@ const routeModelDetails = (route) =>
|
|
|
368
380
|
.filter(Boolean)
|
|
369
381
|
.join(' · ');
|
|
370
382
|
|
|
371
|
-
export const routeLabel = (route) => {
|
|
383
|
+
export const routeLabel = (route, providerNames = null) => {
|
|
372
384
|
if (!route?.provider || !route?.model) return '(unset)';
|
|
373
|
-
return [
|
|
385
|
+
return [resolveProviderDisplayName(route.provider, providerNames), routeModelDetails(route)]
|
|
386
|
+
.filter(Boolean)
|
|
387
|
+
.join(' · ');
|
|
374
388
|
};
|
|
375
389
|
|
|
376
390
|
export const routeModelLabel = (route) => (route?.model ? routeModelDetails(route) : '(unset)');
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
normalizeModelOptions,
|
|
15
15
|
buildCatalogFailureItems,
|
|
16
16
|
buildModelProviderItems,
|
|
17
|
+
catalogProviderDisplayNames,
|
|
17
18
|
loadProviderCatalogFailures,
|
|
18
19
|
loadProviderDisplayNames,
|
|
19
20
|
} from './model-options.mjs';
|
|
@@ -83,7 +84,7 @@ export function createModelPicker({
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
const models = normalizeModelOptions(providerModels);
|
|
86
|
-
const providerNames = await loadProviderDisplayNames(store);
|
|
87
|
+
const providerNames = catalogProviderDisplayNames(models, await loadProviderDisplayNames(store));
|
|
87
88
|
const catalogFailures = await loadProviderCatalogFailures(store);
|
|
88
89
|
const activeRoute = options.currentRoute || {
|
|
89
90
|
provider: state.provider,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* openers (openModelPicker) thread as lazy getter wrappers so they resolve the
|
|
8
8
|
* live binding at call time.
|
|
9
9
|
*/
|
|
10
|
+
import { loadProviderDisplayNames } from './model-options.mjs';
|
|
10
11
|
import { createAgentsPicker } from './route-pickers/agents-picker.mjs';
|
|
11
12
|
import { createOutputStylePicker } from './route-pickers/output-style-picker.mjs';
|
|
12
13
|
import { createWorkflowPicker } from './route-pickers/workflow-picker.mjs';
|
|
@@ -59,7 +60,8 @@ export function createRoutePickers({
|
|
|
59
60
|
store.pushNotice('Web-search model save is already running.', 'warn');
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
+
const providerNames = await loadProviderDisplayNames(store);
|
|
64
|
+
store.pushNotice(`Web-search model set to ${routeLabel(result, providerNames)}`, 'info');
|
|
63
65
|
return result;
|
|
64
66
|
},
|
|
65
67
|
onAfterSelect: null,
|
|
@@ -139,9 +139,9 @@ export function buildSettingsItems({
|
|
|
139
139
|
{
|
|
140
140
|
value: 'autoclear',
|
|
141
141
|
label: 'Auto-clear',
|
|
142
|
-
meta: autoClearEnabled ? `On (${formatDuration(autoClear.idleMs)})` : 'Off',
|
|
142
|
+
meta: autoClearEnabled ? `On (${autoClear.unlimited ? 'Unlimited' : formatDuration(autoClear.idleMs)})` : 'Off',
|
|
143
143
|
description: autoClearEnabled
|
|
144
|
-
? `Clear idle sessions after ${formatDuration(autoClear.idleMs)}${autoClearSource}. Enter for options.`
|
|
144
|
+
? `${autoClear.unlimited ? 'Never clear idle sessions' : `Clear idle sessions after ${formatDuration(autoClear.idleMs)}`}${autoClearSource}. Enter for options.`
|
|
145
145
|
: 'Idle auto-clear disabled. Enter for options.',
|
|
146
146
|
_action: 'autoclear',
|
|
147
147
|
},
|
|
@@ -30,7 +30,7 @@ export const SLASH_COMMANDS = [
|
|
|
30
30
|
{
|
|
31
31
|
name: 'autoclear',
|
|
32
32
|
usage: '/autoclear',
|
|
33
|
-
params: '[on|off|duration]',
|
|
33
|
+
params: '[on|off|duration|unlimited]',
|
|
34
34
|
description: 'Reduce cache-miss cost after long idle gaps',
|
|
35
35
|
},
|
|
36
36
|
{ name: 'resume', usage: '/resume', params: '[id]', description: 'Resume a saved chat' },
|