mixdog 1.0.11 → 1.1.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/NOTICE.md +20 -0
- package/README.md +75 -181
- package/package.json +9 -4
- package/scripts/build-shipped-history.mjs +131 -0
- package/scripts/check-changelog-locales.mjs +203 -0
- package/scripts/computer-task-cost-report.mjs +0 -4
- package/scripts/lib/run-node-tests.mjs +235 -13
- package/scripts/lib/test-failure-records.mjs +5 -0
- package/scripts/lib/test-failure-summary.mjs +9 -3
- package/scripts/lib/test-spawn-ledger.mjs +19 -0
- package/scripts/prune-embedding-runtime.mjs +9 -5
- package/scripts/sync-client-version-floors.mjs +100 -0
- package/scripts/test-direct.mjs +16 -1
- package/src/agents/advisor/AGENT.md +38 -0
- package/src/agents/advisor/agent.json +6 -0
- package/src/agents/reviewer/AGENT.md +5 -2
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +381 -0
- package/src/defaults/skills/docx/SKILL.md +7 -5
- package/src/defaults/skills/docx/references/html.md +9 -8
- package/src/defaults/skills/docx/references/native-authoring.md +28 -18
- package/src/defaults/skills/goal-management/SKILL.md +11 -5
- package/src/defaults/skills/local-provider/SKILL.md +2 -1
- package/src/defaults/skills/pdf/SKILL.md +9 -6
- package/src/defaults/skills/pdf/references/html.md +17 -12
- package/src/defaults/skills/pptx/SKILL.md +8 -6
- package/src/defaults/skills/pptx/references/composition.md +4 -4
- package/src/defaults/skills/pptx/references/concepts.md +168 -0
- package/src/defaults/skills/pptx/references/direction.md +5 -4
- package/src/defaults/skills/pptx/references/html.md +6 -29
- package/src/defaults/skills/pptx/references/kit-index.md +11 -3
- package/src/defaults/skills/pptx/references/kit.md +27 -5
- package/src/defaults/skills/pptx/references/review.md +6 -5
- package/src/defaults/skills/setup/SKILL.md +5 -8
- package/src/defaults/skills/setup/references/actions.md +61 -31
- package/src/defaults/skills/setup/references/surfaces.md +12 -10
- package/src/defaults/skills/xlsx/SKILL.md +8 -6
- package/src/defaults/skills/xlsx/references/html.md +8 -4
- package/src/defaults/skills/xlsx/references/model-conventions.md +2 -0
- package/src/defaults/skills/xlsx/references/report-design.md +32 -16
- package/src/help.mjs +1 -1
- package/src/lib/rules-builder.cjs +1 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.d.mts +1 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +44 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +9 -1
- package/src/runtime/agent/orchestrator/config.mjs +102 -21
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +90 -26
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +44 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +79 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +29 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -22
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +28 -10
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +14 -72
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +19 -3
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +20 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-sink.mjs +36 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +11 -17
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +388 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +92 -109
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +107 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +138 -30
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +32 -15
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +39 -5
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/lib/note-error-usage.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +57 -0
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +20 -15
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +14 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +56 -11
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +28 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +27 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +7 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -8
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +26 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +34 -15
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +12 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +0 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +0 -19
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +12 -43
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +39 -9
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +31 -9
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +13 -38
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +40 -9
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +7 -39
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +28 -101
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +3 -6
- package/src/runtime/agent/orchestrator/providers/openai-service-tier.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/openai-startup-prewarm.mjs +5 -195
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +9 -18
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +4 -66
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +11 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/acquire-attempt.mjs +3 -15
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/attempt-request.mjs +6 -56
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +1 -19
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure-stamps.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts.mjs +3 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-outcome.mjs +10 -89
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-span.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-trace.mjs +0 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +34 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +3 -7
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +44 -19
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +40 -12
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +70 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -3
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +11 -0
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +31 -41
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +5 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +0 -17
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +0 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +0 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +18 -4
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -1
- package/src/runtime/agent/orchestrator/runtime-core/session-route-policy.mjs +16 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +7 -7
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +45 -2
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/eager-dispatch/entry.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +6 -13
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +114 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +5 -9
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +51 -18
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +6 -9
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +63 -3
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +10 -28
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +10 -19
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +1 -3
- package/src/runtime/agent/orchestrator/stall-policy.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +18 -8
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +19 -20
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +6 -11
- package/src/runtime/agent/orchestrator/tools/builtin/file-version-test-helpers.mjs +11 -0
- package/src/runtime/agent/orchestrator/tools/builtin/file-version.mjs +13 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-single-file-rescue.mjs +8 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +25 -12
- package/src/runtime/agent/orchestrator/tools/builtin/raw-content-publication.mjs +17 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +136 -76
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +15 -17
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +30 -16
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +4 -11
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +7 -3
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-validation.mjs +16 -19
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +14 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +58 -8
- package/src/runtime/agent/orchestrator/tools/patch/content-guard.mjs +47 -0
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +155 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch/native-proofs.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/dispatch/native-snapshots.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +19 -16
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +13 -44
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/post-patch-excerpts.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +47 -7
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +72 -8
- package/src/runtime/agent/orchestrator/tools/patch/section-coalesce.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/patch/sequence/run.mjs +9 -1
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +9 -1
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +16 -4
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +35 -14
- package/src/runtime/agent/orchestrator/tools/patch/wave.mjs +42 -4
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-codepage.mjs +296 -0
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +75 -24
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -0
- package/src/runtime/channels/lib/config.mjs +3 -8
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +7 -3
- package/src/{tui → runtime/channels}/lib/voice-setup.mjs +38 -22
- package/src/runtime/channels/lib/webhook/request-handler.mjs +42 -8
- package/src/runtime/computer-bridge/actions.mjs +2 -0
- package/src/runtime/effort-judge/judge-client.mjs +125 -25
- package/src/runtime/effort-judge/judge-input.mjs +96 -0
- package/src/runtime/effort-judge/judge-worker.mjs +52 -20
- package/src/runtime/effort-judge/model-install.mjs +74 -0
- package/src/runtime/effort-judge/model-manifest.json +21 -0
- package/src/runtime/effort-judge/previous-human-request.mjs +162 -0
- package/src/runtime/effort-judge/verified-context-input.mjs +10 -0
- package/src/runtime/github/tool.mjs +214 -14
- package/src/runtime/local-provider/context-settings.mjs +15 -6
- package/src/runtime/local-provider/gguf-header.mjs +13 -5
- package/src/runtime/local-provider/hugging-face.mjs +27 -5
- package/src/runtime/local-provider/install-progress.mjs +7 -0
- package/src/runtime/local-provider/managed-runtime.mjs +2 -1
- package/src/runtime/local-provider/model-maintenance.mjs +15 -6
- package/src/runtime/local-provider/resumable-installations.mjs +40 -1
- package/src/runtime/local-provider/server.mjs +2 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +12 -0
- package/src/runtime/memory/lib/http-router/session-routes.mjs +2 -1
- package/src/runtime/memory/lib/memory-config-flags.mjs +3 -2
- package/src/runtime/memory/lib/memory-embed.mjs +5 -0
- package/src/runtime/memory/lib/pg/process.mjs +57 -5
- package/src/runtime/office/README.md +13 -7
- package/src/runtime/office/authoring/docx-html-build.mjs +4 -4
- package/src/runtime/office/authoring/docx-html-measure.mjs +60 -0
- package/src/runtime/office/authoring/pdf-author-action.mjs +6 -1
- package/src/runtime/office/authoring/pptx-brief.mjs +40 -1
- package/src/runtime/office/authoring/pptx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/bench/deck-bench.mjs +1 -1
- package/src/runtime/office/com/office-com-host.ps1 +8 -0
- package/src/runtime/office/core/office-actions-render.mjs +2 -0
- package/src/runtime/office/design/design-art-direction.mjs +10 -2
- package/src/runtime/office/design/design-discipline.mjs +4 -5
- package/src/runtime/office/design/design-tokens.mjs +20 -1
- package/src/runtime/office/design/docx/design-docx/front-matter.mjs +7 -4
- package/src/runtime/office/design/docx/design-docx/section.mjs +3 -1
- package/src/runtime/office/design/docx/design-docx/writer.mjs +1 -0
- package/src/runtime/office/design/docx/design-docx-components.mjs +19 -15
- package/src/runtime/office/design/docx/design-docx.mjs +5 -6
- package/src/runtime/office/design/docx/document-typography.mjs +20 -6
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +9 -2
- package/src/runtime/office/pdf/document-preview.mjs +133 -12
- package/src/runtime/office/pdf/pdf-writer.mjs +56 -22
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +46 -3
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +27 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +21 -5
- package/src/runtime/office/quality/assurance-structure-docx.mjs +41 -9
- package/src/runtime/office/quality/design-aesthetics.mjs +4 -2
- package/src/runtime/office/quality/design-deck-diversity.mjs +15 -3
- package/src/runtime/office/quality/design-review.mjs +13 -5
- package/src/runtime/office/quality/document-brief.mjs +8 -2
- package/src/runtime/office/quality/forced-break-pages.mjs +203 -0
- package/src/runtime/office/quality/pptx-deck-rubric.mjs +21 -3
- package/src/runtime/office/quality/quality-pipeline.mjs +14 -17
- package/src/runtime/session-search/session-search-db.mjs +183 -0
- package/src/runtime/session-search/session-search-ingest.mjs +106 -0
- package/src/runtime/shared/agent-route-config.mjs +50 -2
- package/src/runtime/shared/bounded-file-read.mjs +166 -0
- package/src/runtime/shared/builtin-grandfathering.mjs +37 -0
- package/src/runtime/shared/config.mjs +24 -4
- package/src/runtime/shared/defaults-separation.mjs +263 -0
- package/src/runtime/shared/error-presentation.mjs +8 -1
- package/src/runtime/shared/llm/anthropic-effort.mjs +4 -0
- package/src/runtime/shared/llm/cost.mjs +4 -2
- package/src/runtime/shared/llm/model-catalog-projection.mjs +1 -1
- package/src/runtime/shared/llm/model-catalog.mjs +25 -0
- package/src/runtime/shared/llm/reasoning-usage.mjs +1 -2
- package/src/runtime/shared/llm/usage-accounting.mjs +14 -4
- package/src/runtime/shared/llm/usage-context.mjs +11 -1
- package/src/runtime/shared/llm/usage-ledger-repair.mjs +3 -1
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +105 -1
- package/src/runtime/shared/llm/usage-ledger-worker.mjs +2 -1
- package/src/runtime/shared/llm/usage-ledger.mjs +72 -5
- package/src/runtime/shared/onnx-runtime-support.mjs +6 -0
- package/src/runtime/shared/orchestration.mjs +14 -6
- package/src/runtime/shared/pristine-execution-contract.json +7 -2
- package/src/runtime/shared/projects.mjs +65 -48
- package/src/runtime/shared/provider-accounts.mjs +47 -6
- package/src/runtime/shared/quota-resume-store.mjs +255 -0
- package/src/runtime/shared/shipped-definitions.mjs +275 -0
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +30 -9
- package/src/runtime/shared/tool-card-model/aggregate-card.mjs +7 -3
- package/src/runtime/shared/tool-card-model/background-task.mjs +17 -1
- package/src/runtime/shared/tool-card-model/card-detail.mjs +10 -4
- package/src/runtime/shared/tool-card-model/card-header.mjs +10 -4
- package/src/runtime/shared/tool-card-model/card-status.mjs +22 -5
- package/src/runtime/shared/tool-card-model/displayed-result.mjs +6 -1
- package/src/runtime/shared/tool-card-model/media-result.mjs +53 -0
- package/src/runtime/shared/tool-card-model/terminal-status.mjs +17 -1
- package/src/runtime/shared/tool-card-model.golden-cases.mjs +1 -1
- package/src/runtime/shared/tool-card-model.golden.json +75 -66
- package/src/runtime/shared/tool-card-model.mjs +1 -0
- package/src/runtime/shared/tool-output-limit.mjs +3 -0
- package/src/runtime/shared/tool-primitives.mjs +24 -18
- package/src/runtime/shared/tool-result-summary.mjs +128 -17
- package/src/runtime/shared/tool-status.mjs +20 -7
- package/src/runtime/shared/tool-surface.mjs +105 -28
- package/src/runtime/shared/tool-work-units.mjs +221 -18
- package/src/runtime/shared/transcript-metadata.mjs +2 -0
- package/src/runtime/shared/turn-review-reply.mjs +2 -0
- package/src/runtime/shared/turn-snapshot.mjs +65 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +202 -22
- package/src/runtime/shared/worker-requests.mjs +14 -2
- package/src/runtime/terminal-bridge/client.mjs +311 -0
- package/src/runtime/terminal-bridge/tool-defs.mjs +36 -0
- package/src/runtime/web-search/lib/ssrf-guard.mjs +12 -56
- package/src/runtime/web-search/tool-defs.mjs +2 -0
- package/src/session-runtime/boot/apis.mjs +30 -5
- package/src/session-runtime/boot/config.mjs +4 -0
- package/src/session-runtime/boot/facade.mjs +4 -1
- package/src/session-runtime/boot/infrastructure.mjs +21 -2
- package/src/session-runtime/boot/session.mjs +5 -5
- package/src/session-runtime/boot/tools.mjs +2 -0
- package/src/session-runtime/builtin-features.d.mts +1 -0
- package/src/session-runtime/channel-config-api.mjs +5 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +3 -0
- package/src/session-runtime/config-lifecycle.mjs +31 -6
- package/src/session-runtime/goal-facade-api.mjs +4 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +15 -3
- package/src/session-runtime/lifecycle/inheritance.mjs +28 -6
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +3 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +7 -1
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +9 -0
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +14 -2
- package/src/session-runtime/lifecycle/teardown.mjs +5 -0
- package/src/session-runtime/local-provider-settings.mjs +10 -0
- package/src/session-runtime/media-api.mjs +32 -22
- package/src/session-runtime/model-recency.mjs +14 -0
- package/src/session-runtime/model-route/route-persist.mjs +17 -2
- package/src/session-runtime/model-route/route-tuning.mjs +16 -5
- package/src/session-runtime/model-route/set-route.mjs +55 -22
- package/src/session-runtime/model-route/web-search-route.mjs +2 -2
- package/src/session-runtime/model-route-api.mjs +2 -1
- package/src/session-runtime/notification-bus.mjs +31 -6
- package/src/session-runtime/provider-auth/login.mjs +6 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +3 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +36 -10
- package/src/session-runtime/quick-model-rows/model-meta.mjs +26 -0
- package/src/session-runtime/quick-model-rows/provider-rows.mjs +40 -14
- package/src/session-runtime/resource-api.mjs +8 -1
- package/src/session-runtime/route-state.mjs +9 -0
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +20 -1
- package/src/session-runtime/runtime-feature-gates.mjs +2 -0
- package/src/session-runtime/runtime-review-api.mjs +12 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +14 -1
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +10 -15
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +6 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +20 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +14 -6
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +2 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +12 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +17 -1
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-admin.mjs +87 -13
- package/src/session-runtime/services/provider-admin.mjs +306 -66
- package/src/session-runtime/services/seeds.mjs +73 -142
- package/src/session-runtime/services/usage-dashboard-model.mjs +29 -0
- package/src/session-runtime/services/usage-dashboard.mjs +7 -0
- package/src/session-runtime/session-address.mjs +125 -0
- package/src/session-runtime/session-create.mjs +57 -2
- package/src/session-runtime/settings-api.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +15 -10
- package/src/session-runtime/settings-compaction-api.mjs +13 -0
- package/src/session-runtime/setup-tool/executor.mjs +93 -40
- package/src/session-runtime/setup-tool/extended-actions.mjs +64 -5
- package/src/session-runtime/setup-tool/settings-contract.mjs +46 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +14 -6
- package/src/session-runtime/tool-surface.mjs +16 -9
- package/src/session-runtime/turn/session-ops.mjs +3 -0
- package/src/session-runtime/turn/share-ops.mjs +4 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +6 -0
- package/src/session-runtime/usage-stats-api.mjs +43 -3
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +31 -5
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +6 -2
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +27 -7
- package/src/standalone/daemon-boot-coordinator.mjs +10 -0
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-drain-policy.mjs +9 -0
- package/src/standalone/daemon-stored-session-views.mjs +7 -8
- package/src/standalone/daemon.mjs +36 -8
- package/src/standalone/local-session-runtime.mjs +11 -0
- package/src/standalone/session-client.mjs +52 -7
- package/src/standalone/session-protocol.mjs +9 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +2 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +2 -0
- package/src/standalone/session-service/entries/session-loads.mjs +9 -0
- package/src/standalone/session-service/projection/revisions.mjs +28 -4
- package/src/standalone/session-service/projection.mjs +1 -0
- package/src/standalone/session-service/quota-resume.mjs +140 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +2 -2
- package/src/standalone/session-service/session-calls.mjs +10 -2
- package/src/standalone/session-service/stored-reader.mjs +26 -1
- package/src/standalone/session-service.mjs +21 -0
- package/src/standalone/session-transport/routes.mjs +2 -0
- package/src/tui/app/doctor.mjs +7 -11
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +3 -5
- package/src/tui/app/model-picker/model-footer.mjs +2 -2
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +21 -2
- package/src/tui/app/model-picker/route-selection.mjs +6 -1
- package/src/tui/app/settings-picker/settings-rows.mjs +4 -6
- package/src/tui/app/settings-picker/settings-toggles/store-toggles.mjs +1 -1
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +5 -3
- package/src/tui/app/transcript-row-estimate.mjs +17 -5
- package/src/tui/components/ContextPanel.jsx +5 -1
- package/src/tui/components/Spinner.jsx +34 -319
- package/src/tui/components/SpinnerByline.jsx +256 -0
- package/src/tui/components/tool-execution/aggregate-card.jsx +4 -2
- package/src/tui/components/tool-execution/text-format.mjs +1 -0
- package/src/tui/components/use-spinner-progress.mjs +113 -0
- package/src/tui/dist/index.mjs +15896 -14452
- package/src/tui/session/agent-job-feed/execution-delivery.mjs +13 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +3 -0
- package/src/tui/session/agent-job-feed/pending-resume.mjs +14 -1
- package/src/tui/session/agent-job-feed.mjs +4 -0
- package/src/tui/session/context-state.mjs +13 -1
- package/src/tui/session/initial-state.mjs +6 -0
- package/src/tui/session/quota-resume.mjs +263 -0
- package/src/tui/session/session-api/intake/abort.mjs +39 -35
- package/src/tui/session/session-api/intake/submission.mjs +13 -21
- package/src/tui/session/session-api/intake.mjs +3 -3
- package/src/tui/session/session-api/integrations.mjs +5 -1
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -2
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +4 -0
- package/src/tui/session/session-api/lifecycle.mjs +71 -2
- package/src/tui/session/session-api/media.mjs +2 -2
- package/src/tui/session/session-api/quota-resume.mjs +21 -0
- package/src/tui/session/session-api/routes.mjs +5 -2
- package/src/tui/session/session-api/settings.mjs +2 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +14 -6
- package/src/tui/session/session-flow/drain.mjs +52 -5
- package/src/tui/session/session-flow/queue/take-entries.mjs +9 -4
- package/src/tui/session/session-flow/queue.mjs +4 -0
- package/src/tui/session/session-flow/steering.mjs +11 -0
- package/src/tui/session/session-flow.mjs +1 -0
- package/src/tui/session/tool-approval.mjs +7 -2
- package/src/tui/session/transcript-intake.mjs +1 -0
- package/src/tui/session/turn-tool-cards.mjs +4 -6
- package/src/tui/session/turn.mjs +40 -4
- package/src/vendor/statusline/bin/statusline-route.mjs +3 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-warmup.mjs +0 -165
|
@@ -47,6 +47,8 @@ export function createEntryLifecycle({
|
|
|
47
47
|
effort: params.effort,
|
|
48
48
|
fast: params.fast,
|
|
49
49
|
modelParameters: params.modelParameters,
|
|
50
|
+
contextPercent: params.contextPercent,
|
|
51
|
+
selectedContextWindow: params.selectedContextWindow,
|
|
50
52
|
toolMode: params.toolMode || 'full',
|
|
51
53
|
remote: params.remote === true,
|
|
52
54
|
desktopSession: params.desktopSession ?? null,
|
|
@@ -61,6 +61,15 @@ export function createSessionLoads({
|
|
|
61
61
|
await destroy(entry, 'session load mismatch');
|
|
62
62
|
throw new Error(`session ${sessionId} could not be resumed`);
|
|
63
63
|
}
|
|
64
|
+
// The loaded conversation is this entry's durable address from now on:
|
|
65
|
+
// an evicted/unloaded/crashed-restored runtime may resume it again but
|
|
66
|
+
// never mint another id under this entry.
|
|
67
|
+
try {
|
|
68
|
+
await entry.runtime.bindSessionAddress?.(loaded);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
await destroy(entry, 'session address bind failed');
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
64
73
|
// Publish/index the resumed identity before sessionLoads releases its
|
|
65
74
|
// single-flight promise. A second pane arriving in the next microtask must
|
|
66
75
|
// find this owner in O(1), not create a duplicate runtime.
|
|
@@ -34,6 +34,7 @@ export function frameBody(step, prepend = false) {
|
|
|
34
34
|
|
|
35
35
|
/** Response body for the CALLER, which announced the revision it holds. */
|
|
36
36
|
export function bodyForClient(step, baseRevision, prepend = false) {
|
|
37
|
+
if (step.unavailable) return { revision: step.revision, unavailable: true };
|
|
37
38
|
if (!step.changed && baseRevision === step.revision) return { revision: step.revision };
|
|
38
39
|
if (step.patch && baseRevision === step.previousRevision) return frameBody(step, prepend);
|
|
39
40
|
return { revision: step.revision, full: step.snapshot };
|
|
@@ -49,7 +50,7 @@ function headGrowthPatch(previous, snapshot) {
|
|
|
49
50
|
return patch?.itemsPrepend ? patch : null;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
export function createRevisionSteps({ revisionEpoch, index, updateEntryBusy }) {
|
|
53
|
+
export function createRevisionSteps({ revisionEpoch, index, updateEntryBusy, log = () => {} }) {
|
|
53
54
|
// One clock owns every snapshot served by this daemon, including stored
|
|
54
55
|
// views and replacement runtimes. Per-entry counters restarted after idle
|
|
55
56
|
// eviction, so clients retaining the old baseline discarded new turns.
|
|
@@ -97,12 +98,35 @@ export function createRevisionSteps({ revisionEpoch, index, updateEntryBusy }) {
|
|
|
97
98
|
function advance(entry) {
|
|
98
99
|
// Deltas are computed against the WINDOWED snapshot, so a tail-only
|
|
99
100
|
// baseline keeps receiving ordinary suffix patches.
|
|
100
|
-
const
|
|
101
|
-
const projectedSessionId = String(
|
|
101
|
+
const current = windowTranscriptSnapshot(entry, snapshotOf(entry));
|
|
102
|
+
const projectedSessionId = String(current?.sessionId || '');
|
|
102
103
|
const addressedSessionId = String(entry.addressedSessionId || '');
|
|
103
104
|
if (addressedSessionId && projectedSessionId && projectedSessionId !== addressedSessionId) {
|
|
104
|
-
|
|
105
|
+
// The runtime now reports another conversation. Throwing here failed
|
|
106
|
+
// every read of this entry (view sync, getSnapshot, push watcher), so
|
|
107
|
+
// keep serving what this address last published and say so once.
|
|
108
|
+
if (entry.addressMismatchLogged !== projectedSessionId) {
|
|
109
|
+
entry.addressMismatchLogged = projectedSessionId;
|
|
110
|
+
log(
|
|
111
|
+
`session ${addressedSessionId} changed its durable address to ${projectedSessionId}; serving last snapshot`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
// `current` belongs to ANOTHER conversation and is never served for this
|
|
115
|
+
// address; with no published snapshot left (retention cleared it) the
|
|
116
|
+
// step says so and callers answer without a body.
|
|
117
|
+
const stale = entry.publishedSnapshot ?? null;
|
|
118
|
+
const staleRevision = entry.revision || 0;
|
|
119
|
+
return {
|
|
120
|
+
changed: false,
|
|
121
|
+
...(stale ? {} : { unavailable: true }),
|
|
122
|
+
snapshot: stale,
|
|
123
|
+
revision: staleRevision,
|
|
124
|
+
previousRevision: staleRevision,
|
|
125
|
+
patch: null,
|
|
126
|
+
prependPatch: null,
|
|
127
|
+
};
|
|
105
128
|
}
|
|
129
|
+
const snapshot = current;
|
|
106
130
|
if (!addressedSessionId && projectedSessionId) {
|
|
107
131
|
entry.addressedSessionId = projectedSessionId;
|
|
108
132
|
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// session-service/quota-resume.mjs
|
|
2
|
+
// The daemon's clock for quota auto-resume. Waiting lives in the durable
|
|
3
|
+
// store (runtime/shared/quota-resume-store.mjs), never in a session runtime,
|
|
4
|
+
// so an evicted or not-yet-loaded session waits exactly like a live one. One
|
|
5
|
+
// timer is armed for the earliest due entry; when it fires, the addressed
|
|
6
|
+
// session is materialized under daemon ownership (the Goal-recovery pattern),
|
|
7
|
+
// a fresh usage reading decides whether its provider can serve the model
|
|
8
|
+
// again, and the session's own lane runs the retry under the entry's
|
|
9
|
+
// generation. Overdue entries run as soon as the scheduler starts.
|
|
10
|
+
|
|
11
|
+
/** A still-exhausted reading is re-taken once, this much later. */
|
|
12
|
+
export const QUOTA_RESUME_RETRY_MS = 5 * 60_000;
|
|
13
|
+
/** A busy session is re-checked this much later, without spending an attempt. */
|
|
14
|
+
export const QUOTA_RESUME_BUSY_RECHECK_MS = 30_000;
|
|
15
|
+
const MAX_TIMER_MS = 2 ** 31 - 1;
|
|
16
|
+
|
|
17
|
+
const isCurrent = (store, entry) => store.quotaResumeEntry(entry.sessionId)?.generation === entry.generation;
|
|
18
|
+
|
|
19
|
+
/** One due entry: load its session, take the fresh reading, then fire,
|
|
20
|
+
* re-check later, or clear it. Returns the outcome for the log. */
|
|
21
|
+
async function resumeDueEntry(entry, { store, materializeSession, readQuotaUsable, log, isClosed, now }) {
|
|
22
|
+
const { sessionId, generation } = entry;
|
|
23
|
+
let runtime;
|
|
24
|
+
try {
|
|
25
|
+
runtime = await materializeSession(sessionId);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (isClosed()) return 'closed';
|
|
28
|
+
log(`quota resume could not load session=${sessionId}: ${error?.message || error}`);
|
|
29
|
+
store.cancelQuotaResumeEntry(sessionId, { generation });
|
|
30
|
+
return 'unavailable';
|
|
31
|
+
}
|
|
32
|
+
if (!isCurrent(store, entry)) return 'cancelled';
|
|
33
|
+
let usable = false;
|
|
34
|
+
try {
|
|
35
|
+
usable = await readQuotaUsable(entry.provider, entry.model);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
log(`quota resume usage reading failed provider=${entry.provider}: ${error?.message || error}`);
|
|
38
|
+
}
|
|
39
|
+
if (!isCurrent(store, entry)) return 'cancelled';
|
|
40
|
+
if (!usable) {
|
|
41
|
+
// One more reading five minutes on; after that the session falls back
|
|
42
|
+
// to the user's own choice.
|
|
43
|
+
if (entry.attempts < 1) {
|
|
44
|
+
store.deferQuotaResumeEntry(sessionId, generation, {
|
|
45
|
+
resetAt: now() + QUOTA_RESUME_RETRY_MS,
|
|
46
|
+
attempts: entry.attempts + 1,
|
|
47
|
+
});
|
|
48
|
+
return 'exhausted-retry';
|
|
49
|
+
}
|
|
50
|
+
store.cancelQuotaResumeEntry(sessionId, { generation });
|
|
51
|
+
return 'exhausted';
|
|
52
|
+
}
|
|
53
|
+
const outcome =
|
|
54
|
+
typeof runtime?.fireQuotaResume === 'function' ? runtime.fireQuotaResume({ generation }) : 'unsupported';
|
|
55
|
+
if (outcome === 'busy') {
|
|
56
|
+
store.deferQuotaResumeEntry(sessionId, generation, {
|
|
57
|
+
resetAt: now() + QUOTA_RESUME_BUSY_RECHECK_MS,
|
|
58
|
+
attempts: entry.attempts,
|
|
59
|
+
});
|
|
60
|
+
} else if (isCurrent(store, entry)) {
|
|
61
|
+
// Every other outcome settles the entry; one the session could not
|
|
62
|
+
// address (it now holds another session id) must not stay due forever.
|
|
63
|
+
store.cancelQuotaResumeEntry(sessionId, { generation });
|
|
64
|
+
}
|
|
65
|
+
return outcome;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function createQuotaResumeScheduler({
|
|
69
|
+
store,
|
|
70
|
+
materializeSession,
|
|
71
|
+
readQuotaUsable,
|
|
72
|
+
log = () => {},
|
|
73
|
+
isClosed = () => false,
|
|
74
|
+
now = () => Date.now(),
|
|
75
|
+
setTimer = (task, ms) => setTimeout(task, ms),
|
|
76
|
+
clearTimer = (timer) => clearTimeout(timer),
|
|
77
|
+
}) {
|
|
78
|
+
let started = false;
|
|
79
|
+
let timer = null;
|
|
80
|
+
let running = null;
|
|
81
|
+
let unsubscribe = null;
|
|
82
|
+
const deps = { store, materializeSession, readQuotaUsable, log, isClosed, now };
|
|
83
|
+
|
|
84
|
+
function arm() {
|
|
85
|
+
if (timer) clearTimer(timer);
|
|
86
|
+
timer = null;
|
|
87
|
+
if (!started || isClosed() || running) return;
|
|
88
|
+
const entries = store.listQuotaResumeEntries();
|
|
89
|
+
if (entries.length === 0) return;
|
|
90
|
+
const due = Math.min(...entries.map((entry) => entry.resetAt));
|
|
91
|
+
timer = setTimer(
|
|
92
|
+
() => {
|
|
93
|
+
timer = null;
|
|
94
|
+
void tick();
|
|
95
|
+
},
|
|
96
|
+
Math.min(MAX_TIMER_MS, Math.max(0, due - now()))
|
|
97
|
+
);
|
|
98
|
+
timer?.unref?.();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function tick() {
|
|
102
|
+
if (running) return running;
|
|
103
|
+
running = (async () => {
|
|
104
|
+
for (const entry of store.listQuotaResumeEntries()) {
|
|
105
|
+
if (isClosed()) return;
|
|
106
|
+
if (entry.resetAt > now() || !isCurrent(store, entry)) continue;
|
|
107
|
+
try {
|
|
108
|
+
const outcome = await resumeDueEntry(entry, deps);
|
|
109
|
+
log(`quota resume session=${entry.sessionId} outcome=${outcome}`);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
log(`quota resume failed session=${entry.sessionId}: ${error?.message || error}`);
|
|
112
|
+
store.cancelQuotaResumeEntry(entry.sessionId, { generation: entry.generation });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
})().finally(() => {
|
|
116
|
+
running = null;
|
|
117
|
+
arm();
|
|
118
|
+
});
|
|
119
|
+
return running;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
/** Start the clock; entries already due run right away. */
|
|
124
|
+
start() {
|
|
125
|
+
if (started || isClosed()) return;
|
|
126
|
+
started = true;
|
|
127
|
+
unsubscribe = store.subscribeQuotaResume(() => arm());
|
|
128
|
+
arm();
|
|
129
|
+
},
|
|
130
|
+
/** Run every due entry now (the timer's own callback). */
|
|
131
|
+
tick,
|
|
132
|
+
stop() {
|
|
133
|
+
started = false;
|
|
134
|
+
unsubscribe?.();
|
|
135
|
+
unsubscribe = null;
|
|
136
|
+
if (timer) clearTimer(timer);
|
|
137
|
+
timer = null;
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -22,7 +22,7 @@ function requireSessionAction(action, allowed) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function createSessionActionCalls(ctx) {
|
|
25
|
-
const { isClosed, log, listSessions, getRemoteSessionState, loadProjectStore, advanceForCaller, readStoredReview } =
|
|
25
|
+
const { isClosed, log, listSessions, getRemoteSessionState, loadProjectStore, advanceForCaller, readStoredReview, responseSessionId } =
|
|
26
26
|
ctx;
|
|
27
27
|
const { bodyForClient } = ctx.projection;
|
|
28
28
|
const { retainUnwatched } = ctx.retention;
|
|
@@ -83,7 +83,7 @@ export function createSessionActionCalls(ctx) {
|
|
|
83
83
|
retainUnwatched(entry);
|
|
84
84
|
return {
|
|
85
85
|
value: sanitizeForWire(value) ?? null,
|
|
86
|
-
sessionId:
|
|
86
|
+
sessionId: responseSessionId(entry, id),
|
|
87
87
|
...bodyForClient(step, Number.isInteger(baseRevision) ? baseRevision : null),
|
|
88
88
|
};
|
|
89
89
|
}
|
|
@@ -23,10 +23,18 @@ import { createSessionViewCalls } from './session-calls/session-views.mjs';
|
|
|
23
23
|
export function createSessionCalls(deps) {
|
|
24
24
|
const { advance, currentSessionId, publishStep, bodyForClient } = deps.projection;
|
|
25
25
|
|
|
26
|
+
/** The id a response reports: the entry's immutable addressed id (what the
|
|
27
|
+
* served snapshot describes), never a runtime id that drifted away from it.
|
|
28
|
+
* Before the first advance there is no address yet, so the runtime id (a
|
|
29
|
+
* fresh create/resume) is the identity. */
|
|
30
|
+
function responseSessionId(entry, fallback = '') {
|
|
31
|
+
return String(entry.addressedSessionId || currentSessionId(entry) || fallback);
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
/** `prepend`: the caller announced transcriptPrepend (see frameBody). */
|
|
27
35
|
function sessionResult(entry, step, baseRevision = null, extra = {}, { prepend = false } = {}) {
|
|
28
36
|
return {
|
|
29
|
-
sessionId:
|
|
37
|
+
sessionId: responseSessionId(entry),
|
|
30
38
|
reservedOnly: entry.reservedOnly === true,
|
|
31
39
|
...extra,
|
|
32
40
|
...bodyForClient(step, Number.isInteger(baseRevision) ? baseRevision : null, prepend),
|
|
@@ -46,7 +54,7 @@ export function createSessionCalls(deps) {
|
|
|
46
54
|
return step;
|
|
47
55
|
}
|
|
48
56
|
|
|
49
|
-
const ctx = { ...deps, sessionResult, advanceForCaller };
|
|
57
|
+
const ctx = { ...deps, sessionResult, responseSessionId, advanceForCaller };
|
|
50
58
|
const actions = createSessionActionCalls(ctx);
|
|
51
59
|
const views = createSessionViewCalls({ ...ctx, runSessionAction: actions.runSessionAction });
|
|
52
60
|
const turns = createSessionTurnCalls(ctx);
|
|
@@ -10,9 +10,27 @@ export function createStoredSessionReader({
|
|
|
10
10
|
statStoredSession = null,
|
|
11
11
|
forgetStoredSession = null,
|
|
12
12
|
releaseStoredSession = null,
|
|
13
|
+
readQuotaResume = null,
|
|
13
14
|
sessionOwner,
|
|
14
15
|
log,
|
|
15
16
|
}) {
|
|
17
|
+
/** The cold session's queued quota resume (snapshot shape) or null. */
|
|
18
|
+
const quotaResumeOf = (sessionId) => {
|
|
19
|
+
if (typeof readQuotaResume !== 'function') return null;
|
|
20
|
+
try {
|
|
21
|
+
return readQuotaResume(sessionId) ?? null;
|
|
22
|
+
} catch (err) {
|
|
23
|
+
log(`stored quota resume projection failed session=${sessionId}: ${err?.message || err}`);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
// The resume is projected beside the transcript, so its identity is part
|
|
28
|
+
// of the stamp a cold view is served by: a scheduled, deferred or cleared
|
|
29
|
+
// resume refreshes the view even while the transcript files are unchanged.
|
|
30
|
+
const quotaResumeStamp = (sessionId) => {
|
|
31
|
+
const resume = quotaResumeOf(sessionId);
|
|
32
|
+
return resume ? `${resume.turnKey}:${resume.resetAt}:${resume.attempts}` : '';
|
|
33
|
+
};
|
|
16
34
|
// `${sessionId}|${window}` -> { projectionStamp, fileStamp }: the settled
|
|
17
35
|
// file identity each served projection was built from. The 1s cold-view
|
|
18
36
|
// refresh asks again with the stamp it holds; while the files still carry
|
|
@@ -78,11 +96,15 @@ export function createStoredSessionReader({
|
|
|
78
96
|
|
|
79
97
|
async function fileStampOf(sessionId) {
|
|
80
98
|
if (typeof statStoredSession !== 'function') return null;
|
|
99
|
+
let stamp;
|
|
81
100
|
try {
|
|
82
|
-
|
|
101
|
+
stamp = (await statStoredSession(sessionId)) || null;
|
|
83
102
|
} catch {
|
|
84
103
|
return null;
|
|
85
104
|
}
|
|
105
|
+
if (stamp === null) return null;
|
|
106
|
+
const resume = quotaResumeStamp(sessionId);
|
|
107
|
+
return resume ? `${stamp}|quota-resume:${resume}` : stamp;
|
|
86
108
|
}
|
|
87
109
|
|
|
88
110
|
/** Whether the projection a caller holds (`projectionStamp`, read through
|
|
@@ -145,6 +167,9 @@ export function createStoredSessionReader({
|
|
|
145
167
|
...wire,
|
|
146
168
|
sessionId,
|
|
147
169
|
...(typeof readStoredGoal === 'function' ? { goal: sanitizeForWire(goal, 1) ?? null } : {}),
|
|
170
|
+
...(typeof readQuotaResume === 'function'
|
|
171
|
+
? { quotaResume: sanitizeForWire(quotaResumeOf(sessionId)) ?? null }
|
|
172
|
+
: {}),
|
|
148
173
|
queued: Array.isArray(snapshot.queued) ? wire.queued : [],
|
|
149
174
|
};
|
|
150
175
|
}
|
|
@@ -22,6 +22,7 @@ import { createSessionRetention } from './session-service/retention.mjs';
|
|
|
22
22
|
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
|
+
import { createQuotaResumeScheduler } from './session-service/quota-resume.mjs';
|
|
25
26
|
|
|
26
27
|
const EXTERNAL_SESSION_ACTIONS = new Set([
|
|
27
28
|
...SESSION_READ_ACTION_SET,
|
|
@@ -56,6 +57,10 @@ export function createSessionService({
|
|
|
56
57
|
onDesktopReady = () => {},
|
|
57
58
|
idleEvictMs = null,
|
|
58
59
|
evictSweepMs = null,
|
|
60
|
+
// Quota auto-resume: the durable queue module and the fresh usage reading
|
|
61
|
+
// (provider, model) => Promise<boolean>. Without a store nothing is scheduled.
|
|
62
|
+
quotaResumeStore = null,
|
|
63
|
+
readQuotaUsable = null,
|
|
59
64
|
} = {}) {
|
|
60
65
|
const createRuntime = createSessionRuntime;
|
|
61
66
|
if (typeof createRuntime !== 'function') throw new Error('createSessionRuntime is required');
|
|
@@ -165,6 +170,9 @@ export function createSessionService({
|
|
|
165
170
|
statStoredSession,
|
|
166
171
|
forgetStoredSession,
|
|
167
172
|
releaseStoredSession,
|
|
173
|
+
readQuotaResume: quotaResumeStore
|
|
174
|
+
? (sessionId) => quotaResumeStore.publicQuotaResume(quotaResumeStore.quotaResumeEntry(sessionId))
|
|
175
|
+
: null,
|
|
168
176
|
sessionOwner: projection.sessionOwner,
|
|
169
177
|
log,
|
|
170
178
|
});
|
|
@@ -197,10 +205,21 @@ export function createSessionService({
|
|
|
197
205
|
retainUnwatched: retention.retainUnwatched,
|
|
198
206
|
createSession: calls.createSession,
|
|
199
207
|
});
|
|
208
|
+
const quotaUsableReader = typeof readQuotaUsable === 'function' ? readQuotaUsable : async () => false;
|
|
209
|
+
const quotaResume = quotaResumeStore
|
|
210
|
+
? createQuotaResumeScheduler({
|
|
211
|
+
store: quotaResumeStore,
|
|
212
|
+
materializeSession: calls.materializeSession,
|
|
213
|
+
readQuotaUsable: quotaUsableReader,
|
|
214
|
+
log,
|
|
215
|
+
isClosed,
|
|
216
|
+
})
|
|
217
|
+
: null;
|
|
200
218
|
|
|
201
219
|
function stop(reason = 'service stop') {
|
|
202
220
|
if (stopPromise) return stopPromise;
|
|
203
221
|
closed = true;
|
|
222
|
+
quotaResume?.stop();
|
|
204
223
|
stopPromise = Promise.resolve().then(async () => {
|
|
205
224
|
try {
|
|
206
225
|
unsubscribeExternalSessionStates();
|
|
@@ -264,6 +283,8 @@ export function createSessionService({
|
|
|
264
283
|
methods: {
|
|
265
284
|
...calls,
|
|
266
285
|
stop,
|
|
286
|
+
startQuotaResume: () => quotaResume?.start(),
|
|
287
|
+
runDueQuotaResumes: () => quotaResume?.tick() ?? Promise.resolve(),
|
|
267
288
|
releaseClient: viewers.releaseClient,
|
|
268
289
|
agentSurface: agentTree.agentSurface,
|
|
269
290
|
agentManager: agentTree.agentManager,
|
|
@@ -114,6 +114,7 @@ export function createTransportRoutes({
|
|
|
114
114
|
const requestedProtocol = Number(body.protocol);
|
|
115
115
|
const requestedRevision = Math.max(0, Number(body.revision) || 0);
|
|
116
116
|
const requestedVersion = String(body.version || '0.0.0');
|
|
117
|
+
const force = body.force === true;
|
|
117
118
|
const revisionOrder = requestedRevision - SESSION_REVISION;
|
|
118
119
|
const versionOrder = compareRuntimeVersions(requestedVersion, runtimeVersion());
|
|
119
120
|
const newerBuild =
|
|
@@ -140,6 +141,7 @@ export function createTransportRoutes({
|
|
|
140
141
|
protocol: SESSION_PROTOCOL,
|
|
141
142
|
revision: requestedRevision,
|
|
142
143
|
version: requestedVersion,
|
|
144
|
+
force,
|
|
143
145
|
});
|
|
144
146
|
} catch {}
|
|
145
147
|
});
|
package/src/tui/app/doctor.mjs
CHANGED
|
@@ -115,6 +115,7 @@ function reportNode({ version, engines }, row) {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
function providerUnusableReason(entry) {
|
|
118
|
+
if (entry.configError) return `has an invalid configuration (${entry.configError})`;
|
|
118
119
|
if (entry.reauthRequired) return 'requires sign-in again';
|
|
119
120
|
if (entry.enabled === false) return 'is disabled';
|
|
120
121
|
if (entry.type === 'local' && !entry.detected) return 'has no installed runtime/model';
|
|
@@ -240,9 +241,7 @@ function reportRegistry(label) {
|
|
|
240
241
|
const broken = active.filter(
|
|
241
242
|
(entry) => entry.broken || entry.error || entry.invalid || entry.dependencyIssues?.length
|
|
242
243
|
);
|
|
243
|
-
const missing = Array.isArray(status.missing)
|
|
244
|
-
? status.missing.filter((entry) => entry.enabled !== false)
|
|
245
|
-
: [];
|
|
244
|
+
const missing = Array.isArray(status.missing) ? status.missing.filter((entry) => entry.enabled !== false) : [];
|
|
246
245
|
let detail = `${active.length}/${entries.length} active${scopeDetail}`;
|
|
247
246
|
const issues = [...broken, ...(label === 'plugins' ? missing : [])];
|
|
248
247
|
if (!issues.length) {
|
|
@@ -340,7 +339,8 @@ async function readDataFolder(dataDir) {
|
|
|
340
339
|
|
|
341
340
|
function reportDataFolder({ dataDir, writable, missing }, row) {
|
|
342
341
|
if (writable) row('ok', `writable · ${dataDir}`);
|
|
343
|
-
else if (missing)
|
|
342
|
+
else if (missing)
|
|
343
|
+
row('fail', `not found · ${dataDir}`, { hint: 'create the folder or point MIXDOG_DATA_DIR at an existing one' });
|
|
344
344
|
else row('fail', `not writable · ${dataDir}`, { hint: 'check the folder permissions' });
|
|
345
345
|
}
|
|
346
346
|
|
|
@@ -398,15 +398,11 @@ export async function runDoctorChecks(runtime = {}, getState = () => ({}), optio
|
|
|
398
398
|
[
|
|
399
399
|
'voice',
|
|
400
400
|
'voice',
|
|
401
|
-
async () =>
|
|
401
|
+
async () =>
|
|
402
|
+
(runtime.getVoiceStatus || (await import('../../runtime/channels/lib/voice-setup.mjs')).getVoiceStatus)(),
|
|
402
403
|
reportVoice,
|
|
403
404
|
],
|
|
404
|
-
[
|
|
405
|
-
'automation',
|
|
406
|
-
'automation',
|
|
407
|
-
() => runtime.getChannelSettings?.({ includeStatus: true }),
|
|
408
|
-
reportChannels(runtime),
|
|
409
|
-
],
|
|
405
|
+
['automation', 'automation', () => runtime.getChannelSettings?.({ includeStatus: true }), reportChannels(runtime)],
|
|
410
406
|
['skills', 'skills', () => runtime.skillsStatus?.(), reportRegistry('skills')],
|
|
411
407
|
['plugins', 'plugins', () => runtime.pluginsStatus?.(), reportRegistry('plugins')],
|
|
412
408
|
['hooks', 'hooks', () => runtime.hooksStatus?.(), reportHooks],
|
|
@@ -110,11 +110,9 @@ export function createAutoClearPicker({
|
|
|
110
110
|
const enabled = current?.enabled !== false;
|
|
111
111
|
const idleMs = Number(current?.idleMs || HOUR_MS);
|
|
112
112
|
const cacheTtlLabel = !enabled || idleMs >= HOUR_MS ? '1h' : '5m';
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
? 'global'
|
|
117
|
-
: `${current?.provider || 'default'} default`;
|
|
113
|
+
let sourceLabel = `${current?.provider || 'default'} default`;
|
|
114
|
+
if (current?.providerCustom) sourceLabel = `${current.provider} override`;
|
|
115
|
+
else if (current?.custom) sourceLabel = 'global';
|
|
118
116
|
const items = [
|
|
119
117
|
{
|
|
120
118
|
value: 'toggle',
|
|
@@ -53,11 +53,11 @@ export function modelFooter(selection, model = null) {
|
|
|
53
53
|
fastLine = {
|
|
54
54
|
glyph: fastOn ? '●' : '○',
|
|
55
55
|
color: fastOn ? theme.fastMode : theme.inactive,
|
|
56
|
-
text: `${fastDisplayLabel(fastOn)} · Tab Toggle`,
|
|
56
|
+
text: `${selection.isUltrafast?.(model) ? 'Ultrafast' : fastDisplayLabel(fastOn)} · Tab Toggle`,
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
const parameterLines = (model?.modelParameterOptions || [])
|
|
60
|
-
.filter((parameter) => parameter.id !== 'context')
|
|
60
|
+
.filter((parameter) => parameter.id !== 'context' && parameter.id !== 'serviceTier')
|
|
61
61
|
.map((parameter) => {
|
|
62
62
|
const value = selection.modelParametersFor(model)[parameter.id] || '';
|
|
63
63
|
return {
|
|
@@ -57,9 +57,28 @@ export function createFastParameterSelection({ state, currentRoute, isCurrentRou
|
|
|
57
57
|
return fast;
|
|
58
58
|
};
|
|
59
59
|
/** Flips Fast; false when the model cannot run Fast at the selected effort. */
|
|
60
|
+
const ultrafastOffered = (model) =>
|
|
61
|
+
(model?.modelParameterOptions || []).some(
|
|
62
|
+
(parameter) => parameter.id === 'serviceTier' && parameter.options?.some((o) => o.value === 'ultrafast')
|
|
63
|
+
);
|
|
64
|
+
const isUltrafast = (model) =>
|
|
65
|
+
ultrafastOffered(model) && getSelectedFast(model) && modelParametersFor(model).serviceTier === 'ultrafast';
|
|
66
|
+
const setSpeed = (model, fast, tier) => {
|
|
67
|
+
selectedFast.set(modelKey(model), fast);
|
|
68
|
+
selectedModelParameters.set(modelKey(model), { ...modelParametersFor(model), serviceTier: tier });
|
|
69
|
+
};
|
|
70
|
+
/** Cycles Standard → Fast → Ultrafast → Standard when the model offers
|
|
71
|
+
* Ultrafast, else flips Fast; false when the model cannot run Fast at the
|
|
72
|
+
* selected effort. */
|
|
60
73
|
const toggleFast = (model) => {
|
|
61
74
|
if (!fastAvailableFor(model)) return false;
|
|
62
|
-
|
|
75
|
+
if (!ultrafastOffered(model)) {
|
|
76
|
+
selectedFast.set(modelKey(model), !getSelectedFast(model));
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (!getSelectedFast(model)) setSpeed(model, true, 'priority');
|
|
80
|
+
else if (!isUltrafast(model)) setSpeed(model, true, 'ultrafast');
|
|
81
|
+
else setSpeed(model, false, 'priority');
|
|
63
82
|
return true;
|
|
64
83
|
};
|
|
65
84
|
|
|
@@ -80,5 +99,5 @@ export function createFastParameterSelection({ state, currentRoute, isCurrentRou
|
|
|
80
99
|
return true;
|
|
81
100
|
};
|
|
82
101
|
|
|
83
|
-
return { modelParametersFor, fastAvailableFor, getSelectedFast, toggleFast, cycleThinking };
|
|
102
|
+
return { modelParametersFor, fastAvailableFor, getSelectedFast, isUltrafast, toggleFast, cycleThinking };
|
|
84
103
|
}
|
|
@@ -26,6 +26,10 @@ export function createRouteSelection({ providerModels, state, currentRoute }) {
|
|
|
26
26
|
const coercedEffort = effort.coerceEffort(selected);
|
|
27
27
|
const fastCapable = fast.fastAvailableFor(selected, coercedEffort);
|
|
28
28
|
const contextSelection = context.contextSelectionFor(selected);
|
|
29
|
+
const { serviceTier, ...otherParameters } = fast.modelParametersFor(selected);
|
|
30
|
+
const modelParameters = serviceTier && fastCapable && fast.getSelectedFast(selected)
|
|
31
|
+
? { ...otherParameters, serviceTier }
|
|
32
|
+
: otherParameters;
|
|
29
33
|
return {
|
|
30
34
|
effort: coercedEffort,
|
|
31
35
|
routeInput: {
|
|
@@ -35,7 +39,7 @@ export function createRouteSelection({ providerModels, state, currentRoute }) {
|
|
|
35
39
|
...(contextSelection ? { contextPercent: contextSelection.percent } : {}),
|
|
36
40
|
...(selected.fastCapable ? { fast: fastCapable && fast.getSelectedFast(selected) } : {}),
|
|
37
41
|
...((selected.modelParameterOptions || []).length
|
|
38
|
-
? { modelParameters
|
|
42
|
+
? { modelParameters }
|
|
39
43
|
: {}),
|
|
40
44
|
},
|
|
41
45
|
};
|
|
@@ -51,6 +55,7 @@ export function createRouteSelection({ providerModels, state, currentRoute }) {
|
|
|
51
55
|
stepContext: context.stepContext,
|
|
52
56
|
fastAvailableFor: fast.fastAvailableFor,
|
|
53
57
|
getSelectedFast: fast.getSelectedFast,
|
|
58
|
+
isUltrafast: fast.isUltrafast,
|
|
54
59
|
toggleFast: fast.toggleFast,
|
|
55
60
|
cycleEffort: effort.cycleEffort,
|
|
56
61
|
cycleThinking: fast.cycleThinking,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// concern — routing/model first, then session behavior, integrations, voice,
|
|
4
4
|
// system — and must stay in sync with desktop SETTINGS_ITEMS (tui-parity
|
|
5
5
|
// test, minus system-shell).
|
|
6
|
-
import { isVoiceEnabled } from '
|
|
6
|
+
import { isVoiceEnabled } from '../../../runtime/channels/lib/voice-setup.mjs';
|
|
7
7
|
|
|
8
8
|
const boolLabel = (enabled) => (enabled ? 'On' : 'Off');
|
|
9
9
|
|
|
@@ -66,11 +66,9 @@ export function buildSettingsItems({
|
|
|
66
66
|
const { workflow, mcp, plugins, skills } = view;
|
|
67
67
|
const outputStyleLabel =
|
|
68
68
|
outputStyle?.current?.label || outputStyle?.current?.id || outputStyle?.configured || 'Default';
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
? ' (global)'
|
|
73
|
-
: ` (${autoClear.provider || 'default'} default)`;
|
|
69
|
+
let autoClearSource = ` (${autoClear.provider || 'default'} default)`;
|
|
70
|
+
if (autoClear.providerCustom) autoClearSource = ` (${autoClear.provider} override)`;
|
|
71
|
+
else if (autoClear.custom) autoClearSource = ' (global)';
|
|
74
72
|
return [
|
|
75
73
|
{
|
|
76
74
|
value: 'model',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// The boolean rows of Settings: each write goes through the store, reports the
|
|
3
3
|
// outcome as a notice, and refreshes Settings through the deferred refresh
|
|
4
4
|
// bound to the keypress that started it.
|
|
5
|
-
import { toggleVoice, isVoiceInstallBusy } from '
|
|
5
|
+
import { toggleVoice, isVoiceInstallBusy } from '../../../../runtime/channels/lib/voice-setup.mjs';
|
|
6
6
|
|
|
7
7
|
export function createStoreToggles({ store, view, formatDuration, deferredSettingsRefresh }) {
|
|
8
8
|
const applyAutoClear = (patch = {}) => {
|
|
@@ -50,7 +50,7 @@ export const SLASH_COMMANDS = [
|
|
|
50
50
|
{ name: 'theme', usage: '/theme', params: '[id]', description: 'Change the TUI color theme' },
|
|
51
51
|
{ name: 'agents', usage: '/agents', params: '[refresh]', description: 'Show available workflow agents' },
|
|
52
52
|
{ name: 'effort', usage: '/effort', params: '[level]', description: 'Set reasoning effort for the current model' },
|
|
53
|
-
{ name: 'fast', usage: '/fast', params: '[on|off]', description: '
|
|
53
|
+
{ name: 'fast', usage: '/fast', params: '[on|off|ultra]', description: 'Set Fast or Ultrafast mode for the current model' },
|
|
54
54
|
{ name: 'mcp', usage: '/mcp', description: 'Manage MCP servers and tools' },
|
|
55
55
|
{ name: 'skills', usage: '/skills', description: 'Choose a skill for the next request' },
|
|
56
56
|
{ name: 'memory', usage: '/memory', params: '[status|core ...]', description: 'List and edit core memories' },
|
|
@@ -166,10 +166,11 @@ export const routeCommands = {
|
|
|
166
166
|
.toLowerCase();
|
|
167
167
|
let setTo = null;
|
|
168
168
|
if (!value) setTo = undefined;
|
|
169
|
+
else if (['ultra', 'ultrafast'].includes(value)) setTo = 'ultrafast';
|
|
169
170
|
else if (['1', 'true', 'yes', 'on', 'enable', 'enabled'].includes(value)) setTo = true;
|
|
170
171
|
else if (['0', 'false', 'no', 'off', 'disable', 'disabled'].includes(value)) setTo = false;
|
|
171
172
|
if (setTo === null) {
|
|
172
|
-
store.pushNotice('usage: /fast [on|off]', 'warn');
|
|
173
|
+
store.pushNotice('usage: /fast [on|off|ultra]', 'warn');
|
|
173
174
|
return true;
|
|
174
175
|
}
|
|
175
176
|
const action = setTo === undefined ? store.toggleFast?.() : store.setFast?.(setTo);
|
|
@@ -179,9 +180,10 @@ export const routeCommands = {
|
|
|
179
180
|
store.pushNotice('Fast mode switch is already running.', 'warn');
|
|
180
181
|
return;
|
|
181
182
|
}
|
|
183
|
+
const fastModeLabel = enabled ? 'Fast mode on' : 'Fast mode off';
|
|
184
|
+
const modeLabel = setTo === 'ultrafast' ? 'Ultrafast' : fastModeLabel;
|
|
182
185
|
store.pushNotice(
|
|
183
|
-
|
|
184
|
-
(state.busy ? ' (applies from the next turn)' : ''),
|
|
186
|
+
`${modeLabel} for ${state.provider}/${state.model}` + (state.busy ? ' (applies from the next turn)' : ''),
|
|
185
187
|
'info'
|
|
186
188
|
);
|
|
187
189
|
})
|