mixdog 1.3.5 → 1.4.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 +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +4 -2
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +10 -1
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +17 -1
- package/src/defaults/skills/browser-use/SKILL.md +59 -11
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +33 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +10 -8
- package/src/rules/agent/AGENT.md +6 -6
- package/src/rules/lead/LEAD.md +18 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +181 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +145 -66
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -13
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +26 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +133 -22
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +18 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -14
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +34 -1
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-result-summary.mjs +1 -14
- package/src/runtime/shared/worktrees/test-support.mjs +9 -4
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +27 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +448 -185
- package/src/session-runtime/agent-task-sessions.mjs +329 -180
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +16 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +124 -188
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/dist/index.mjs +58 -64
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -40,7 +40,7 @@ export function createSessionActionCalls(ctx) {
|
|
|
40
40
|
responseSessionId,
|
|
41
41
|
} = ctx;
|
|
42
42
|
const { bodyForClient } = ctx.projection;
|
|
43
|
-
const { retainUnwatched } = ctx.retention;
|
|
43
|
+
const { retainUnwatched, awaitingApprovalSessionKinds, roomHandoffQuestions } = ctx.retention;
|
|
44
44
|
const { assertAvailable, hostedEntryForSession, entryForSession } = ctx.entries;
|
|
45
45
|
|
|
46
46
|
/** A cold session's review, read from its durable turn record (the same
|
|
@@ -111,6 +111,27 @@ export function createSessionActionCalls(ctx) {
|
|
|
111
111
|
return result;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/** Rows with `awaitingApproval` on every session whose live runtime shows an
|
|
115
|
+
* approval card: a list row reads "needs you" from it whether or not any
|
|
116
|
+
* pane receives that session's lane. A room member's row also carries the
|
|
117
|
+
* handed-off questions it holds (`handoffQuestions`), which its room shows. */
|
|
118
|
+
function withApprovalWaits(rows) {
|
|
119
|
+
if (!Array.isArray(rows)) return rows;
|
|
120
|
+
const waiting = awaitingApprovalSessionKinds();
|
|
121
|
+
const questions = roomHandoffQuestions();
|
|
122
|
+
if (!waiting.size && !questions.size) return rows;
|
|
123
|
+
return rows.map((row) => {
|
|
124
|
+
const kind = waiting.get(row?.id);
|
|
125
|
+
const asked = questions.get(row?.id);
|
|
126
|
+
if (!kind && !asked) return row;
|
|
127
|
+
return {
|
|
128
|
+
...row,
|
|
129
|
+
...(kind ? { awaitingApproval: true, ...(kind === 'question' ? { awaitingQuestion: true } : {}) } : {}),
|
|
130
|
+
...(asked ? { handoffQuestions: asked } : {}),
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
114
135
|
async function listSessionCatalog(options = {}) {
|
|
115
136
|
if (isClosed()) throw new Error('session service is closed');
|
|
116
137
|
if (typeof listSessions !== 'function') {
|
|
@@ -124,7 +145,7 @@ export function createSessionActionCalls(ctx) {
|
|
|
124
145
|
});
|
|
125
146
|
// A `page: { limit, cursor }` request answers one page: { sessions, nextCursor }.
|
|
126
147
|
const page = listed && !Array.isArray(listed) && Array.isArray(listed.sessions) ? listed : null;
|
|
127
|
-
const sessions = page ? page.sessions : listed;
|
|
148
|
+
const sessions = withApprovalWaits(page ? page.sessions : listed);
|
|
128
149
|
const remoteSession = typeof getRemoteSessionState === 'function' ? await getRemoteSessionState() : null;
|
|
129
150
|
const nextCursor = typeof page?.nextCursor === 'string' ? page.nextCursor : null;
|
|
130
151
|
return {
|
|
@@ -131,6 +131,14 @@ export function createSessionViewCalls(ctx) {
|
|
|
131
131
|
notePrependViewer(viewer, params);
|
|
132
132
|
const id = String(sessionId || '');
|
|
133
133
|
if (!id) throw new TypeError('sessionId is required');
|
|
134
|
+
if (params.attachmentHistory === true) {
|
|
135
|
+
// Apart from every window: nothing here reads, fills or replaces a
|
|
136
|
+
// transcript projection.
|
|
137
|
+
const stored =
|
|
138
|
+
typeof readStoredSession === 'function' ? await readStoredSession(id, { attachmentHistory: true }) : null;
|
|
139
|
+
assertAvailable();
|
|
140
|
+
return { history: stored ? { items: stored.items } : null };
|
|
141
|
+
}
|
|
134
142
|
const live = await liveEntryFor(id);
|
|
135
143
|
assertAvailable(live);
|
|
136
144
|
if (params.transcriptRange) {
|
|
@@ -7,6 +7,8 @@ import { summarizeToolResult } from '../runtime/shared/tool-result-summary.mjs';
|
|
|
7
7
|
import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../runtime/shared/tool-output-budget.mjs';
|
|
8
8
|
|
|
9
9
|
export const SESSION_TOOL_OUTPUT_BYTES = TOOL_OUTPUT_TAIL_BYTES;
|
|
10
|
+
// A session title as the session tool quotes it, listed or read.
|
|
11
|
+
export const SESSION_TITLE_LIMIT = 160;
|
|
10
12
|
const MESSAGE_TEXT_LIMIT = 2000;
|
|
11
13
|
const LIST_PREVIEW_LIMIT = 100;
|
|
12
14
|
const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
@@ -15,24 +17,30 @@ const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
|
15
17
|
* `rich` adds the owning bot, last activity, latest line and working state
|
|
16
18
|
* (never for a background caller: bot-status.mjs scopedBot). `rich` may be a
|
|
17
19
|
* per-row predicate: a bot gets them only for its own sessions. */
|
|
18
|
-
export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
20
|
+
export function sessionListOutput(page, limit, { rich = true, cursorOf = encodeCatalogCursor } = {}) {
|
|
19
21
|
const raw = page.sessions;
|
|
20
22
|
const sessions = raw.slice(0, limit).map((row) => {
|
|
21
23
|
// Decided first: a session that is not the caller's carries its real
|
|
22
24
|
// title only, never a preview standing in for it.
|
|
23
25
|
const own = typeof rich === 'function' ? rich(row) : rich;
|
|
24
26
|
const title = own ? row.title || row.preview : row.title;
|
|
27
|
+
// Live work, for every caller: its own turn or pool row (`working`)
|
|
28
|
+
// reads `running` whatever the settled catalog status; an Agent session
|
|
29
|
+
// working for it (`agentWorking`) marks it working too.
|
|
30
|
+
const status = row.working === true ? 'running' : row.status;
|
|
31
|
+
const working = row.working === true || row.agentWorking === true ? { working: true } : {};
|
|
25
32
|
const base = {
|
|
26
33
|
id: row.id,
|
|
27
|
-
...(title ? { title: escapeHarnessTags(truncateToolText(title,
|
|
28
|
-
...(
|
|
34
|
+
...(title ? { title: escapeHarnessTags(truncateToolText(title, SESSION_TITLE_LIMIT)) } : {}),
|
|
35
|
+
...(status ? { status } : {}),
|
|
29
36
|
...(row.cwd ? { cwd: row.cwd } : {}),
|
|
30
37
|
...(row.archived === true ? { archived: true } : {}),
|
|
31
38
|
};
|
|
32
|
-
if (!own) return base;
|
|
39
|
+
if (!own) return { ...base, ...working };
|
|
33
40
|
// The bot it belongs to: its chat, room seat or the task's creator.
|
|
34
41
|
const bot = sessionBotOf(row);
|
|
35
|
-
|
|
42
|
+
// A live row's latest sign of work (`liveAt`) is newer than its last settled turn.
|
|
43
|
+
const lastUsedAt = Math.max(Number(row.lastUsedAt) || 0, Number(row.liveAt) || 0);
|
|
36
44
|
const preview = String(row.lastMessagePreview || '').replace(/\s+/g, ' ');
|
|
37
45
|
return {
|
|
38
46
|
...base,
|
|
@@ -40,7 +48,7 @@ export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
|
40
48
|
...(lastUsedAt ? { lastUsedAt: new Date(lastUsedAt).toISOString() } : {}),
|
|
41
49
|
// The latest user or assistant line, quoted data.
|
|
42
50
|
...(preview.trim() ? { preview: escapeHarnessTags(truncateToolText(preview, LIST_PREVIEW_LIMIT)) } : {}),
|
|
43
|
-
...
|
|
51
|
+
...working,
|
|
44
52
|
};
|
|
45
53
|
});
|
|
46
54
|
const result = {
|
|
@@ -50,7 +58,7 @@ export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
|
50
58
|
};
|
|
51
59
|
for (;;) {
|
|
52
60
|
if (sessions.length < raw.length && sessions.length) {
|
|
53
|
-
result.nextCursor =
|
|
61
|
+
result.nextCursor = cursorOf(raw[sessions.length - 1]);
|
|
54
62
|
}
|
|
55
63
|
if (outputBytes(result) <= TOOL_OUTPUT_PAGE_BYTES) return result;
|
|
56
64
|
if (sessions.length <= 1) throw new Error('session: one catalog row exceeds the output budget');
|
|
@@ -9,6 +9,7 @@ import { theme } from '../theme.mjs';
|
|
|
9
9
|
import { displayModelName, effortDisplayLabel } from '../../runtime/shared/model-display.mjs';
|
|
10
10
|
import { isRollingModelAlias } from '../../runtime/shared/model-alias.mjs';
|
|
11
11
|
import { describeError } from '../../runtime/shared/error-presentation.mjs';
|
|
12
|
+
import { providerDisplayName } from '../../runtime/shared/provider-display-name.mjs';
|
|
12
13
|
import { DAYBREAK_PROVIDER, daybreakBlueOn } from '../../runtime/shared/llm/openai-daybreak.mjs';
|
|
13
14
|
|
|
14
15
|
export const parsedModelVersion = (id) => {
|
|
@@ -165,34 +166,8 @@ export const normalizeModelOptions = (models) => {
|
|
|
165
166
|
return normalized;
|
|
166
167
|
};
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
['anthropic-oauth', 'Anthropic OAuth'],
|
|
171
|
-
['grok-oauth', 'Grok OAuth'],
|
|
172
|
-
['muse-code-oauth', 'Muse Code'],
|
|
173
|
-
['command-code-oauth', 'Command Code'],
|
|
174
|
-
['mimo-oauth', 'MiMo'],
|
|
175
|
-
['cursor-oauth', 'Cursor OAuth'],
|
|
176
|
-
['devin-oauth', 'Devin'],
|
|
177
|
-
['antigravity-oauth', 'Antigravity OAuth'],
|
|
178
|
-
['openai', 'OpenAI API'],
|
|
179
|
-
['openai-api', 'OpenAI API'],
|
|
180
|
-
['anthropic', 'Anthropic API'],
|
|
181
|
-
['anthropic-api', 'Anthropic API'],
|
|
182
|
-
['gemini', 'Gemini API'],
|
|
183
|
-
['gemini-api', 'Gemini API'],
|
|
184
|
-
['xai', 'xAI API'],
|
|
185
|
-
['xai-api', 'xAI API'],
|
|
186
|
-
['deepseek', 'DeepSeek API'],
|
|
187
|
-
['deepseek-api', 'DeepSeek API'],
|
|
188
|
-
['opencode-go-oauth', 'OpenCode Go OAuth'],
|
|
189
|
-
['openrouter', 'OpenRouter'],
|
|
190
|
-
['mixdog-local', 'Local Provider'],
|
|
191
|
-
['default', 'Default'],
|
|
192
|
-
]);
|
|
193
|
-
|
|
194
|
-
export const providerDisplayName = (provider) =>
|
|
195
|
-
PROVIDER_DISPLAY_NAMES.get(String(provider || '').toLowerCase()) ?? (provider || 'Provider');
|
|
169
|
+
// Provider display names live in runtime/shared so error text can name the provider too.
|
|
170
|
+
export { providerDisplayName };
|
|
196
171
|
|
|
197
172
|
export const resolveProviderDisplayName = (provider, providerNames = null) =>
|
|
198
173
|
(String(provider || '')
|
package/src/tui/dist/index.mjs
CHANGED
|
@@ -24385,6 +24385,12 @@ var init_file_has_data = __esm({
|
|
|
24385
24385
|
}
|
|
24386
24386
|
});
|
|
24387
24387
|
|
|
24388
|
+
// src/runtime/shared/abort-race.mjs
|
|
24389
|
+
var init_abort_race = __esm({
|
|
24390
|
+
"src/runtime/shared/abort-race.mjs"() {
|
|
24391
|
+
}
|
|
24392
|
+
});
|
|
24393
|
+
|
|
24388
24394
|
// src/runtime/shared/bounded-download.mjs
|
|
24389
24395
|
import { createWriteStream, rmSync as rmSync2 } from "node:fs";
|
|
24390
24396
|
import { Transform as Transform2 } from "node:stream";
|
|
@@ -24458,7 +24464,7 @@ async function streamResponseToFile(response, destPath, { maxBytes, expectedByte
|
|
|
24458
24464
|
var MAX_NATIVE_BINARY_DOWNLOAD_BYTES;
|
|
24459
24465
|
var init_bounded_download = __esm({
|
|
24460
24466
|
"src/runtime/shared/bounded-download.mjs"() {
|
|
24461
|
-
|
|
24467
|
+
init_abort_race();
|
|
24462
24468
|
MAX_NATIVE_BINARY_DOWNLOAD_BYTES = 256 * 1024 * 1024;
|
|
24463
24469
|
}
|
|
24464
24470
|
});
|
|
@@ -40971,16 +40977,7 @@ function summarizeCodeGraphResult({ text, translate }) {
|
|
|
40971
40977
|
if (looksLikeZeroResultText(text)) return translate("No results", "No results");
|
|
40972
40978
|
return null;
|
|
40973
40979
|
}
|
|
40974
|
-
function summarizeFetchResult({ text
|
|
40975
|
-
if (normalized === "fetch") {
|
|
40976
|
-
const a = parseToolArgs(args);
|
|
40977
|
-
const isChannelFetch = !firstText(a.url, a.uri) && Boolean(firstText(a.channel, a.channelId, a.chatId, a.messageId) || a.limit != null);
|
|
40978
|
-
if (isChannelFetch) {
|
|
40979
|
-
const n = countNonEmptyLines(text);
|
|
40980
|
-
if (trimmed && looksLineOriented(text) && n > 0) return countLabel(translate, n, "message");
|
|
40981
|
-
return summarizeGenericResult(text, translate);
|
|
40982
|
-
}
|
|
40983
|
-
}
|
|
40980
|
+
function summarizeFetchResult({ text }) {
|
|
40984
40981
|
const status = /(?:HTTP[\s/]*\d?\.?\d?\s*|status[:\s]+)([1-5]\d{2})\b/i.exec(text) || /\b([1-5]\d{2})\s+(?:OK|Not\s+Found|Forbidden|Moved|Found|Created|No\s+Content|Bad\s+Request|Unauthorized|Internal)/.exec(
|
|
40985
40982
|
text
|
|
40986
40983
|
);
|
|
@@ -42494,6 +42491,22 @@ function transportErrorText(error) {
|
|
|
42494
42491
|
return `${TRANSPORT_SENTENCES[verdict.kind]}${detail ? ` (${detail})` : ""}.`;
|
|
42495
42492
|
}
|
|
42496
42493
|
|
|
42494
|
+
// src/runtime/shared/provider-timeout-phase.mjs
|
|
42495
|
+
var TIMEOUT_PHASE = Object.freeze({
|
|
42496
|
+
// The response headers did not arrive in the first-byte window.
|
|
42497
|
+
HEADERS: "headers",
|
|
42498
|
+
// The headers arrived, the first chunk did not.
|
|
42499
|
+
FIRST_CHUNK: "first-chunk",
|
|
42500
|
+
// A stream that already produced output went silent.
|
|
42501
|
+
IDLE: "idle",
|
|
42502
|
+
// A sign-in token refresh did not answer: an auth problem, not a slow model.
|
|
42503
|
+
AUTH: "auth"
|
|
42504
|
+
});
|
|
42505
|
+
function isFirstByteTimeout(err) {
|
|
42506
|
+
const phase = err?.timeoutPhase;
|
|
42507
|
+
return phase === TIMEOUT_PHASE.HEADERS || phase === TIMEOUT_PHASE.FIRST_CHUNK;
|
|
42508
|
+
}
|
|
42509
|
+
|
|
42497
42510
|
// src/runtime/agent/orchestrator/providers/provider-error-kind.mjs
|
|
42498
42511
|
var PROVIDER_ERROR_KINDS = Object.freeze([
|
|
42499
42512
|
"overloaded",
|
|
@@ -43341,20 +43354,6 @@ function describeError(value) {
|
|
|
43341
43354
|
};
|
|
43342
43355
|
}
|
|
43343
43356
|
|
|
43344
|
-
// src/runtime/shared/provider-timeout-phase.mjs
|
|
43345
|
-
var TIMEOUT_PHASE = Object.freeze({
|
|
43346
|
-
// The response headers did not arrive in the first-byte window.
|
|
43347
|
-
HEADERS: "headers",
|
|
43348
|
-
// The headers arrived, the first chunk did not.
|
|
43349
|
-
FIRST_CHUNK: "first-chunk",
|
|
43350
|
-
// A stream that already produced output went silent.
|
|
43351
|
-
IDLE: "idle"
|
|
43352
|
-
});
|
|
43353
|
-
function isFirstByteTimeout(err) {
|
|
43354
|
-
const phase = err?.timeoutPhase;
|
|
43355
|
-
return phase === TIMEOUT_PHASE.HEADERS || phase === TIMEOUT_PHASE.FIRST_CHUNK;
|
|
43356
|
-
}
|
|
43357
|
-
|
|
43358
43357
|
// src/runtime/shared/err-text.mjs
|
|
43359
43358
|
function errorHttpStatus(err) {
|
|
43360
43359
|
return Number(err?.httpStatus || err?.status || err?.response?.status || 0) || 0;
|
|
@@ -43512,16 +43511,16 @@ function hasTypedEvidence(error) {
|
|
|
43512
43511
|
if (!error || typeof error !== "object") return false;
|
|
43513
43512
|
return Boolean(error.errorKind?.kind) || errorHttpStatus(error) > 0 || Boolean(error.code) || Boolean(error.retryAfterMs);
|
|
43514
43513
|
}
|
|
43515
|
-
var timedOutMs = (text) => Number(/timed out after (\d+)ms/i.exec(text)?.[1]) || 0;
|
|
43516
|
-
function stillThinkingText(error, text) {
|
|
43514
|
+
var timedOutMs = (text) => Number(/(?:timed out after|within) (\d+)ms/i.exec(text)?.[1]) || 0;
|
|
43515
|
+
function stillThinkingText(error, text, providerLabel) {
|
|
43517
43516
|
const ms = Number(error.waitedMs) || timedOutMs(text);
|
|
43518
|
-
const provider = typeof
|
|
43517
|
+
const provider = typeof providerLabel === "string" && providerLabel ? providerLabel : "the provider";
|
|
43519
43518
|
const attempts = Number(error.attempts) > 0 ? `; attempts: ${Math.floor(Number(error.attempts))}` : "";
|
|
43520
43519
|
return `Model still thinking: no output in ${formatDurationMs(ms)}; ${provider} sent nothing yet${attempts}.`;
|
|
43521
43520
|
}
|
|
43522
|
-
function typedStreamFailureText(error, text) {
|
|
43521
|
+
function typedStreamFailureText(error, text, providerLabel) {
|
|
43523
43522
|
if (!error || typeof error !== "object") return null;
|
|
43524
|
-
if (isFirstByteTimeout(error)) return stillThinkingText(error, text);
|
|
43523
|
+
if (isFirstByteTimeout(error)) return stillThinkingText(error, text, providerLabel);
|
|
43525
43524
|
if (error.timeoutPhase === TIMEOUT_PHASE.IDLE) {
|
|
43526
43525
|
const ms = timedOutMs(text);
|
|
43527
43526
|
return ms > 0 ? `No progress ${formatDurationMs(ms)}.` : "No progress.";
|
|
@@ -43558,7 +43557,7 @@ function presentErrorText(error, options = {}) {
|
|
|
43558
43557
|
if (embeddedError) text = embeddedError;
|
|
43559
43558
|
text = oneLine(stripErrorPrefix(text));
|
|
43560
43559
|
if (!text) return "Unknown error";
|
|
43561
|
-
const streamFailure = typedStreamFailureText(error, text);
|
|
43560
|
+
const streamFailure = typedStreamFailureText(error, text, options.providerLabel);
|
|
43562
43561
|
if (streamFailure) return streamFailure;
|
|
43563
43562
|
if (code === "PROVIDER_PREFIX_MUTATION" || name === "ProviderPrefixMutationError") {
|
|
43564
43563
|
return "Session state changed unexpectedly.";
|
|
@@ -59516,6 +59515,34 @@ function isRollingModelAlias(id) {
|
|
|
59516
59515
|
return /-latest$/i.test(String(id || "").trim());
|
|
59517
59516
|
}
|
|
59518
59517
|
|
|
59518
|
+
// src/runtime/shared/provider-display-name.mjs
|
|
59519
|
+
var PROVIDER_DISPLAY_NAMES = /* @__PURE__ */ new Map([
|
|
59520
|
+
["openai-oauth", "OpenAI OAuth"],
|
|
59521
|
+
["anthropic-oauth", "Anthropic OAuth"],
|
|
59522
|
+
["grok-oauth", "Grok OAuth"],
|
|
59523
|
+
["muse-code-oauth", "Muse Code"],
|
|
59524
|
+
["command-code-oauth", "Command Code"],
|
|
59525
|
+
["mimo-oauth", "MiMo"],
|
|
59526
|
+
["cursor-oauth", "Cursor OAuth"],
|
|
59527
|
+
["devin-oauth", "Devin"],
|
|
59528
|
+
["antigravity-oauth", "Antigravity OAuth"],
|
|
59529
|
+
["openai", "OpenAI API"],
|
|
59530
|
+
["openai-api", "OpenAI API"],
|
|
59531
|
+
["anthropic", "Anthropic API"],
|
|
59532
|
+
["anthropic-api", "Anthropic API"],
|
|
59533
|
+
["gemini", "Gemini API"],
|
|
59534
|
+
["gemini-api", "Gemini API"],
|
|
59535
|
+
["xai", "xAI API"],
|
|
59536
|
+
["xai-api", "xAI API"],
|
|
59537
|
+
["deepseek", "DeepSeek API"],
|
|
59538
|
+
["deepseek-api", "DeepSeek API"],
|
|
59539
|
+
["opencode-go-oauth", "OpenCode Go OAuth"],
|
|
59540
|
+
["openrouter", "OpenRouter"],
|
|
59541
|
+
["mixdog-local", "Local Provider"],
|
|
59542
|
+
["default", "Default"]
|
|
59543
|
+
]);
|
|
59544
|
+
var providerDisplayName = (provider) => PROVIDER_DISPLAY_NAMES.get(String(provider || "").toLowerCase()) ?? (provider || "Provider");
|
|
59545
|
+
|
|
59519
59546
|
// src/runtime/shared/llm/openai-daybreak.mjs
|
|
59520
59547
|
var DAYBREAK_PROVIDER = "openai-oauth";
|
|
59521
59548
|
var DAYBREAK_PARAMETER_ID = "daybreak";
|
|
@@ -59663,32 +59690,6 @@ var normalizeModelOptions = (models) => {
|
|
|
59663
59690
|
}
|
|
59664
59691
|
return normalized;
|
|
59665
59692
|
};
|
|
59666
|
-
var PROVIDER_DISPLAY_NAMES = /* @__PURE__ */ new Map([
|
|
59667
|
-
["openai-oauth", "OpenAI OAuth"],
|
|
59668
|
-
["anthropic-oauth", "Anthropic OAuth"],
|
|
59669
|
-
["grok-oauth", "Grok OAuth"],
|
|
59670
|
-
["muse-code-oauth", "Muse Code"],
|
|
59671
|
-
["command-code-oauth", "Command Code"],
|
|
59672
|
-
["mimo-oauth", "MiMo"],
|
|
59673
|
-
["cursor-oauth", "Cursor OAuth"],
|
|
59674
|
-
["devin-oauth", "Devin"],
|
|
59675
|
-
["antigravity-oauth", "Antigravity OAuth"],
|
|
59676
|
-
["openai", "OpenAI API"],
|
|
59677
|
-
["openai-api", "OpenAI API"],
|
|
59678
|
-
["anthropic", "Anthropic API"],
|
|
59679
|
-
["anthropic-api", "Anthropic API"],
|
|
59680
|
-
["gemini", "Gemini API"],
|
|
59681
|
-
["gemini-api", "Gemini API"],
|
|
59682
|
-
["xai", "xAI API"],
|
|
59683
|
-
["xai-api", "xAI API"],
|
|
59684
|
-
["deepseek", "DeepSeek API"],
|
|
59685
|
-
["deepseek-api", "DeepSeek API"],
|
|
59686
|
-
["opencode-go-oauth", "OpenCode Go OAuth"],
|
|
59687
|
-
["openrouter", "OpenRouter"],
|
|
59688
|
-
["mixdog-local", "Local Provider"],
|
|
59689
|
-
["default", "Default"]
|
|
59690
|
-
]);
|
|
59691
|
-
var providerDisplayName = (provider) => PROVIDER_DISPLAY_NAMES.get(String(provider || "").toLowerCase()) ?? (provider || "Provider");
|
|
59692
59693
|
var resolveProviderDisplayName = (provider, providerNames = null) => String(provider || "").trim().startsWith("custom-") && providerNames?.[String(provider).trim()] || providerDisplayName(provider);
|
|
59693
59694
|
var loadProviderDisplayNames = async (store) => {
|
|
59694
59695
|
let setup = null;
|
|
@@ -62368,13 +62369,6 @@ function canonicalizeStoredChannelsConfig(value = {}) {
|
|
|
62368
62369
|
const next = isPlainObject(value) ? { ...value } : {};
|
|
62369
62370
|
delete next.promptInjection;
|
|
62370
62371
|
delete next.schedules;
|
|
62371
|
-
delete next.nonInteractive;
|
|
62372
|
-
delete next.interactive;
|
|
62373
|
-
delete next.backend;
|
|
62374
|
-
delete next.provider;
|
|
62375
|
-
delete next.discord;
|
|
62376
|
-
delete next.telegram;
|
|
62377
|
-
delete next.channel;
|
|
62378
62372
|
return next;
|
|
62379
62373
|
}
|
|
62380
62374
|
function canonicalizeUnifiedConfig(value = {}) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readImageAttachmentFromPath } from '../../paste-attachments.mjs';
|
|
2
|
+
import { PROMPT_ORIGIN_CHANNEL } from '../../../runtime/agent/orchestrator/session/manager/pending-message-entry.mjs';
|
|
2
3
|
|
|
3
4
|
// Channel inbound images arrive as a JSON-array-of-paths meta value (stringified
|
|
4
5
|
// across the notify IPC boundary). Parse defensively; a malformed value simply
|
|
@@ -44,6 +45,8 @@ export function createModelNotificationEnqueue({ chain, enqueue, getState, getDi
|
|
|
44
45
|
priority: 'later',
|
|
45
46
|
key: notificationKey || undefined,
|
|
46
47
|
displayText: delivery.displayText || text,
|
|
48
|
+
// Its provenance (an inbound channel message) rides beside the mode.
|
|
49
|
+
...(event?.origin === PROMPT_ORIGIN_CHANNEL ? { origin: PROMPT_ORIGIN_CHANNEL } : {}),
|
|
47
50
|
};
|
|
48
51
|
// Image load failed or overran its budget: still deliver the text body so
|
|
49
52
|
// the notification is never silently lost.
|
|
@@ -26,6 +26,9 @@ export function createInitialSessionState({ runtime, runtimeCwd, baseRouteState
|
|
|
26
26
|
queued: [],
|
|
27
27
|
thinking: null,
|
|
28
28
|
toolApproval: null,
|
|
29
|
+
// Approvals waiting behind the shown one (its own, and copies of sessions
|
|
30
|
+
// it delegated or handed work to): the dock's "1/N".
|
|
31
|
+
toolApprovalsWaiting: 0,
|
|
29
32
|
// How the last approval ended and from which device, so every device can
|
|
30
33
|
// say who answered ({ id, approved, device, at }).
|
|
31
34
|
toolApprovalResult: null,
|
|
@@ -40,6 +40,8 @@ export function createNoticeSurface({ getState, set, isDisposed, pushItem, repla
|
|
|
40
40
|
: polishNoticeText(text);
|
|
41
41
|
if (!value && !options.room) return null;
|
|
42
42
|
const forceTranscript = options.transcript === true;
|
|
43
|
+
// A message posted from the stored record keeps its stored time.
|
|
44
|
+
const storedAt = Number.isFinite(options.at) ? options.at : null;
|
|
43
45
|
if (!forceTranscript) return pushToast(value, tone, options.ttlMs, options);
|
|
44
46
|
// The agent's own message posted outside a turn (agent-home-delivery.mjs):
|
|
45
47
|
// its reply row, as the stored message restores.
|
|
@@ -50,8 +52,9 @@ export function createNoticeSurface({ getState, set, isDisposed, pushItem, repla
|
|
|
50
52
|
id,
|
|
51
53
|
text: value,
|
|
52
54
|
streaming: false,
|
|
53
|
-
at: Date.now(),
|
|
55
|
+
at: storedAt ?? Date.now(),
|
|
54
56
|
...(options.messageId ? { messageId: options.messageId } : {}),
|
|
57
|
+
...(options.posted ? { posted: true } : {}),
|
|
55
58
|
});
|
|
56
59
|
return id;
|
|
57
60
|
}
|
|
@@ -85,6 +88,9 @@ export function createNoticeSurface({ getState, set, isDisposed, pushItem, repla
|
|
|
85
88
|
// A held request of an unattended run (human-gate/held-message.mjs).
|
|
86
89
|
...(options.heldRequest ? { heldRequest: options.heldRequest } : {}),
|
|
87
90
|
...(options.messageId ? { messageId: options.messageId } : {}),
|
|
91
|
+
...(storedAt !== null ? { at: storedAt } : {}),
|
|
92
|
+
// Posted outside any turn: its own turn key (transcript-turn-keys.mjs).
|
|
93
|
+
...(options.posted ? { posted: true } : {}),
|
|
88
94
|
});
|
|
89
95
|
return id;
|
|
90
96
|
};
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* flattening, session activity timestamps, and batch merging.
|
|
5
5
|
*/
|
|
6
6
|
import { agentJobResultText, parseAgentJob, parseSyntheticAgentMessage } from './agent-envelope.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import { isAttachmentReference } from '../../runtime/attachments/store.mjs';
|
|
8
|
+
import { promptContentText, sessionActivityTimestamp } from '../../runtime/shared/idle-auto-clear-gate.mjs';
|
|
8
9
|
import { recognisedSlashToken } from '../app/slash-commands.mjs';
|
|
9
10
|
|
|
10
11
|
const QUEUE_PRIORITY = { now: 0, next: 1, later: 2 };
|
|
@@ -82,47 +83,7 @@ export function notificationDisplayText(text) {
|
|
|
82
83
|
return firstQueueLine(synthetic?.result || result || text) || 'agent notification';
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
export
|
|
86
|
-
if (typeof content === 'string') return content;
|
|
87
|
-
if (Array.isArray(content)) {
|
|
88
|
-
return content
|
|
89
|
-
.map((part) => {
|
|
90
|
-
if (typeof part === 'string') return part;
|
|
91
|
-
if (part?.type === 'text') return isAttachmentReference(part) ? attachmentTextForPart(part) : part.text || '';
|
|
92
|
-
if (part?.type === 'image') return '[Image]';
|
|
93
|
-
if (part?.type === 'file') return '[File]';
|
|
94
|
-
return part?.text || '';
|
|
95
|
-
})
|
|
96
|
-
.filter(Boolean)
|
|
97
|
-
.join('\n');
|
|
98
|
-
}
|
|
99
|
-
return String(content ?? '');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function timestampMs(value) {
|
|
103
|
-
if (value == null || value === '') return 0;
|
|
104
|
-
const n = Number(value);
|
|
105
|
-
if (Number.isFinite(n) && n > 0) return n;
|
|
106
|
-
const parsed = Date.parse(String(value));
|
|
107
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function hasModelVisibleConversation(session) {
|
|
111
|
-
const messages = Array.isArray(session?.messages) ? session.messages : [];
|
|
112
|
-
return messages.some((message) => {
|
|
113
|
-
const role = message?.role;
|
|
114
|
-
if (role !== 'user' && role !== 'assistant' && role !== 'tool') return false;
|
|
115
|
-
const text = promptContentText(message.content).trim();
|
|
116
|
-
if (role === 'user' && text.startsWith('<system-reminder>')) return false;
|
|
117
|
-
if (role === 'assistant' && text === '.' && !Array.isArray(message.toolCalls)) return false;
|
|
118
|
-
return !!text || role === 'assistant' || role === 'tool';
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export function sessionActivityTimestamp(session, fallback = 0) {
|
|
123
|
-
if (!hasModelVisibleConversation(session)) return 0;
|
|
124
|
-
return timestampMs(session?.lastUsedAt) || timestampMs(session?.updatedAt) || timestampMs(fallback);
|
|
125
|
-
}
|
|
86
|
+
export { promptContentText, sessionActivityTimestamp };
|
|
126
87
|
|
|
127
88
|
export function promptDisplayText(content, options = {}) {
|
|
128
89
|
if (typeof options.displayText === 'string' && options.displayText.trim()) return options.displayText;
|
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
* routes-agent-definitions.mjs — the session route surface's passthroughs to
|
|
3
3
|
* the runtime's agent, workflow-pack, connector and lead-identity services.
|
|
4
4
|
*/
|
|
5
|
+
|
|
6
|
+
/** Mixy's status with `exists`, the one rule (mixy-presence.mjs) the desktop
|
|
7
|
+
* answers from (main/mixy-first.ts). null when her routines cannot be read:
|
|
8
|
+
* the status still serves readers of her name. */
|
|
9
|
+
async function withMixyExists(status) {
|
|
10
|
+
if (!status || typeof status !== 'object') return status;
|
|
11
|
+
const { readMixyExists } = await import('../../../session-runtime/routine-owner.mjs');
|
|
12
|
+
return { ...status, exists: await readMixyExists(status).catch(() => null) };
|
|
13
|
+
}
|
|
14
|
+
|
|
5
15
|
export function createAgentDefinitionApi(runtime) {
|
|
6
16
|
return {
|
|
7
17
|
listAgents: () => {
|
|
@@ -53,8 +63,10 @@ export function createAgentDefinitionApi(runtime) {
|
|
|
53
63
|
saveLeadPersona: async (text) => runtime.saveLeadPersona?.(text) ?? '',
|
|
54
64
|
getLeadAgentBody: () => runtime.getLeadAgentBody?.() ?? '',
|
|
55
65
|
saveLeadAgentBody: async (text) => runtime.saveLeadAgentBody?.(text) ?? '',
|
|
56
|
-
getLeadStatus: () =>
|
|
57
|
-
|
|
66
|
+
getLeadStatus: async () =>
|
|
67
|
+
withMixyExists(
|
|
68
|
+
runtime.getLeadStatus?.() ?? { created: null, name: '', avatar: null, homeChatted: false, route: null }
|
|
69
|
+
),
|
|
58
70
|
getLeadHomeRoute: () => runtime.getLeadHomeRoute?.() ?? null,
|
|
59
71
|
saveLeadIdentity: async (payload) => runtime.saveLeadIdentity?.(payload) ?? null,
|
|
60
72
|
setLeadCreated: async (created, description) => runtime.setLeadCreated?.(created, description) ?? null,
|
|
@@ -54,14 +54,18 @@ const SESSION_ONLY_KEYS = new Set(['provider', 'model', 'effort', 'fast', 'autoE
|
|
|
54
54
|
* the tuning, or both. Completed here, inside the serialized route write,
|
|
55
55
|
* against the latest selected route — so a Fast-only change keeps the effort a
|
|
56
56
|
* previous write selected. `unchanged` when it asks for nothing the selected
|
|
57
|
-
* route does not already have
|
|
57
|
+
* route does not already have and the session itself already runs that model
|
|
58
|
+
* (a fallback hop moves the session, not the selected route).
|
|
58
59
|
*/
|
|
59
60
|
function completeSessionOnlyRequest(request, selected) {
|
|
60
61
|
const named = Boolean(request.provider || request.model);
|
|
61
62
|
const target = named ? request : { ...request, provider: selected.provider, model: selected.model };
|
|
62
63
|
const sameModel = target.provider === selected.provider && target.model === selected.model;
|
|
63
64
|
if (!sameModel) return { request: target, unchanged: false };
|
|
65
|
+
const sessionOnTarget =
|
|
66
|
+
!selected.sessionModel || (selected.sessionProvider === target.provider && selected.sessionModel === target.model);
|
|
64
67
|
const unchanged =
|
|
68
|
+
sessionOnTarget &&
|
|
65
69
|
Object.keys(request).every((key) => SESSION_ONLY_KEYS.has(key)) &&
|
|
66
70
|
(request.effort === undefined || request.effort === selected.effort) &&
|
|
67
71
|
(request.fast === undefined || request.fast === (selected.fast === true)) &&
|
|
@@ -128,6 +128,7 @@ export function createSessionRouteApi(bag) {
|
|
|
128
128
|
return result;
|
|
129
129
|
}),
|
|
130
130
|
getOrchestrationMode: () => runtime.getOrchestrationMode(),
|
|
131
|
+
getConfiguredOrchestrationMode: () => runtime.getConfiguredOrchestrationMode(),
|
|
131
132
|
setOrchestrationMode: withCommandLock(async (mode, options) => {
|
|
132
133
|
const result = await runtime.setOrchestrationMode(mode, options);
|
|
133
134
|
publishSessionSwitches(bag, { orchestrationModeSwitch: result?.orchestrationModeSwitch });
|
|
@@ -112,12 +112,28 @@ export function createSessionSettingsApi(bag) {
|
|
|
112
112
|
setAiSessionTitles: withCommandLock(async (enabled) => {
|
|
113
113
|
return await runtime.setAiSessionTitles?.(enabled);
|
|
114
114
|
}),
|
|
115
|
+
getCacheWarmingSettings: () => {
|
|
116
|
+
return runtime.getCacheWarmingSettings?.() || { enabled: true };
|
|
117
|
+
},
|
|
118
|
+
setCacheWarmingEnabled: withCommandLock(async (enabled) => {
|
|
119
|
+
return await runtime.setCacheWarmingEnabled?.(enabled);
|
|
120
|
+
}),
|
|
115
121
|
getHeartbeatSettings: () => {
|
|
116
|
-
return runtime.getHeartbeatSettings?.() || { heartbeat: true };
|
|
122
|
+
return runtime.getHeartbeatSettings?.() || { heartbeat: true, intervalMinutes: 60 };
|
|
117
123
|
},
|
|
118
124
|
setHeartbeatEnabled: withCommandLock(async (enabled) => {
|
|
119
125
|
return await runtime.setHeartbeatEnabled?.(enabled);
|
|
120
126
|
}),
|
|
127
|
+
setHeartbeatInterval: withCommandLock(async (minutes) => {
|
|
128
|
+
return await runtime.setHeartbeatInterval?.(minutes);
|
|
129
|
+
}),
|
|
130
|
+
// The desktop app reports the user's latest in-app input time: Mixy's
|
|
131
|
+
// heartbeat waits for 30 quiet minutes (mixy-heartbeat.mjs noteUserInput).
|
|
132
|
+
noteUserInput: async (at) => {
|
|
133
|
+
const { noteUserInput } = await import('../../../session-runtime/mixy-heartbeat.mjs');
|
|
134
|
+
noteUserInput(at);
|
|
135
|
+
return { ok: true };
|
|
136
|
+
},
|
|
121
137
|
getReactionSettings: () => {
|
|
122
138
|
return runtime.getReactionSettings?.() || { reactions: true };
|
|
123
139
|
},
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* cleared-session UI once the active turn settles.
|
|
5
5
|
*/
|
|
6
6
|
import { presentErrorText } from '../../../runtime/shared/err-text.mjs';
|
|
7
|
-
import { sessionActivityTimestamp } from '
|
|
7
|
+
import { idleAutoClearDue, sessionActivityTimestamp } from '../../../runtime/shared/idle-auto-clear-gate.mjs';
|
|
8
8
|
import { archiveItemsForCompaction, compactionArchivedRows } from '../compaction-view.mjs';
|
|
9
9
|
|
|
10
10
|
// Upper bound on the awaited idle compaction. Without a bound a stalled
|
|
@@ -17,29 +17,6 @@ import { archiveItemsForCompaction, compactionArchivedRows } from '../compaction
|
|
|
17
17
|
const AUTO_CLEAR_COMPACT_TIMEOUT_MS = 60_000;
|
|
18
18
|
const LATE_COMPLETION_NOTICE = 'auto-clear completed late; compacted conversation retained';
|
|
19
19
|
|
|
20
|
-
// A zero is often an unavailable/stale meter field, not an authoritative
|
|
21
|
-
// measurement. Do not let it mask the sibling live estimate.
|
|
22
|
-
function contextUsageBelowThreshold(runtime, minContextPercent) {
|
|
23
|
-
if (!(minContextPercent > 0)) return false;
|
|
24
|
-
const status = runtime.contextStatus?.() || null;
|
|
25
|
-
const usedTokens = Math.max(
|
|
26
|
-
0,
|
|
27
|
-
Number(status?.usedTokens) || 0,
|
|
28
|
-
Number(status?.currentEstimatedTokens) || 0,
|
|
29
|
-
Number(status?.compaction?.currentEstimatedTokens) || 0
|
|
30
|
-
);
|
|
31
|
-
const triggerTokens = Number(
|
|
32
|
-
status?.compaction?.triggerTokens ||
|
|
33
|
-
status?.compaction?.autoCompactTokenLimit ||
|
|
34
|
-
runtime.session?.autoCompactTokenLimit ||
|
|
35
|
-
0
|
|
36
|
-
);
|
|
37
|
-
if (!Number.isFinite(usedTokens) || !Number.isFinite(triggerTokens) || !(usedTokens > 0 && triggerTokens > 0)) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
return (usedTokens / triggerTokens) * 100 < minContextPercent;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
20
|
export function createAutoClearOps(bag, { reset, kickDrain }) {
|
|
44
21
|
const {
|
|
45
22
|
runtime,
|
|
@@ -140,15 +117,9 @@ export function createAutoClearOps(bag, { reset, kickDrain }) {
|
|
|
140
117
|
const cfg = autoClearState();
|
|
141
118
|
const now = Date.now();
|
|
142
119
|
const activityAt = sessionActivityTimestamp(runtime.session, flags.lastUserActivityAt);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
getState().busy ||
|
|
147
|
-
(!ignorePending && pending.length > 0) ||
|
|
148
|
-
flags.autoClearRunning ||
|
|
149
|
-
flags.autoClearInFlight ||
|
|
150
|
-
idleMs < cfg.idleMs;
|
|
151
|
-
if (notIdle || contextUsageBelowThreshold(runtime, Number(cfg.minContextPercent ?? 10))) {
|
|
120
|
+
const blocked =
|
|
121
|
+
getState().busy || (!ignorePending && pending.length > 0) || flags.autoClearRunning || flags.autoClearInFlight;
|
|
122
|
+
if (blocked || !idleAutoClearDue({ cfg, activityAt, at: now, runtime })) {
|
|
152
123
|
if (!activityAt) flags.lastUserActivityAt = now;
|
|
153
124
|
return false;
|
|
154
125
|
}
|