mixdog 1.3.5 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- 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 +35 -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 +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- 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/cache-break-trace.mjs +2 -0
- 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 +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- 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/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- 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-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- 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/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- 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/mimo-oauth-login.mjs +1 -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-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
- 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/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- 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 +38 -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 +49 -16
- 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/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- 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/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
- 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/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
- 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 +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -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/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- 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 +5 -4
- 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 +49 -21
- 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-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- 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 +24 -14
- 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 +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -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-delete.mjs +7 -0
- 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 +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -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 +79 -3
- 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/stall-policy.mjs +23 -0
- 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/invocation-plan.mjs +2 -2
- 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/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
- 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/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- 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 +28 -2
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -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/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- 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/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- 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/bot-owned-work.mjs +56 -0
- 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 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- 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/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- 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 +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -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 +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- 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-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -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 +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- 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 +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.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/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- 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/model-route/set-route.mjs +11 -2
- 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/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- 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/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- 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/provider-admin.mjs +2 -1
- 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 +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- 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 +142 -190
- 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/agent-tree/agent-turns.mjs +16 -12
- 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 +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- 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 +16 -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/ui/statusline-agents.mjs +1 -3
- 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
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
|
-
import { loadConfig,
|
|
4
|
+
import { loadConfig, DATA_DIR } from './config.mjs';
|
|
5
5
|
import { resolveVoiceRuntime } from './voice-runtime-fetcher.mjs';
|
|
6
6
|
import { whisperThreadCount } from './voice-transcription.mjs';
|
|
7
7
|
import { ensureReady, stopVoiceWhisperServer } from './whisper-server.mjs';
|
|
8
8
|
import { ensurePrivateRuntimeRoot, resolveRuntimeRoot } from '../../shared/runtime-root.mjs';
|
|
9
9
|
import { Scheduler } from './scheduler.mjs';
|
|
10
10
|
import { renameSchedule as renameScheduleRow } from './schedules-db.mjs';
|
|
11
|
-
import { hasPending as dispatchHasPending } from '../../agent/orchestrator/dispatch-persist.mjs';
|
|
12
11
|
import { stripSoftWarns } from '../../agent/orchestrator/tool-loop-guard.mjs';
|
|
13
12
|
import { JsonStateFile } from './state-file.mjs';
|
|
14
13
|
import { writeJsonAtomicSync } from '../../shared/atomic-file.mjs';
|
|
@@ -94,7 +93,6 @@ if (isMixdogDebug()) {
|
|
|
94
93
|
);
|
|
95
94
|
}
|
|
96
95
|
let config = await loadConfig();
|
|
97
|
-
let provider = createProvider(config);
|
|
98
96
|
const INSTANCE_ID = makeInstanceId();
|
|
99
97
|
const TERMINAL_LEAD_PID = getTerminalLeadPid();
|
|
100
98
|
runWorkerBootstrap({
|
|
@@ -129,22 +127,13 @@ let _reloadDebounce = null;
|
|
|
129
127
|
const STATUS_FILE = getStatusPath(INSTANCE_ID);
|
|
130
128
|
const statusState = new JsonStateFile(STATUS_FILE, {});
|
|
131
129
|
statusState.ensure();
|
|
132
|
-
const scheduler = new Scheduler(config.
|
|
130
|
+
const scheduler = new Scheduler(config.schedules ?? []);
|
|
133
131
|
// A schedule fire is a turn in its owner bot's chat; the runner belongs to the
|
|
134
132
|
// session-runtime layer, so this worker entry injects it (lazy, like webhooks).
|
|
135
133
|
scheduler.setScheduleRunner(async (schedule, opts) => {
|
|
136
134
|
const { runScheduleSession } = await import('../../../session-runtime/schedule-session-run.mjs');
|
|
137
135
|
return runScheduleSession(schedule, opts);
|
|
138
136
|
});
|
|
139
|
-
// Register the pending-dispatch probe so the scheduler treats an in-flight
|
|
140
|
-
// bridge dispatch as "active" regardless of user-inbound silence.
|
|
141
|
-
scheduler.setPendingCheck(() => {
|
|
142
|
-
try {
|
|
143
|
-
return dispatchHasPending(DATA_DIR);
|
|
144
|
-
} catch {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
137
|
let webhookServer = null;
|
|
149
138
|
let eventPipeline = null;
|
|
150
139
|
let bridgeRuntimeConnected = false;
|
|
@@ -158,10 +147,6 @@ const { startAutomationRuntime, startOwnedRuntime, stopOwnedRuntime, reloadRunti
|
|
|
158
147
|
setConfig: (v) => {
|
|
159
148
|
config = v;
|
|
160
149
|
},
|
|
161
|
-
getProvider: () => provider,
|
|
162
|
-
setProvider: (v) => {
|
|
163
|
-
provider = v;
|
|
164
|
-
},
|
|
165
150
|
getBridgeRuntimeConnected: () => bridgeRuntimeConnected,
|
|
166
151
|
setBridgeRuntimeConnected: (v) => {
|
|
167
152
|
bridgeRuntimeConnected = v;
|
|
@@ -185,7 +170,7 @@ const { startAutomationRuntime, startOwnedRuntime, stopOwnedRuntime, reloadRunti
|
|
|
185
170
|
wireWebhookHandlers,
|
|
186
171
|
wireEventQueueHandlers,
|
|
187
172
|
});
|
|
188
|
-
function injectAndRecord(
|
|
173
|
+
function injectAndRecord(content, options) {
|
|
189
174
|
// Strip soft-warn marker blocks (Tool-loop / Repeated-input / legacy
|
|
190
175
|
// Repeated-tool / Mixed-tool / Tool-budget / Same-file multi-chunk /
|
|
191
176
|
// Bash file-lookup / Iteration / 0-match advisory) from anywhere in the
|
|
@@ -199,22 +184,14 @@ function injectAndRecord(channelId, _name, content, options) {
|
|
|
199
184
|
const now = new Date();
|
|
200
185
|
const timeLabel = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')} `;
|
|
201
186
|
const sourceLabel = options?.type ? `${timeLabel}: ${options.type}` : timeLabel;
|
|
202
|
-
const meta = {
|
|
187
|
+
const meta = { user: sourceLabel, user_id: 'system', ts };
|
|
203
188
|
if (options?.instruction) meta.instruction = options.instruction;
|
|
204
189
|
if (options?.type) meta.type = options.type;
|
|
205
190
|
// `silent_to_agent` — lifecycle status pings (worker/iter/started echoes)
|
|
206
|
-
// must NOT land in Lead's context window
|
|
207
|
-
// surface them is retired, so silent pings are dropped entirely.
|
|
191
|
+
// must NOT land in Lead's context window, so silent pings are dropped.
|
|
208
192
|
if (options?.silent_to_agent === true) return;
|
|
209
193
|
sendNotifyToParent('notifications/claude/channel', { content, meta });
|
|
210
194
|
}
|
|
211
|
-
scheduler.setInjectHandler((channelId, name, content, options) => {
|
|
212
|
-
injectAndRecord(channelId, name, content, options);
|
|
213
|
-
});
|
|
214
|
-
// Interactive schedule fires may only inject while this process
|
|
215
|
-
// actually holds the live bridge seat; otherwise the scheduler falls back to
|
|
216
|
-
// the visible-session run so the fire is never lost.
|
|
217
|
-
scheduler.setInjectReadyCheck(() => bridgeRuntimeConnected && currentOwnerState().owned);
|
|
218
195
|
function wireWebhookHandlers() {
|
|
219
196
|
if (!webhookServer) return;
|
|
220
197
|
webhookServer.setEventPipeline(eventPipeline);
|
|
@@ -237,8 +214,8 @@ function wireWebhookHandlers() {
|
|
|
237
214
|
}
|
|
238
215
|
function wireEventQueueHandlers(eventQueue) {
|
|
239
216
|
if (!eventQueue) return;
|
|
240
|
-
eventQueue.setInjectHandler((
|
|
241
|
-
injectAndRecord(
|
|
217
|
+
eventQueue.setInjectHandler((_name, content, options) => {
|
|
218
|
+
injectAndRecord(content, options);
|
|
242
219
|
});
|
|
243
220
|
// Defensive ownership probe: the queue tick should only run in the active
|
|
244
221
|
// owner process. Non-owner instances see bridgeRuntimeConnected=false and
|
|
@@ -262,7 +239,7 @@ const { handleToolCall } = createToolDispatch({
|
|
|
262
239
|
},
|
|
263
240
|
writeBridgeState,
|
|
264
241
|
notifyRemoteAcquired,
|
|
265
|
-
startChannelBridge: () => start({
|
|
242
|
+
startChannelBridge: () => start({ bridge: true }),
|
|
266
243
|
stopOwnedRuntime,
|
|
267
244
|
reloadRuntimeConfig,
|
|
268
245
|
// Rename and re-arm under one reservation: the scheduler is reloaded from
|
|
@@ -288,7 +265,7 @@ function ensureConfigWatcher() {
|
|
|
288
265
|
} catch {}
|
|
289
266
|
}
|
|
290
267
|
async function start(options = {}) {
|
|
291
|
-
if (options?.
|
|
268
|
+
if (options?.bridge === false) {
|
|
292
269
|
channelBridgeActive = false;
|
|
293
270
|
writeBridgeState(false);
|
|
294
271
|
await startAutomationRuntime();
|
|
@@ -308,7 +285,7 @@ async function start(options = {}) {
|
|
|
308
285
|
}
|
|
309
286
|
// Hot-reload config on file change (schedules/webhooks/events).
|
|
310
287
|
// Cross-process edits invalidate the raw config cache before the debounced
|
|
311
|
-
// reload so both
|
|
288
|
+
// reload so both bridge and automation-only daemon modes stay current.
|
|
312
289
|
ensureConfigWatcher();
|
|
313
290
|
// Pre-warm the whisper-server manager once at owner startup so the first
|
|
314
291
|
// voice transcription does not pay cold-start cost. Non-blocking: failures
|
|
@@ -361,7 +338,6 @@ if (_isWorkerMode && process.send && process.env.MIXDOG_DAEMON_HOST !== '1') {
|
|
|
361
338
|
clearServerPid,
|
|
362
339
|
instanceId: INSTANCE_ID,
|
|
363
340
|
statusState,
|
|
364
|
-
getProvider: () => provider,
|
|
365
341
|
getConfig: () => config,
|
|
366
342
|
handleMemoryCallResponse,
|
|
367
343
|
handleToolCall,
|
|
@@ -35,8 +35,13 @@ const ACTIONS = [
|
|
|
35
35
|
'menu',
|
|
36
36
|
'clipboard',
|
|
37
37
|
'launch',
|
|
38
|
+
'saved_login',
|
|
38
39
|
];
|
|
39
40
|
|
|
41
|
+
// Which value of a saved login saved_login types (the host checks the focused
|
|
42
|
+
// field's kind before typing it).
|
|
43
|
+
const SAVED_LOGIN_FIELDS = ['username', 'password'];
|
|
44
|
+
|
|
40
45
|
const windowTarget = {
|
|
41
46
|
window_id: {
|
|
42
47
|
type: 'string',
|
|
@@ -347,6 +352,28 @@ export const COMPUTER_ACTION_CONTRACTS = [
|
|
|
347
352
|
['app']
|
|
348
353
|
)
|
|
349
354
|
),
|
|
355
|
+
branch(
|
|
356
|
+
'saved_login',
|
|
357
|
+
input(
|
|
358
|
+
{
|
|
359
|
+
...windowTarget,
|
|
360
|
+
...appTarget,
|
|
361
|
+
savedAccount: {
|
|
362
|
+
type: 'string',
|
|
363
|
+
minLength: 1,
|
|
364
|
+
description:
|
|
365
|
+
"Fallback sign-in in the user's own browser; prefer its existing session/SSO or Browser Use's saved sign-in. Saved login (username or masked label; a miss lists the site's labels) written after host checks into the focused field of a Chrome/Edge HTTPS page. The site receives it. A password is kept from you and its browser's pixels are withheld this turn, but a page that redisplays it can expose it, and other programs of the same Windows user are outside this protection; a username is not hidden. On refusal hand the secret to the user (handoff_user secret, surface computer).",
|
|
366
|
+
},
|
|
367
|
+
field: {
|
|
368
|
+
type: 'string',
|
|
369
|
+
enum: SAVED_LOGIN_FIELDS,
|
|
370
|
+
description:
|
|
371
|
+
"username (text field) or password (password field). One-time codes, passkeys, security keys and app approvals are the user's step: handoff_user takeover.",
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
['savedAccount', 'field']
|
|
375
|
+
)
|
|
376
|
+
),
|
|
350
377
|
];
|
|
351
378
|
|
|
352
379
|
// A JSON Schema 2020-12 object root with no root combinator (Anthropic
|
|
@@ -396,7 +423,7 @@ for (const actionBranch of COMPUTER_ACTION_CONTRACTS) {
|
|
|
396
423
|
// Actions that drive one exact window. They carry exactly one window target:
|
|
397
424
|
// the exact window_id, or an app label the host resolves to one window and
|
|
398
425
|
// refuses when it matches more than one.
|
|
399
|
-
const WINDOW_TARGET_ACTIONS = new Set(['act', 'window', 'menu', 'verify']);
|
|
426
|
+
const WINDOW_TARGET_ACTIONS = new Set(['act', 'window', 'menu', 'verify', 'saved_login']);
|
|
400
427
|
// The host command each window operation becomes; every other operation is a
|
|
401
428
|
// window_state change carrying the operation as its state.
|
|
402
429
|
const WINDOW_OPERATION_ACTIONS = Object.freeze({
|
|
@@ -564,6 +591,11 @@ function launchError(input) {
|
|
|
564
591
|
return null;
|
|
565
592
|
}
|
|
566
593
|
|
|
594
|
+
function savedLoginError(input) {
|
|
595
|
+
if (!String(input.savedAccount || '').trim()) return 'Computer Use saved_login savedAccount must not be empty';
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
|
|
567
599
|
function listError(input) {
|
|
568
600
|
if (hasOwn(input, 'limit') && input.kind !== 'history') {
|
|
569
601
|
return 'Computer Use list limit applies to kind="history"';
|
|
@@ -584,6 +616,7 @@ const ACTION_RULES = {
|
|
|
584
616
|
window: windowError,
|
|
585
617
|
clipboard: clipboardError,
|
|
586
618
|
launch: launchError,
|
|
619
|
+
saved_login: savedLoginError,
|
|
587
620
|
};
|
|
588
621
|
|
|
589
622
|
export function validateComputerToolArgs(rawArgs) {
|
|
@@ -686,6 +719,14 @@ export function toComputerHostCommand(rawArgs) {
|
|
|
686
719
|
command.action = inputValue.operation === 'write' ? 'clipboard_write' : 'clipboard_read';
|
|
687
720
|
delete command.operation;
|
|
688
721
|
break;
|
|
722
|
+
case 'saved_login':
|
|
723
|
+
// Always foreground: the value goes to the field focused in the
|
|
724
|
+
// browser window the host verified, never through window messages.
|
|
725
|
+
command.action = 'fill_saved_login';
|
|
726
|
+
command.saved_account = inputValue.savedAccount;
|
|
727
|
+
command.delivery = 'foreground';
|
|
728
|
+
delete command.savedAccount;
|
|
729
|
+
break;
|
|
689
730
|
default:
|
|
690
731
|
command.action = args.action;
|
|
691
732
|
}
|
|
@@ -29,6 +29,8 @@ action('input_recovery_state', nativeRead);
|
|
|
29
29
|
action('input_idle_state', nativeRead);
|
|
30
30
|
action('ocr_image', nativeRead);
|
|
31
31
|
action('ocr_status', nativeRead);
|
|
32
|
+
// Host-internal: whether a saved-login owner's runtime process has ended.
|
|
33
|
+
action('process_fate', nativeRead);
|
|
32
34
|
action('release_session', { retainNativeRefs: true });
|
|
33
35
|
action('release_cursor_theme', { retainNativeRefs: true });
|
|
34
36
|
// Handing held input, focus and pointer back changes no target's content, so a
|
|
@@ -98,8 +100,14 @@ for (const name of [
|
|
|
98
100
|
});
|
|
99
101
|
}
|
|
100
102
|
action('clipboard_write', { foreground: true });
|
|
103
|
+
// A saved login written into the focused field of the user's browser window:
|
|
104
|
+
// an input bound to a fresh observation, always on the foreground lane, with no
|
|
105
|
+
// automatic capture (the reply never carries the field it filled).
|
|
106
|
+
action('fill_saved_login', { observationBound: true, foreground: true, policy: 'act' });
|
|
101
107
|
action('sequence', { policy: 'act' });
|
|
102
|
-
|
|
108
|
+
// turn_settle: the runtime's settlement of one agent turn (turn_id), which
|
|
109
|
+
// alone retires a saved-login fill's protection (desktop secret-input.ts).
|
|
110
|
+
for (const name of ['execution_end', 'session_release', 'session_abort', 'turn_settle']) {
|
|
103
111
|
action(name, { lifecycle: true, observeOnly: true });
|
|
104
112
|
}
|
|
105
113
|
export const COMPUTER_ACTIONS = Object.freeze(catalogue);
|
|
@@ -25,6 +25,8 @@ import { MAX_COMPUTER_REQUEST_BYTES, readComputerBridgeJson, validateComputerRep
|
|
|
25
25
|
import { computerActionHas } from './actions.mjs';
|
|
26
26
|
import { linuxCaptureFallback, linuxComputerPreflight } from './linux-readiness.mjs';
|
|
27
27
|
import { continuePendingComputerWork, isPendingComputerWork } from './pending-continuation.mjs';
|
|
28
|
+
import { randomUUID } from 'node:crypto';
|
|
29
|
+
import { request as httpRequest } from 'node:http';
|
|
28
30
|
|
|
29
31
|
export { canonicalComputerResultText };
|
|
30
32
|
|
|
@@ -53,6 +55,18 @@ const pendingComputerSessionReleases = new Map();
|
|
|
53
55
|
// explicit release, so shutdown needs the full set.
|
|
54
56
|
const hostBoundComputerSessions = new Set();
|
|
55
57
|
const activeComputerExecutions = new Set();
|
|
58
|
+
// Per session, the newest agent turn that sent a saved-login fill whose
|
|
59
|
+
// settlement the desktop has not yet accepted. Aborts never clear it.
|
|
60
|
+
const savedLoginTurns = new Map();
|
|
61
|
+
/** This runtime process as the owner of its saved-login fills: the desktop
|
|
62
|
+
* keeps a fill's protection until its turn settles or this owner is gone
|
|
63
|
+
* (apps/desktop/src/main/secret-input.ts SavedLoginTurn). */
|
|
64
|
+
export const SAVED_LOGIN_OWNER_ID = randomUUID();
|
|
65
|
+
// The owner connection: one held POST /owner (owner id and this process id)
|
|
66
|
+
// to the bridge it was opened on. A close only detaches it on the desktop;
|
|
67
|
+
// the desktop retires this owner early only when the OS proves this process
|
|
68
|
+
// ended. The socket never keeps the process alive.
|
|
69
|
+
let savedLoginOwner = null;
|
|
56
70
|
const BRIDGE_UNAVAILABLE_MESSAGE =
|
|
57
71
|
'computer use is unavailable; open the Mixdog desktop app and enable Computer Use in settings';
|
|
58
72
|
|
|
@@ -269,7 +283,15 @@ async function executeComputerToolInner(rawArgs, context, note) {
|
|
|
269
283
|
command = fallback.command;
|
|
270
284
|
note.text = fallback.note;
|
|
271
285
|
}
|
|
272
|
-
|
|
286
|
+
// A saved-login fill names its agent turn: the desktop keeps the fill's
|
|
287
|
+
// protection until that turn's settlement (settleSavedLoginTurn).
|
|
288
|
+
const turnId = Number(context?.turnId) || 0;
|
|
289
|
+
const savedLoginTurn = command.action === 'fill_saved_login' && sessionId && turnId > 0 ? turnId : 0;
|
|
290
|
+
const encoded = JSON.stringify({
|
|
291
|
+
...command,
|
|
292
|
+
...(sessionId ? { session_id: sessionId } : {}),
|
|
293
|
+
...(savedLoginTurn ? { turn_id: savedLoginTurn, runtime_id: SAVED_LOGIN_OWNER_ID } : {}),
|
|
294
|
+
});
|
|
273
295
|
if (Buffer.byteLength(encoded) > MAX_COMPUTER_REQUEST_BYTES) {
|
|
274
296
|
return computerErrorResult('Error: computer request exceeds byte limit; no input was dispatched');
|
|
275
297
|
}
|
|
@@ -286,7 +308,14 @@ async function executeComputerToolInner(rawArgs, context, note) {
|
|
|
286
308
|
}
|
|
287
309
|
const releaseError = await awaitPendingSessionRelease(sessionId, args, context);
|
|
288
310
|
if (releaseError) return releaseError;
|
|
311
|
+
if (savedLoginTurn) {
|
|
312
|
+
const ownerError = await savedLoginOwnerError(discovery, sessionId, args, context);
|
|
313
|
+
if (ownerError) return ownerError;
|
|
314
|
+
}
|
|
289
315
|
trackComputerSession(sessionId, command);
|
|
316
|
+
// Recorded before the request leaves: the fill may arm its protection even
|
|
317
|
+
// when its reply is lost, so the turn's settlement is owed regardless.
|
|
318
|
+
if (savedLoginTurn) savedLoginTurns.set(sessionId, Math.max(savedLoginTurns.get(sessionId) || 0, savedLoginTurn));
|
|
290
319
|
const posted = await postWithBridgeRecovery(discovery, command, encoded, sessionId, context);
|
|
291
320
|
if (!posted.response) return posted;
|
|
292
321
|
const { bridge, response } = posted;
|
|
@@ -362,7 +391,7 @@ async function settlePendingComputerWork(value, command, bridge, sessionId, cont
|
|
|
362
391
|
}
|
|
363
392
|
}
|
|
364
393
|
|
|
365
|
-
async function sendComputerSessionControl(sessionId, action, timeoutMs) {
|
|
394
|
+
async function sendComputerSessionControl(sessionId, action, timeoutMs, extra = {}) {
|
|
366
395
|
const discovery = readBridgeDiscovery(DISCOVERY_FILE);
|
|
367
396
|
if (!discovery) return false;
|
|
368
397
|
try {
|
|
@@ -371,6 +400,7 @@ async function sendComputerSessionControl(sessionId, action, timeoutMs) {
|
|
|
371
400
|
{
|
|
372
401
|
action,
|
|
373
402
|
session_id: sessionId,
|
|
403
|
+
...extra,
|
|
374
404
|
},
|
|
375
405
|
{ timeoutMs }
|
|
376
406
|
);
|
|
@@ -381,12 +411,40 @@ async function sendComputerSessionControl(sessionId, action, timeoutMs) {
|
|
|
381
411
|
}
|
|
382
412
|
}
|
|
383
413
|
|
|
414
|
+
/** Runtime-only, at request time: bind `requestId` to the exact window and
|
|
415
|
+
* field ref the agent named (desktop secret-input.ts bindComputerSecret).
|
|
416
|
+
* Answers 'bound' or 'no_field'; no desktop or an unknown answer is 'blocked'. */
|
|
417
|
+
export async function computerSecretBind(sessionId, requestId, { ref = '', windowId = '', signal } = {}) {
|
|
418
|
+
const discovery = readBridgeDiscovery(DISCOVERY_FILE);
|
|
419
|
+
if (!discovery || !sessionId || !requestId) return 'blocked';
|
|
420
|
+
try {
|
|
421
|
+
const response = await postComputerCommand(
|
|
422
|
+
discovery,
|
|
423
|
+
{
|
|
424
|
+
action: 'secret_bind',
|
|
425
|
+
session_id: String(sessionId),
|
|
426
|
+
request_id: String(requestId),
|
|
427
|
+
ref: String(ref),
|
|
428
|
+
window_id: String(windowId),
|
|
429
|
+
},
|
|
430
|
+
{ signal }
|
|
431
|
+
);
|
|
432
|
+
const body = await readComputerBridgeJson(response);
|
|
433
|
+
const text = response.ok && body?.ok === true ? body.value?.text : '';
|
|
434
|
+
return ['bound', 'no_field'].includes(text) ? text : 'blocked';
|
|
435
|
+
} catch {
|
|
436
|
+
return 'blocked';
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
384
440
|
/** Runtime-only: type the secret the user handed the desktop for `requestId`
|
|
385
|
-
* into the
|
|
386
|
-
* here; the host answers only
|
|
441
|
+
* into the window and field it was bound to (computerSecretBind) once. The
|
|
442
|
+
* value never passes through here; the host answers only the outcome
|
|
443
|
+
* ('entered', 'no_field', 'page_changed', 'blocked', 'expired'); no desktop
|
|
444
|
+
* or an unknown answer is 'blocked'. */
|
|
387
445
|
export async function computerSecretInput(sessionId, requestId, { ref = '', windowId = '', signal } = {}) {
|
|
388
446
|
const discovery = readBridgeDiscovery(DISCOVERY_FILE);
|
|
389
|
-
if (!discovery || !sessionId || !requestId) return '
|
|
447
|
+
if (!discovery || !sessionId || !requestId) return 'blocked';
|
|
390
448
|
try {
|
|
391
449
|
const response = await postComputerCommand(
|
|
392
450
|
discovery,
|
|
@@ -400,9 +458,10 @@ export async function computerSecretInput(sessionId, requestId, { ref = '', wind
|
|
|
400
458
|
{ signal }
|
|
401
459
|
);
|
|
402
460
|
const body = await readComputerBridgeJson(response);
|
|
403
|
-
|
|
461
|
+
const text = response.ok && body?.ok === true ? body.value?.text : '';
|
|
462
|
+
return ['entered', 'no_field', 'page_changed', 'blocked', 'expired'].includes(text) ? text : 'blocked';
|
|
404
463
|
} catch {
|
|
405
|
-
return '
|
|
464
|
+
return 'blocked';
|
|
406
465
|
}
|
|
407
466
|
}
|
|
408
467
|
|
|
@@ -423,12 +482,125 @@ async function abortComputerSession(sessionId) {
|
|
|
423
482
|
* desktop back, keeping the warm worker and observation refs for a possible follow-up. */
|
|
424
483
|
export async function endComputerExecution(sessionId) {
|
|
425
484
|
const id = String(sessionId || '').trim();
|
|
426
|
-
if (!id
|
|
485
|
+
if (!id) return false;
|
|
486
|
+
await settleSavedLoginTurn(id);
|
|
487
|
+
if (!activeComputerExecutions.has(id)) return false;
|
|
427
488
|
const ended = await sendComputerSessionControl(id, 'execution_end', EXECUTION_END_TIMEOUT_MS);
|
|
428
489
|
if (ended) activeComputerExecutions.delete(id);
|
|
429
490
|
return ended;
|
|
430
491
|
}
|
|
431
492
|
|
|
493
|
+
/** Agent-turn settlement for a session that filled a saved login: tell the
|
|
494
|
+
* desktop the turn is over so that fill's protection can retire. Separate
|
|
495
|
+
* from input cleanup and independent of any abort; a settlement the desktop
|
|
496
|
+
* did not accept stays owed and is sent again at the session's next one.
|
|
497
|
+
* `endedTurnId` is the turn that ended when the caller knows it (the
|
|
498
|
+
* session's terminal state); otherwise the newest owed turn is the one
|
|
499
|
+
* ending (the lead's turn settlement). */
|
|
500
|
+
async function settleSavedLoginTurn(sessionId, endedTurnId = 0) {
|
|
501
|
+
const owed = savedLoginTurns.get(sessionId);
|
|
502
|
+
if (!owed) return;
|
|
503
|
+
if (endedTurnId > 0 && owed > endedTurnId) return;
|
|
504
|
+
const accepted = await sendComputerSessionControl(sessionId, 'turn_settle', EXECUTION_END_TIMEOUT_MS, {
|
|
505
|
+
turn_id: owed,
|
|
506
|
+
runtime_id: SAVED_LOGIN_OWNER_ID,
|
|
507
|
+
});
|
|
508
|
+
if (accepted && savedLoginTurns.get(sessionId) === owed) savedLoginTurns.delete(sessionId);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/** A session's agent turn reached its terminal state (done, error or
|
|
512
|
+
* cancelled; manager/runtime-liveness.mjs, for lead and sub-agent sessions
|
|
513
|
+
* alike): settle its saved-login fills. */
|
|
514
|
+
export async function finishComputerTurn(sessionId, turnId) {
|
|
515
|
+
const id = String(sessionId || '').trim();
|
|
516
|
+
if (!id || !(Number(turnId) > 0)) return;
|
|
517
|
+
await settleSavedLoginTurn(id, Number(turnId));
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Returns the error result that ends a saved-login call whose owner connection
|
|
521
|
+
// is not attached, or null to proceed. Nothing was sent in any of these cases.
|
|
522
|
+
async function savedLoginOwnerError(discovery, sessionId, args, context) {
|
|
523
|
+
let attached;
|
|
524
|
+
try {
|
|
525
|
+
attached = await attachSavedLoginOwner(discovery, context.signal);
|
|
526
|
+
} catch (error) {
|
|
527
|
+
if (context.signal?.aborted) return cancelledComputerResult(sessionId, false);
|
|
528
|
+
return computerErrorResult(
|
|
529
|
+
formatComputerToolError(
|
|
530
|
+
`saved_login_unavailable: the desktop did not answer the owner attachment (${error.name}); no input was sent`,
|
|
531
|
+
args
|
|
532
|
+
)
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
if (attached) return null;
|
|
536
|
+
return computerErrorResult(
|
|
537
|
+
formatComputerToolError(
|
|
538
|
+
'saved_login_unavailable: the desktop did not accept this runtime as the owner of its saved-login fills; no input was sent',
|
|
539
|
+
args
|
|
540
|
+
)
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** Open (or reuse) this runtime's owner connection to `discovery`'s bridge:
|
|
545
|
+
* true once the desktop answered it, false when it refused or is unreachable.
|
|
546
|
+
* The shared handshake is bounded by the bridge request timeout (rejecting
|
|
547
|
+
* with its TimeoutError and resetting the shared state); each caller's wait
|
|
548
|
+
* also ends on its own `signal` without closing the shared connection. */
|
|
549
|
+
function attachSavedLoginOwner(discovery, signal) {
|
|
550
|
+
const current = savedLoginOwner;
|
|
551
|
+
if (current && current.port === discovery.port && current.token === discovery.token) {
|
|
552
|
+
return waitForComputerRelease(current.attached, signal);
|
|
553
|
+
}
|
|
554
|
+
current?.request.destroy();
|
|
555
|
+
const owner = { port: discovery.port, token: discovery.token, request: null, attached: null };
|
|
556
|
+
owner.attached = new Promise((resolve, reject) => {
|
|
557
|
+
const body = JSON.stringify({ runtime_id: SAVED_LOGIN_OWNER_ID, pid: process.pid });
|
|
558
|
+
const handshake = AbortSignal.timeout(REQUEST_TIMEOUT_MS);
|
|
559
|
+
const forget = () => {
|
|
560
|
+
handshake.removeEventListener('abort', onHandshakeTimeout);
|
|
561
|
+
if (savedLoginOwner === owner) savedLoginOwner = null;
|
|
562
|
+
resolve(false);
|
|
563
|
+
};
|
|
564
|
+
// Rejects first, so the callers see the timeout; forgetting at once lets
|
|
565
|
+
// the next fill attach afresh instead of waiting on the closing socket.
|
|
566
|
+
function onHandshakeTimeout() {
|
|
567
|
+
reject(handshake.reason);
|
|
568
|
+
forget();
|
|
569
|
+
owner.request.destroy();
|
|
570
|
+
}
|
|
571
|
+
handshake.addEventListener('abort', onHandshakeTimeout, { once: true });
|
|
572
|
+
owner.request = httpRequest(
|
|
573
|
+
{
|
|
574
|
+
host: '127.0.0.1',
|
|
575
|
+
port: discovery.port,
|
|
576
|
+
path: '/owner',
|
|
577
|
+
method: 'POST',
|
|
578
|
+
agent: false,
|
|
579
|
+
headers: { ...computerCommandHeaders(discovery), 'content-length': Buffer.byteLength(body) },
|
|
580
|
+
},
|
|
581
|
+
(response) => {
|
|
582
|
+
response.once('close', forget);
|
|
583
|
+
response.once('error', forget);
|
|
584
|
+
if (response.statusCode !== 200) {
|
|
585
|
+
response.resume();
|
|
586
|
+
forget();
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
response.once('data', () => {
|
|
590
|
+
handshake.removeEventListener('abort', onHandshakeTimeout);
|
|
591
|
+
resolve(true);
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
);
|
|
595
|
+
owner.request.once('socket', (socket) => socket.unref());
|
|
596
|
+
owner.request.once('error', forget);
|
|
597
|
+
owner.request.once('close', forget);
|
|
598
|
+
owner.request.end(body);
|
|
599
|
+
});
|
|
600
|
+
savedLoginOwner = owner;
|
|
601
|
+
return waitForComputerRelease(owner.attached, signal);
|
|
602
|
+
}
|
|
603
|
+
|
|
432
604
|
function cancelDeferredComputerSessionRelease(sessionId) {
|
|
433
605
|
const id = String(sessionId || '').trim();
|
|
434
606
|
if (!id) return false;
|
|
@@ -74,13 +74,13 @@ export const COMPUTER_CORE_ACTION_SCHEMA = {
|
|
|
74
74
|
text: {
|
|
75
75
|
type: 'string',
|
|
76
76
|
maxLength: 30_000,
|
|
77
|
-
description: `Literal text; foreground cap ${MAX_COMPUTER_FOREGROUND_TEXT_CHARS} UTF-16 code units per action.`,
|
|
77
|
+
description: `Literal text; foreground cap ${MAX_COMPUTER_FOREGROUND_TEXT_CHARS} UTF-16 code units per action. Never a password or one-time code, even one shown on screen: saved_login or handoff_user.`,
|
|
78
78
|
},
|
|
79
79
|
value: {
|
|
80
80
|
type: 'string',
|
|
81
81
|
maxLength: 30_000,
|
|
82
82
|
description:
|
|
83
|
-
'set_value replacement for an element that advertises set_value; writes the control directly, without focus or keystrokes.',
|
|
83
|
+
'set_value replacement for an element that advertises set_value; writes the control directly, without focus or keystrokes. Never a password or one-time code, even one shown on screen: saved_login or handoff_user.',
|
|
84
84
|
},
|
|
85
85
|
keys: {
|
|
86
86
|
type: 'string',
|
|
@@ -20,7 +20,7 @@ function targetLabel(args) {
|
|
|
20
20
|
|
|
21
21
|
const LIST_WINDOW_CODES = new Set(['ambiguous_window_target', 'window_stale', 'window_target_not_found']);
|
|
22
22
|
const STALE_TARGET_CODES = new Set(['stale_frame', 'stale_target', 'target_mismatch']);
|
|
23
|
-
const USER_YIELD_CODES = new Set(['computer_user_control_active', 'computer_user_takeover'
|
|
23
|
+
const USER_YIELD_CODES = new Set(['computer_user_control_active', 'computer_user_takeover']);
|
|
24
24
|
const DIAGNOSE_CODES = new Set(['input_observation_unavailable', 'computer_cursor_unavailable']);
|
|
25
25
|
const CLEANUP_CODES = new Set([
|
|
26
26
|
'computer_cleanup_pending',
|
|
@@ -29,6 +29,11 @@ const CLEANUP_CODES = new Set([
|
|
|
29
29
|
'privileged_worker_cleanup_unconfirmed',
|
|
30
30
|
]);
|
|
31
31
|
const PIXEL_CODES = new Set(['pixel_unavailable', 'observation_unavailable']);
|
|
32
|
+
// Saved-login refusals made before anything was written (host/saved-login.ts).
|
|
33
|
+
const SAVED_LOGIN_REFUSAL_CODES = new Set(['saved_login_refused', 'saved_login_changed', 'saved_login_unavailable']);
|
|
34
|
+
const SECRET_HANDOFF = 'hand the secret to the user with handoff_user (kind "secret", surface "computer")';
|
|
35
|
+
const STEP_HANDOFF =
|
|
36
|
+
'hand the step to the user with handoff_user (kind "takeover", surface "computer", need "sign_in")';
|
|
32
37
|
// Reads send no input, so their timeout is a provider budget, not an uncertain
|
|
33
38
|
// mutation: the caller needs another read route, not a cleanup investigation.
|
|
34
39
|
const READ_ONLY_ACTIONS = new Set(['capture', 'list', 'diagnose', 'verify']);
|
|
@@ -109,7 +114,14 @@ function recoveryForCode(code, args) {
|
|
|
109
114
|
code,
|
|
110
115
|
next: 'wait_for_user',
|
|
111
116
|
guidance:
|
|
112
|
-
"Computer Use yielded to the user. Call wait_for_user for bounded waiting. The user's Resume on the overlay continues the pause
|
|
117
|
+
"Computer Use yielded to the user. Call wait_for_user for bounded waiting. The user's Resume on the overlay continues the pause. Physical input alone never pauses the session; only an explicit Pause/Stop or uncertain cleanup/observation does, and those require the user. Stop cancels the task. Timeout does not authorize input. After resumed, capture fresh state; never replay interrupted input.",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (code === 'user_input_active') {
|
|
121
|
+
return {
|
|
122
|
+
code,
|
|
123
|
+
next: 'capture',
|
|
124
|
+
guidance: `The user's own input interrupted this action only; the session keeps running and this is not a pause. Do not call wait_for_user for it. Capture ${target} again before any further input, and never replay the interrupted input, which may have been partly delivered. If the step needed foreground, retry it after the user pauses or use a supported background route.`,
|
|
113
125
|
};
|
|
114
126
|
}
|
|
115
127
|
if (code === 'input_recovery_unconfirmed') {
|
|
@@ -143,6 +155,20 @@ function recoveryForCode(code, args) {
|
|
|
143
155
|
guidance: `No input was sent. Foreground delivery needs an observation taken while the user's own input was idle. Let their input settle and capture ${target} again, or send this action through background delivery when it supports one.`,
|
|
144
156
|
};
|
|
145
157
|
}
|
|
158
|
+
if (SAVED_LOGIN_REFUSAL_CODES.has(code)) {
|
|
159
|
+
return {
|
|
160
|
+
code,
|
|
161
|
+
next: 'handoff_user',
|
|
162
|
+
guidance: `Nothing was written. If the refusal lists stored masked labels and the user's account is one of them, use that label; otherwise ${SECRET_HANDOFF}. Never type the secret yourself or try another window or field to get past the check.`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
if (code === 'saved_login_unconfirmed') {
|
|
166
|
+
return {
|
|
167
|
+
code,
|
|
168
|
+
next: 'handoff_user',
|
|
169
|
+
guidance: `The saved value may have been written. Do not call saved_login again for this field and do not type it yourself; ${STEP_HANDOFF} to check the field and finish signing in.`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
146
172
|
if (code === 'computer_command_timeout') return timeoutRecovery(code, args, target);
|
|
147
173
|
if (code.startsWith('menu_')) {
|
|
148
174
|
return {
|
|
@@ -14,15 +14,34 @@
|
|
|
14
14
|
// pointer/keyboard the input device (uinput on Wayland, XTest on X11).
|
|
15
15
|
|
|
16
16
|
const WINDOW_ACTIONS = new Set([
|
|
17
|
-
'list_windows',
|
|
18
|
-
'
|
|
19
|
-
'
|
|
17
|
+
'list_windows',
|
|
18
|
+
'window_snapshot',
|
|
19
|
+
'related_windows',
|
|
20
|
+
'window_bounds',
|
|
21
|
+
'window_capture',
|
|
22
|
+
'window_integrity',
|
|
23
|
+
'validate_background_input',
|
|
24
|
+
'list_apps',
|
|
25
|
+
'verify',
|
|
26
|
+
'focus_window',
|
|
27
|
+
'move_window',
|
|
28
|
+
'window_state',
|
|
29
|
+
'close_window',
|
|
30
|
+
'terminate_process',
|
|
20
31
|
]);
|
|
21
32
|
const ACCESSIBILITY_ACTIONS = new Set(['snapshot', 'find', 'window_predicates', 'accessibility_probe']);
|
|
22
33
|
const SEMANTIC_ACTIONS = new Set(['invoke', 'set_value', 'toggle', 'invoke_menu']);
|
|
23
34
|
const POINTER_ACTIONS = new Set([
|
|
24
|
-
'click',
|
|
25
|
-
'
|
|
35
|
+
'click',
|
|
36
|
+
'double_click',
|
|
37
|
+
'right_click',
|
|
38
|
+
'middle_click',
|
|
39
|
+
'triple_click',
|
|
40
|
+
'mouse_down',
|
|
41
|
+
'mouse_up',
|
|
42
|
+
'mouse_move',
|
|
43
|
+
'drag',
|
|
44
|
+
'scroll',
|
|
26
45
|
]);
|
|
27
46
|
const KEYBOARD_ACTIONS = new Set(['type', 'key', 'key_down', 'key_up']);
|
|
28
47
|
|
|
@@ -35,7 +35,10 @@ export interface LinuxComputerRefusal {
|
|
|
35
35
|
export const MIN_WINDOW_HELPER_VERSION: number;
|
|
36
36
|
export const CAPABILITY_UNAVAILABLE_CODE: 'computer_capability_unavailable';
|
|
37
37
|
export function detectSession(env: Record<string, string | undefined>): 'wayland' | 'x11';
|
|
38
|
-
export function detectDesktop(
|
|
38
|
+
export function detectDesktop(
|
|
39
|
+
env: Record<string, string | undefined>,
|
|
40
|
+
session: 'wayland' | 'x11'
|
|
41
|
+
): LinuxComputerReadiness['desktop'];
|
|
39
42
|
export function checkLinuxComputerReadiness(options?: Record<string, unknown>): Promise<LinuxComputerReadiness>;
|
|
40
43
|
export function getLinuxComputerReadiness(options?: Record<string, unknown>): Promise<LinuxComputerReadiness>;
|
|
41
44
|
export function missingCapabilities(
|
|
@@ -47,4 +50,6 @@ export function resetLinuxComputerPreflightCache(): void;
|
|
|
47
50
|
export const GNOME_EXTENSION_UUID: 'mixdog-windows@mixdog.io';
|
|
48
51
|
export function gnomeExtensionDirs(env?: Record<string, string | undefined>): string[];
|
|
49
52
|
export const CAPTURE_FALLBACK_NOTE: string;
|
|
50
|
-
export function linuxCaptureFallback(
|
|
53
|
+
export function linuxCaptureFallback(
|
|
54
|
+
options?: Record<string, unknown>
|
|
55
|
+
): Promise<{ command: Record<string, unknown>; note: string } | null>;
|