mixdog 1.3.4 → 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/LICENSES/oh-my-pi-MIT.txt +23 -0
- package/NOTICE.md +17 -2
- package/README.md +11 -0
- package/package.json +3 -11
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/embed-google-oauth-client.mjs +49 -0
- package/scripts/gate-local.mjs +4 -2
- package/scripts/lib/test-spawn-ledger.mjs +46 -1
- 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 +12 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +25 -1
- package/src/defaults/skills/browser-use/SKILL.md +77 -17
- 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 +29 -2
- package/src/defaults/skills/setup/references/actions.md +117 -28
- package/src/defaults/skills/setup/references/surfaces.md +77 -35
- package/src/defaults/skills/setup-guide/SKILL.md +3 -3
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/keychain-cjs.cjs +359 -29
- package/src/lib/rules-builder.cjs +10 -8
- package/src/rules/agent/AGENT.md +6 -6
- package/src/rules/agent-mode/AGENT_MODE.md +10 -2
- package/src/rules/agent-mode/MIXY.md +12 -0
- 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/heartbeat-completion.mjs +193 -0
- 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 +34 -0
- 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 +177 -73
- package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
- 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 +160 -69
- 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-oauth-catalog.mjs +52 -8
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
- package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
- package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
- 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 +19 -1
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -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/opencode-go-gemini.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
- 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 +43 -3
- 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/providers/wire-protobuf-codec.mjs +368 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- 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 +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
- 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-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
- 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 +8 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
- 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 +11 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -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 +14 -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 +10 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
- 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-commit.mjs +2 -0
- 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 +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -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 +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/session-tool-surface.mjs +13 -0
- 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/message-ids.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
- package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
- 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.d.mts +0 -2
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
- 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-header-cache.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
- 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/tail-reminder-rules.mjs +11 -5
- 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/tool-batch/state.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
- 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/schedule-errors.mjs +51 -0
- package/src/runtime/channels/lib/scheduler.mjs +135 -154
- package/src/runtime/channels/lib/schedules-db.mjs +83 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +14 -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 +19 -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/office/com/com-adapter.mjs +17 -1
- package/src/runtime/office/com/office-com-host.ps1 +51 -1
- package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
- package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
- package/src/runtime/office/pdf/document-preview.mjs +326 -8
- package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
- package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
- package/src/runtime/office/portable/portable-soffice.mjs +45 -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/bot-hops.mjs +62 -2
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +51 -35
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +33 -2
- package/src/runtime/shared/connector-catalog.mjs +166 -8
- 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/developer-options.mjs +32 -1
- 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/google-oauth-client.generated.json +4 -0
- package/src/runtime/shared/google-oauth-client.mjs +34 -9
- 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/anthropic-betas.mjs +7 -0
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/llm/well-formed.mjs +66 -0
- 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 +231 -59
- package/src/runtime/shared/provider-api-key.mjs +19 -8
- 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 +52 -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-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +1 -14
- package/src/runtime/shared/transcript-metadata.mjs +38 -0
- package/src/runtime/shared/user-data-guard.mjs +30 -2
- package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
- 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 +486 -179
- package/src/session-runtime/agent-room-delivery.mjs +28 -1
- package/src/session-runtime/agent-task-sessions.mjs +561 -199
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/begin.mjs +3 -2
- 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 +8 -1
- package/src/session-runtime/bot-chain.mjs +32 -0
- package/src/session-runtime/bot-status.mjs +7 -4
- package/src/session-runtime/channel-config-api.mjs +63 -17
- 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/internal-tool-executor/reaction-tool.mjs +45 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
- package/src/session-runtime/internal-tool-executor.mjs +4 -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 +61 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +927 -0
- package/src/session-runtime/model-route/route-tuning.mjs +10 -6
- 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 +35 -13
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/provider-auth/login.mjs +7 -0
- package/src/session-runtime/provider-models/row-hydration.mjs +13 -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/routine-home-turn.mjs +33 -6
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/schedule-session-run.mjs +7 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
- 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 +73 -31
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/channel-worker.mjs +1 -1
- package/src/session-runtime/services/provider-admin.mjs +128 -25
- package/src/session-runtime/services/schedule-access.mjs +14 -0
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +8 -4
- 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 +28 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +187 -29
- package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
- package/src/session-runtime/task-session-route.mjs +99 -0
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
- package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
- package/src/session-runtime/tool-surface.mjs +4 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
- package/src/session-runtime/workspace/transitions.mjs +10 -2
- 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 +161 -157
- package/src/standalone/daemon.mjs +33 -2
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +10 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
- 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-turns.mjs +6 -0
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-service.mjs +13 -0
- package/src/standalone/session-tool-output.mjs +21 -10
- package/src/tui/app/model-options.mjs +4 -27
- package/src/tui/dist/index.mjs +81 -65
- 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 +23 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/integrations.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +8 -0
- 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 +30 -2
- 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 +36 -3
- package/src/tui/session/turn.mjs +23 -2
- 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
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// The fallback chain a running session follows, read from its settings when
|
|
2
|
+
// it is needed (a hop, a status read) instead of the copy taken at creation:
|
|
3
|
+
// an edit made while the session runs applies from its next model request,
|
|
4
|
+
// and a chain cleared to [] stops further hops at once.
|
|
5
|
+
// - A Lead-class session (coding Lead, a bot's chat, Mixy) follows its
|
|
6
|
+
// owner's stored route (owner-route-fallbacks.mjs);
|
|
7
|
+
// - a delegated agent follows the route it was spawned from
|
|
8
|
+
// (`routeFallbackSource`: its agent's route, else Main's, or a named preset).
|
|
9
|
+
// The stored chain applies only while the session's primary — the route it
|
|
10
|
+
// ran on before its first hop — is that stored route's model. A session
|
|
11
|
+
// whose source cannot be read (an older record, a direct route) keeps its own.
|
|
12
|
+
import { findPreset } from '../../runtime-core/config-helpers.mjs';
|
|
13
|
+
import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
|
|
14
|
+
import { configuredAgentRouteCandidates } from '../../../../shared/agent-route-config.mjs';
|
|
15
|
+
import { CODING_MODE, resolveSessionMode } from '../agent-mode.mjs';
|
|
16
|
+
import { _liveSessions } from '../store/live-state.mjs';
|
|
17
|
+
import { ownerConfiguredRoute, sameRouteModel } from './owner-route-fallbacks.mjs';
|
|
18
|
+
|
|
19
|
+
const LEAF_FIELDS = ['effort', 'fast', 'autoEffort', 'modelParameters', 'contextPercent', 'contextTokens'];
|
|
20
|
+
|
|
21
|
+
/** The switchable fields of a route or session record (no chain). */
|
|
22
|
+
export function routeLeaf(route) {
|
|
23
|
+
const leaf = { provider: route?.provider || '', model: route?.model || '' };
|
|
24
|
+
for (const key of LEAF_FIELDS) if (route?.[key] !== undefined && route[key] !== null) leaf[key] = route[key];
|
|
25
|
+
return leaf;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The route the session ran on before its first fallback hop; its own route
|
|
29
|
+
* while it has not hopped. */
|
|
30
|
+
export function sessionRoutePrimary(session) {
|
|
31
|
+
if (session?.routeFallbackPrimary?.provider) return session.routeFallbackPrimary;
|
|
32
|
+
const first = session?.routeFallbackFailures?.[0];
|
|
33
|
+
if (first?.provider && first?.model) return { provider: first.provider, model: first.model };
|
|
34
|
+
return routeLeaf(session);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function normalizedOrNull(stored) {
|
|
38
|
+
if (!stored) return null;
|
|
39
|
+
try {
|
|
40
|
+
return normalizeWorkflowRoute(stored) || null;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The stored route the session's chain comes from, read now; null when the
|
|
47
|
+
* session has no readable source (it then keeps its own chain). */
|
|
48
|
+
export function sessionChainSource(session, config) {
|
|
49
|
+
const { mode, agentId } = resolveSessionMode({ session });
|
|
50
|
+
if (agentId) return ownerConfiguredRoute({ sessionMode: mode, agentId, config });
|
|
51
|
+
const source = session?.routeFallbackSource;
|
|
52
|
+
if (source?.agent) {
|
|
53
|
+
// As the spawn resolved it: the agent's own route, else Main's.
|
|
54
|
+
const own = configuredAgentRouteCandidates(config, source.agent).map(normalizedOrNull).find(Boolean);
|
|
55
|
+
return own || normalizedOrNull(findPreset(config, config?.default));
|
|
56
|
+
}
|
|
57
|
+
if (source?.preset) return normalizedOrNull(findPreset(config, source.preset));
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** `{ chain, fromSettings }`: the fallback routes the session follows now. */
|
|
62
|
+
export function liveRouteFallbacks(session, config) {
|
|
63
|
+
const source = sessionChainSource(session, config);
|
|
64
|
+
if (!source)
|
|
65
|
+
return { chain: Array.isArray(session?.routeFallbacks) ? session.routeFallbacks : [], fromSettings: false };
|
|
66
|
+
const onSourcePrimary = sameRouteModel(source, sessionRoutePrimary(session));
|
|
67
|
+
return { chain: onSourcePrimary ? source.fallbacks || [] : [], fromSettings: true };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Index in `chain` of the next route to try: the first after the session's
|
|
71
|
+
* current model that this session has not already run (its primary and the
|
|
72
|
+
* models it already left); `chain.length` when none is left. */
|
|
73
|
+
export function nextRouteFallbackIndex(session, chain) {
|
|
74
|
+
const tried = [sessionRoutePrimary(session), ...(session?.routeFallbackFailures || []), session];
|
|
75
|
+
const at = chain.findIndex((entry) => sameRouteModel(entry, session));
|
|
76
|
+
for (let index = at + 1; index < chain.length; index += 1) {
|
|
77
|
+
if (!tried.some((route) => sameRouteModel(chain[index], route))) return index;
|
|
78
|
+
}
|
|
79
|
+
return chain.length;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const modelOf = (route) => ({ provider: route?.provider || '', model: route?.model || '' });
|
|
83
|
+
|
|
84
|
+
/** The public fallback position of one session: the route it is on against
|
|
85
|
+
* its primary, the hop index, the chain it follows now and why it left each model. */
|
|
86
|
+
export function routeFallbackPosition(session, config) {
|
|
87
|
+
const { chain, fromSettings } = liveRouteFallbacks(session, config);
|
|
88
|
+
const next = chain[nextRouteFallbackIndex(session, chain)] || null;
|
|
89
|
+
const primary = sessionRoutePrimary(session);
|
|
90
|
+
const { mode, agentId } = resolveSessionMode({ session });
|
|
91
|
+
let kind = 'agent';
|
|
92
|
+
if (agentId) kind = mode === CODING_MODE ? 'lead' : 'bot';
|
|
93
|
+
return {
|
|
94
|
+
sessionId: session.id,
|
|
95
|
+
kind,
|
|
96
|
+
agent: agentId || session.agent || null,
|
|
97
|
+
current: modelOf(session),
|
|
98
|
+
primary: modelOf(primary),
|
|
99
|
+
onPrimary: sameRouteModel(primary, session),
|
|
100
|
+
fallbackIndex: Number(session.routeFallbackIndex) || 0,
|
|
101
|
+
fallbacks: chain.map(modelOf),
|
|
102
|
+
chainFrom: fromSettings ? 'settings' : 'session',
|
|
103
|
+
next: next ? modelOf(next) : null,
|
|
104
|
+
failures: (session.routeFallbackFailures || []).map(({ provider, model, kind: errorKind, error }) => ({
|
|
105
|
+
provider,
|
|
106
|
+
model,
|
|
107
|
+
kind: errorKind,
|
|
108
|
+
error,
|
|
109
|
+
})),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Whether the session has left its primary for a fallback model. */
|
|
114
|
+
export const routeFallbackHopped = (session) =>
|
|
115
|
+
Number(session?.routeFallbackIndex) > 0 || Boolean(session?.routeFallbackFailures?.length);
|
|
116
|
+
|
|
117
|
+
/** Positions of the sessions held in this process that follow a chain or have
|
|
118
|
+
* hopped; `keep(position)` narrows them. */
|
|
119
|
+
export function liveRouteFallbackPositions(config, keep = () => true) {
|
|
120
|
+
const rows = [];
|
|
121
|
+
for (const session of _liveSessions.values()) {
|
|
122
|
+
// Only a session with an agent hops (advanceAgentRoute).
|
|
123
|
+
if (!session?.id || session.closed === true || !session.agent) continue;
|
|
124
|
+
const position = routeFallbackPosition(session, config);
|
|
125
|
+
if (!position.fallbacks.length && !routeFallbackHopped(session)) continue;
|
|
126
|
+
if (keep(position)) rows.push(position);
|
|
127
|
+
}
|
|
128
|
+
return rows;
|
|
129
|
+
}
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
// }
|
|
24
24
|
import { createAbortController } from '../../../../shared/abort-controller.mjs';
|
|
25
25
|
import { emitSessionApprovalWaitChange } from '../../../../shared/session-approval-wait.mjs';
|
|
26
|
-
import { emitSessionActivityChange } from '../../../../shared/session-activity-signal.mjs';
|
|
26
|
+
import { emitSessionActivityChange, emitSessionTurnStart } from '../../../../shared/session-activity-signal.mjs';
|
|
27
27
|
import { DEFAULT_ACTIVITY_HEARTBEAT_MS } from '../../stall-policy.mjs';
|
|
28
28
|
import { MODEL_THINKING_STAGE, awaitingModelResponse, lastProgressAt } from '../../../../shared/quiet-progress.mjs';
|
|
29
|
-
import { finishBrowserTurn } from '../../../../browser-bridge/client.mjs';
|
|
29
|
+
import { beginBrowserTurn, finishBrowserTurn, forgetBrowserSession } from '../../../../browser-bridge/client.mjs';
|
|
30
|
+
import { registerSessionPurgeHook } from '../store.mjs';
|
|
31
|
+
import { finishComputerTurn } from '../../../../computer-bridge/client.mjs';
|
|
30
32
|
import { configureUsageMetricsRuntime, dropMetricSeenState, bumpUsageMetricsTurnId } from './usage-metrics.mjs';
|
|
31
33
|
import { runtimeState as _runtimeState, isTurnInFlight } from './runtime-state.mjs';
|
|
32
34
|
|
|
@@ -48,11 +50,25 @@ const VALID_STAGES = new Set([
|
|
|
48
50
|
]);
|
|
49
51
|
const TERMINAL_STAGES = new Set(['done', 'error']);
|
|
50
52
|
|
|
53
|
+
function beginBrowserWork(id, entry) {
|
|
54
|
+
void beginBrowserTurn(id, entry.browserTurnId).catch((error) => {
|
|
55
|
+
process.stderr.write(`[browser] Task start failed: ${error?.message || error}\n`);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// A session deleted for good no longer has browser turns to report.
|
|
60
|
+
registerSessionPurgeHook(forgetBrowserSession);
|
|
61
|
+
|
|
51
62
|
function finishBrowserWork(id, entry, aborted = false) {
|
|
52
63
|
const turnId = Number(entry.browserTurnId ?? entry.session?.usageMetricsTurnId) || 0;
|
|
53
64
|
void finishBrowserTurn(id, turnId, { aborted }).catch((error) => {
|
|
54
65
|
process.stderr.write(`[browser] Task cleanup failed: ${error?.message || error}\n`);
|
|
55
66
|
});
|
|
67
|
+
// The same terminal state settles the turn's Computer Use saved-login fills
|
|
68
|
+
// (lead and sub-agent sessions alike).
|
|
69
|
+
void finishComputerTurn(id, turnId).catch((error) => {
|
|
70
|
+
process.stderr.write(`[computer] Turn settlement failed: ${error?.message || error}\n`);
|
|
71
|
+
});
|
|
56
72
|
}
|
|
57
73
|
|
|
58
74
|
// Injected deps that would otherwise pull manager.mjs's store/provider surface
|
|
@@ -149,6 +165,7 @@ export function markSessionAskStart(id) {
|
|
|
149
165
|
const sessionForTurn = entry.session ?? _deps.loadSession(id);
|
|
150
166
|
if (sessionForTurn) bumpUsageMetricsTurnId(sessionForTurn);
|
|
151
167
|
entry.browserTurnId = Number(sessionForTurn?.usageMetricsTurnId) || 0;
|
|
168
|
+
beginBrowserWork(id, entry);
|
|
152
169
|
entry.stage = 'connecting';
|
|
153
170
|
entry.lastStreamDeltaAt = null;
|
|
154
171
|
entry.lastTransportAt = null;
|
|
@@ -179,6 +196,7 @@ export function markSessionAskStart(id) {
|
|
|
179
196
|
entry.lastProgressAt = now;
|
|
180
197
|
entry.updatedAt = now;
|
|
181
198
|
entry.taskWaits = 0;
|
|
199
|
+
emitSessionTurnStart(id);
|
|
182
200
|
emitSessionActivityChange(id);
|
|
183
201
|
}
|
|
184
202
|
/** The provider put the request on the wire; its response headers are
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
} from './runtime-liveness.mjs';
|
|
25
25
|
import { clearTurnCheckpoint } from './turn-checkpoint.mjs';
|
|
26
26
|
import { forgetSessionSaveBaseline } from '../store/save-worker.mjs';
|
|
27
|
+
import { publishSessionPersistence } from '../store/session-persistence-events.mjs';
|
|
27
28
|
import { forgetSessionLoadCache } from '../store/load-cache.mjs';
|
|
28
29
|
import { releaseReadSnapshotScope } from '../../tools/builtin/snapshot-store.mjs';
|
|
29
30
|
import { cancelOwnedShellTrees } from '../../tools/lib/owned-shell-trees.mjs';
|
|
@@ -142,6 +143,7 @@ function finishClose({ id, reason, tombstone, entry, closeSnapshot, newGen, outc
|
|
|
142
143
|
// above; committing it stops the turn's checkpoint writer. Only now is it
|
|
143
144
|
// safe to remove the crash fallback.
|
|
144
145
|
closeSnapshot?.commit();
|
|
146
|
+
publishSessionPersistence(id, 'closed');
|
|
145
147
|
_stopToolActivityHeartbeat(id);
|
|
146
148
|
cancelOwnedShellProcesses({ id, reason, tombstone });
|
|
147
149
|
clearTurnCheckpoint(id);
|
|
@@ -288,6 +288,13 @@ export function createSession(createOpts) {
|
|
|
288
288
|
if (rulesRevision) session.rulesRevision = rulesRevision;
|
|
289
289
|
}
|
|
290
290
|
if (routeFallbacks?.length) session.routeFallbacks = routeFallbacks;
|
|
291
|
+
// Where an agent's chain is read from at each hop (route-fallback-chain.mjs).
|
|
292
|
+
const fallbackSource = Object.hasOwn(opts, 'routeFallbackSource')
|
|
293
|
+
? opts.routeFallbackSource
|
|
294
|
+
: presetObj?.fallbackSource;
|
|
295
|
+
if (!actingAgent && fallbackSource && typeof fallbackSource === 'object') {
|
|
296
|
+
session.routeFallbackSource = { ...fallbackSource };
|
|
297
|
+
}
|
|
291
298
|
// A non-native agent sends core + bridge, built from its filtered tools.
|
|
292
299
|
applyAgentToolExposure(session);
|
|
293
300
|
refreshSessionBp3Environment(session, opts.cwd);
|
|
@@ -364,6 +371,7 @@ function applyRouteFields(session, route) {
|
|
|
364
371
|
else delete session.routeFallbacks;
|
|
365
372
|
delete session.routeFallbackIndex;
|
|
366
373
|
delete session.routeFallbackFailures;
|
|
374
|
+
delete session.routeFallbackPrimary;
|
|
367
375
|
}
|
|
368
376
|
ensureCodexWireSessionId(session);
|
|
369
377
|
if (Object.hasOwn(route, 'modelParameters')) {
|
|
@@ -36,7 +36,7 @@ export function normalizeDesktopSessionMetadata(value, cwd = null) {
|
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
function initialCompactionConfig(compaction = {}, contextMeta = {}) {
|
|
39
|
+
export function initialCompactionConfig(compaction = {}, contextMeta = {}) {
|
|
40
40
|
return {
|
|
41
41
|
auto: compaction?.auto !== false,
|
|
42
42
|
model: compaction?.model || null,
|
|
@@ -10,6 +10,9 @@ import { isAgentOwner } from '../../agent-owner.mjs';
|
|
|
10
10
|
import { getHiddenAgent } from '../../internal-agents.mjs';
|
|
11
11
|
import { workflowDisallowsAgentTool } from '../../runtime-core/workflow.mjs';
|
|
12
12
|
import { isAgentModeSession } from '../agent-mode.mjs';
|
|
13
|
+
import { agentIdOfHomeSession } from '../agent-home.mjs';
|
|
14
|
+
import { roomMemberOfSession } from '../agent-room.mjs';
|
|
15
|
+
import { REACTION_TOOL_NAME } from '../../runtime-core/reaction-tool-defs.mjs';
|
|
13
16
|
import { finalizeSessionToolList, resolveSessionTools, permissionFromToolSpec } from './tool-resolution.mjs';
|
|
14
17
|
import { unusedModelEditToolName } from '../../../../shared/edit-tool-dialect.mjs';
|
|
15
18
|
import { getAgentRuntimeSync } from './agent-runtime-singleton.mjs';
|
|
@@ -24,6 +27,14 @@ export function delegationDisabled(source, ownerIsAgent) {
|
|
|
24
27
|
);
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
// The react tool belongs to a bot's own chat with the user: its home chat
|
|
31
|
+
// (`sess_home_<id>`) or its seat in a group room (`sess_rmem_…`), decided by the
|
|
32
|
+
// session's id, never a coding session or a delegated worker.
|
|
33
|
+
export function reactionDisabled(source, ownerIsAgent) {
|
|
34
|
+
const id = String(source?.id || '');
|
|
35
|
+
return ownerIsAgent || !(agentIdOfHomeSession(id) || roomMemberOfSession(id));
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
// Exactly two schema surfaces exist: Lead and Agent. Every Agent role gets
|
|
28
39
|
// the full Lead-capable base bundle; the recursive `agent` control tool is
|
|
29
40
|
// removed later at the owner boundary. Role permission remains prompt/
|
|
@@ -79,6 +90,7 @@ export function resolveSessionToolSurface(opts, { profile, toolPreset, modelName
|
|
|
79
90
|
const sessionDeny = [
|
|
80
91
|
...(Array.isArray(opts.disallowedTools) ? opts.disallowedTools : []),
|
|
81
92
|
...(delegationDisabled(opts, ownerIsAgent) ? ['agent'] : []),
|
|
93
|
+
...(reactionDisabled(opts, ownerIsAgent) ? [REACTION_TOOL_NAME] : []),
|
|
82
94
|
];
|
|
83
95
|
// Role permission is prompt/diagnostic metadata only. Resolve and persist
|
|
84
96
|
// it without shaping the provider-visible Agent schema.
|
|
@@ -144,6 +156,7 @@ export function _prepareResumeTools(session, preset) {
|
|
|
144
156
|
disallowedTools: [
|
|
145
157
|
...(Array.isArray(session.disallowedTools) ? session.disallowedTools : []),
|
|
146
158
|
...(delegationDisabled(session, ownerIsAgent) ? ['agent'] : []),
|
|
159
|
+
...(reactionDisabled(session, ownerIsAgent) ? [REACTION_TOOL_NAME] : []),
|
|
147
160
|
],
|
|
148
161
|
ownerIsAgent,
|
|
149
162
|
}),
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import { compareCodePoints } from '../../../../shared/code-point-order.mjs';
|
|
4
4
|
import { getMcpTools } from '../../mcp/client.mjs';
|
|
5
5
|
import { getInternalTools } from '../../internal-tools.mjs';
|
|
6
|
-
import { BUILTIN_TOOLS } from '../../tools/builtin/builtin-tools.mjs';
|
|
6
|
+
import { BUILTIN_TOOLS, bindShellKind } from '../../tools/builtin/builtin-tools.mjs';
|
|
7
|
+
import { resolveShellFor } from '../../tools/builtin/shell-runtime.mjs';
|
|
7
8
|
import { PATCH_TOOL_DEFS } from '../../tools/patch-tool-defs.mjs';
|
|
8
9
|
import { CODE_GRAPH_TOOL_DEFS } from '../../tools/code-graph-tool-defs.mjs';
|
|
9
10
|
import { buildSkillToolDefs } from '../../context/collect.mjs';
|
|
@@ -101,7 +102,11 @@ export function resolveSessionTools(
|
|
|
101
102
|
// time (loop.mjs), so the schema bytes stay bit-identical across roles /
|
|
102
103
|
// cwds and the provider cache shard does not fragment.
|
|
103
104
|
const skillTools = buildSkillToolDefs(skills, { ownerIsAgentSession });
|
|
104
|
-
|
|
105
|
+
// The shell text follows the system shell the runtime actually resolves
|
|
106
|
+
// (Git Bash/WSL on Windows, pwsh on POSIX), before the edit-dialect rewrite.
|
|
107
|
+
const shellKind = resolveShellFor('default')?.shellType;
|
|
108
|
+
const base = _computeBaseTools(toolSpec, mcp, skillTools).map((tool) => bindShellKind(tool, shellKind));
|
|
109
|
+
return filterModelEditTools(base, modelName);
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
export function previewSessionTools(toolSpec, skills = [], options = {}) {
|
|
@@ -39,6 +39,8 @@ import { join } from 'node:path';
|
|
|
39
39
|
import { getPluginData } from '../../config.mjs';
|
|
40
40
|
import { writeFileAtomicSync } from '../../../../shared/atomic-file.mjs';
|
|
41
41
|
import { sanitizeContentForStoredHistory } from '../../providers/media-normalization.mjs';
|
|
42
|
+
import { redactSettledText, sensitiveValuesVersion } from '../sensitive-values.mjs';
|
|
43
|
+
import { redactSensitiveContent, redactSensitiveMessage, redactSensitiveToolCall } from '../sensitive-projection.mjs';
|
|
42
44
|
import { promptContentText } from './prompt-utils.mjs';
|
|
43
45
|
|
|
44
46
|
const TURN_CHECKPOINT_VERSION = 1;
|
|
@@ -96,7 +98,7 @@ export function checkpointMessage(message) {
|
|
|
96
98
|
return content === message.content ? message : { ...message, content };
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
function matchingUserMessage(message, currentUserContent) {
|
|
100
102
|
return (
|
|
101
103
|
message?.role === 'user' &&
|
|
102
104
|
(message.content === currentUserContent ||
|
|
@@ -131,16 +133,54 @@ export function emptyInterruptionSnapshot() {
|
|
|
131
133
|
};
|
|
132
134
|
}
|
|
133
135
|
|
|
134
|
-
//
|
|
136
|
+
// Observed tool calls ([id, { call, eagerStarted }]) and early tool results
|
|
137
|
+
// ([id, tool message]) as a checkpoint stores them (sensitive-projection.mjs).
|
|
138
|
+
const storedCallEntries = (sessionId, entries) =>
|
|
139
|
+
entries.map(([id, entry]) => {
|
|
140
|
+
const call = redactSensitiveToolCall(sessionId, entry?.call);
|
|
141
|
+
return [id, call === entry?.call ? entry : { ...entry, call }];
|
|
142
|
+
});
|
|
143
|
+
const storedResultEntries = (sessionId, entries) =>
|
|
144
|
+
entries.map(([id, message]) => [id, redactSensitiveMessage(sessionId, message)]);
|
|
145
|
+
|
|
146
|
+
/** Interruption snapshot `snapshot` as `sessionId`'s checkpoint stores it:
|
|
147
|
+
* sensitive values (sensitive-values.mjs) replaced, and of the partial text
|
|
148
|
+
* only what no value can still complete. */
|
|
149
|
+
function redactInterruptionSnapshot(sessionId, snapshot) {
|
|
150
|
+
const source = snapshot ?? emptyInterruptionSnapshot();
|
|
151
|
+
if (!sensitiveValuesVersion(sessionId)) return source;
|
|
152
|
+
return {
|
|
153
|
+
...source,
|
|
154
|
+
partialAssistantContent: redactSettledText(sessionId, String(source.partialAssistantContent || '')),
|
|
155
|
+
partialReasoningContent: redactSettledText(sessionId, String(source.partialReasoningContent || '')),
|
|
156
|
+
observedToolCalls: storedCallEntries(
|
|
157
|
+
sessionId,
|
|
158
|
+
Array.isArray(source.observedToolCalls) ? source.observedToolCalls : []
|
|
159
|
+
),
|
|
160
|
+
observedToolResults: storedResultEntries(
|
|
161
|
+
sessionId,
|
|
162
|
+
Array.isArray(source.observedToolResults) ? source.observedToolResults : []
|
|
163
|
+
),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ── Header (written once per turn, again when a sensitive value is marked) ──
|
|
135
168
|
|
|
136
169
|
export function writeCheckpointHeader(checkpoint) {
|
|
137
|
-
const
|
|
170
|
+
const { sessionId } = checkpoint;
|
|
171
|
+
const target = turnCheckpointPath(sessionId);
|
|
138
172
|
const payload = {
|
|
139
173
|
...checkpoint,
|
|
140
174
|
version: TURN_CHECKPOINT_VERSION,
|
|
141
|
-
currentUserContent:
|
|
142
|
-
|
|
143
|
-
|
|
175
|
+
currentUserContent: redactSensitiveContent(
|
|
176
|
+
sessionId,
|
|
177
|
+
sanitizeContentForStoredHistory(checkpoint.currentUserContent)
|
|
178
|
+
),
|
|
179
|
+
turnMessages: (Array.isArray(checkpoint.turnMessages) ? checkpoint.turnMessages : []).map((message) =>
|
|
180
|
+
redactSensitiveMessage(sessionId, checkpointMessage(message))
|
|
181
|
+
),
|
|
182
|
+
interruption: redactInterruptionSnapshot(sessionId, checkpoint.interruption),
|
|
183
|
+
// Counts, token readings and signatures only: no text.
|
|
144
184
|
contextState: checkpoint.contextState ?? null,
|
|
145
185
|
updatedAt: Date.now(),
|
|
146
186
|
};
|
|
@@ -488,7 +528,15 @@ export function replayTurnJournal(header) {
|
|
|
488
528
|
if (seq > expected) break;
|
|
489
529
|
expected = seq + 1;
|
|
490
530
|
if (!head) {
|
|
491
|
-
|
|
531
|
+
// A header rewritten for a newly marked sensitive value starts a new
|
|
532
|
+
// journal epoch; the journal it replaces never replays onto it.
|
|
533
|
+
if (
|
|
534
|
+
record.t !== 'h' ||
|
|
535
|
+
record.turnToken !== header.turnToken ||
|
|
536
|
+
(Number(record.e) || 0) !== (Number(header.journalEpoch) || 0)
|
|
537
|
+
) {
|
|
538
|
+
return header;
|
|
539
|
+
}
|
|
492
540
|
head = true;
|
|
493
541
|
continue;
|
|
494
542
|
}
|
|
@@ -529,7 +577,7 @@ export function replayTurnJournal(header) {
|
|
|
529
577
|
* turn-relative index) plus an opaque interruption cursor, so each encode()
|
|
530
578
|
* touches only what changed since the previous flush.
|
|
531
579
|
*/
|
|
532
|
-
export function createTurnJournalEncoder({ turnToken } = {}) {
|
|
580
|
+
export function createTurnJournalEncoder({ turnToken, sessionId = null } = {}) {
|
|
533
581
|
let journaled = [];
|
|
534
582
|
let fullTranscript = false;
|
|
535
583
|
let cursor = null;
|
|
@@ -537,27 +585,65 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
|
|
|
537
585
|
// Per-turn record sequence. It is assigned where records are produced, so
|
|
538
586
|
// the number line is exactly the enqueue order the write lane preserves.
|
|
539
587
|
let seq = 0;
|
|
588
|
+
// Set while the session has sensitive values (sensitive-values.mjs): the
|
|
589
|
+
// tracker's state as its deltas build it (`raw`) and the state the journal
|
|
590
|
+
// replays to (`written`). Interruption deltas are then journaled as the
|
|
591
|
+
// difference of the redacted text, so a value that streams in across
|
|
592
|
+
// flushes never lands in pieces. A newly marked value reseeds the encoder
|
|
593
|
+
// (turn-checkpoint.mjs), so the session's values are known whenever this is null.
|
|
594
|
+
let mirror = null;
|
|
540
595
|
const line = (record) => {
|
|
541
596
|
const stamped = { ...record, s: seq };
|
|
542
597
|
seq += 1;
|
|
543
598
|
return `${JSON.stringify(stamped)}\n`;
|
|
544
599
|
};
|
|
600
|
+
const stored = (message) => redactSensitiveMessage(sessionId, checkpointMessage(message));
|
|
601
|
+
const interruptionRecord = (delta) => {
|
|
602
|
+
if (!mirror) return delta;
|
|
603
|
+
applyInterruptionDelta(mirror.raw, delta);
|
|
604
|
+
const out = {};
|
|
605
|
+
for (const key of ['rs', 'ph', 'cc', 'od']) if (Object.hasOwn(delta, key)) out[key] = delta[key];
|
|
606
|
+
for (const [field, setKey, appendKey] of [
|
|
607
|
+
['text', 'ts', 'ta'],
|
|
608
|
+
['reasoning', 'qs', 'qa'],
|
|
609
|
+
]) {
|
|
610
|
+
const settled = redactSettledText(sessionId, mirror.raw[field]);
|
|
611
|
+
const written = mirror.written[field];
|
|
612
|
+
if (settled === written) continue;
|
|
613
|
+
if (settled.startsWith(written)) out[appendKey] = settled.slice(written.length);
|
|
614
|
+
else out[setKey] = settled;
|
|
615
|
+
}
|
|
616
|
+
if (Object.hasOwn(delta, 'tb')) out.tb = redactSensitiveContent(sessionId, mirror.raw.tomb);
|
|
617
|
+
if (delta.cs) out.cs = storedCallEntries(sessionId, delta.cs);
|
|
618
|
+
if (delta.os) out.os = storedResultEntries(sessionId, delta.os);
|
|
619
|
+
applyInterruptionDelta(mirror.written, out);
|
|
620
|
+
return out;
|
|
621
|
+
};
|
|
545
622
|
return {
|
|
546
623
|
/** Seed from the turn's opening state; returns the header's messages
|
|
547
624
|
* and the journal's opening lines (head record, plus — defensively —
|
|
548
625
|
* the delta that makes the journal authoritative if the tracker already
|
|
549
|
-
* carried state at open time).
|
|
550
|
-
|
|
626
|
+
* carried state at open time). `snapshot` is the tracker snapshot the
|
|
627
|
+
* header stores; `epoch` names the journal a rewritten header starts. */
|
|
628
|
+
seed(turnOutgoing, currentUserContent, interruption, contextState = null, { snapshot = null, epoch = 0 } = {}) {
|
|
551
629
|
const source = Array.isArray(turnOutgoing) ? turnOutgoing : [];
|
|
552
630
|
const start = findTurnStart(source, currentUserContent);
|
|
553
631
|
fullTranscript = start < 0;
|
|
554
632
|
journaled = fullTranscript ? source.slice() : source.slice(start);
|
|
633
|
+
mirror = sensitiveValuesVersion(sessionId)
|
|
634
|
+
? {
|
|
635
|
+
raw: interruptionStateFromSnapshot(snapshot),
|
|
636
|
+
written: interruptionStateFromSnapshot(redactInterruptionSnapshot(sessionId, snapshot)),
|
|
637
|
+
}
|
|
638
|
+
: null;
|
|
555
639
|
const seeded = typeof interruption?.journalDelta === 'function' ? interruption.journalDelta(null) : null;
|
|
556
640
|
cursor = seeded ? seeded.cursor : null;
|
|
557
641
|
contextStateKey = contextState == null ? null : JSON.stringify(contextState);
|
|
558
642
|
seq = 0;
|
|
559
|
-
const openLines = [line({ t: 'h', turnToken, at: Date.now() })];
|
|
560
|
-
|
|
643
|
+
const openLines = [line({ t: 'h', turnToken, ...(epoch ? { e: epoch } : {}), at: Date.now() })];
|
|
644
|
+
const seededDelta = seeded?.changed ? interruptionRecord(seeded.delta) : null;
|
|
645
|
+
if (seededDelta && Object.keys(seededDelta).length)
|
|
646
|
+
openLines.push(line({ t: 'x', d: seededDelta, at: Date.now() }));
|
|
561
647
|
return {
|
|
562
648
|
turnMessages: journaled.map(checkpointMessage),
|
|
563
649
|
fullTranscript,
|
|
@@ -579,7 +665,7 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
|
|
|
579
665
|
journaled = source.slice();
|
|
580
666
|
records.push({
|
|
581
667
|
t: 'full',
|
|
582
|
-
ms: journaled.map(
|
|
668
|
+
ms: journaled.map(stored),
|
|
583
669
|
});
|
|
584
670
|
} else {
|
|
585
671
|
const offset = fullTranscript ? 0 : start;
|
|
@@ -588,7 +674,7 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
|
|
|
588
674
|
const raw = source[offset + index];
|
|
589
675
|
if (journaled[index] === raw) continue;
|
|
590
676
|
journaled[index] = raw;
|
|
591
|
-
records.push({ t: 'm', i: index, m:
|
|
677
|
+
records.push({ t: 'm', i: index, m: stored(raw) });
|
|
592
678
|
}
|
|
593
679
|
if (journaled.length > length) {
|
|
594
680
|
journaled.length = length;
|
|
@@ -598,7 +684,8 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
|
|
|
598
684
|
if (typeof interruption?.journalDelta === 'function') {
|
|
599
685
|
const next = interruption.journalDelta(cursor);
|
|
600
686
|
cursor = next.cursor;
|
|
601
|
-
|
|
687
|
+
const delta = next.changed ? interruptionRecord(next.delta) : null;
|
|
688
|
+
if (delta && Object.keys(delta).length) records.push({ t: 'x', d: delta });
|
|
602
689
|
}
|
|
603
690
|
const nextContextStateKey = contextState == null ? null : JSON.stringify(contextState);
|
|
604
691
|
if (nextContextStateKey !== contextStateKey) {
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from './turn-checkpoint-journal.mjs';
|
|
20
20
|
import { captureTurnCheckpointContextState, restoreTurnCheckpointContextState } from './turn-checkpoint-context.mjs';
|
|
21
21
|
import { stripProviderReplayMessages } from './provider-replay.mjs';
|
|
22
|
+
import { sensitiveValuesVersion } from '../sensitive-values.mjs';
|
|
22
23
|
|
|
23
24
|
export { turnCheckpointPath, turnMessagesForCheckpoint };
|
|
24
25
|
export { captureTurnCheckpointContextState, restoreTurnCheckpointContextState };
|
|
@@ -67,9 +68,14 @@ export function projectTurnCheckpointMessages(session, checkpoint) {
|
|
|
67
68
|
// long tool-heavy turn no longer amplifies into the shared engine thread that
|
|
68
69
|
// every fanned-out agent session shares.
|
|
69
70
|
export function createTurnCheckpointRecorder({ sessionId, generation, turnToken, startedAt }) {
|
|
70
|
-
const encoder = createTurnJournalEncoder({ turnToken });
|
|
71
|
+
const encoder = createTurnJournalEncoder({ turnToken, sessionId });
|
|
71
72
|
let opened = false;
|
|
72
73
|
let stopped = false;
|
|
74
|
+
// The sensitive-values version (sensitive-values.mjs) the header and
|
|
75
|
+
// journal were written under. A newly marked value rewrites both from the
|
|
76
|
+
// turn's current state with the value replaced, under a new journal epoch,
|
|
77
|
+
// so no recovery record keeps it.
|
|
78
|
+
let openedVersion = 0;
|
|
73
79
|
return {
|
|
74
80
|
get opened() {
|
|
75
81
|
return opened;
|
|
@@ -77,8 +83,14 @@ export function createTurnCheckpointRecorder({ sessionId, generation, turnToken,
|
|
|
77
83
|
/** True when this call wrote or queued durable state. */
|
|
78
84
|
record({ currentUserContent, turnOutgoing, interruption, contextState = null }) {
|
|
79
85
|
if (stopped || !sessionId || !turnToken) return false;
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
const version = sensitiveValuesVersion(sessionId);
|
|
87
|
+
if (!opened || version !== openedVersion) {
|
|
88
|
+
const snapshot =
|
|
89
|
+
typeof interruption?.snapshot === 'function' ? interruption.snapshot() : emptyInterruptionSnapshot();
|
|
90
|
+
const seed = encoder.seed(turnOutgoing, currentUserContent, interruption, contextState, {
|
|
91
|
+
snapshot,
|
|
92
|
+
epoch: version,
|
|
93
|
+
});
|
|
82
94
|
writeCheckpointHeader({
|
|
83
95
|
sessionId,
|
|
84
96
|
generation,
|
|
@@ -87,10 +99,11 @@ export function createTurnCheckpointRecorder({ sessionId, generation, turnToken,
|
|
|
87
99
|
currentUserContent,
|
|
88
100
|
turnMessages: seed.turnMessages,
|
|
89
101
|
...(seed.fullTranscript ? { fullTranscript: true } : {}),
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
...(version ? { journalEpoch: version } : {}),
|
|
103
|
+
interruption: snapshot,
|
|
92
104
|
contextState: seed.contextState,
|
|
93
105
|
});
|
|
106
|
+
openedVersion = version;
|
|
94
107
|
// Opening the journal is part of the anchor: a leftover journal
|
|
95
108
|
// from an earlier turn of this session must never replay onto
|
|
96
109
|
// the new header. It lands synchronously when the lane is idle
|
|
@@ -26,7 +26,7 @@ export function messageIdOf(message) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/** Whether `meta` can hold a transcript id (absent or a plain object). */
|
|
29
|
-
|
|
29
|
+
function canCarryMessageId(message) {
|
|
30
30
|
if (!message || typeof message !== 'object') return false;
|
|
31
31
|
const meta = message.meta;
|
|
32
32
|
return meta === undefined || meta === null || (typeof meta === 'object' && !Array.isArray(meta));
|
|
@@ -101,12 +101,14 @@ export function stampMessageIds(messages, { sessionId = '' } = {}) {
|
|
|
101
101
|
|
|
102
102
|
/** JSON.stringify replacer that leaves stable ids out: hashes and archives
|
|
103
103
|
* the compactor derives from message JSON describe the conversation, not
|
|
104
|
-
* its display bookkeeping (a meta that only held the id is left out too).
|
|
104
|
+
* its display bookkeeping (a meta that only held the id is left out too).
|
|
105
|
+
* Reactions on a message (message-reactions.mjs) are display bookkeeping of
|
|
106
|
+
* the same kind, written in place mid-turn, and are left out with the id. */
|
|
105
107
|
export function withoutMessageIdsReplacer(key, value) {
|
|
106
108
|
if (key !== 'meta' || !value || typeof value !== 'object' || typeof value.transcript?.messageId !== 'string') {
|
|
107
109
|
return value;
|
|
108
110
|
}
|
|
109
|
-
const { messageId: _id, ...transcript } = value.transcript;
|
|
111
|
+
const { messageId: _id, reactions: _reactions, ...transcript } = value.transcript;
|
|
110
112
|
const meta = { ...value };
|
|
111
113
|
if (Object.keys(transcript).length) meta.transcript = transcript;
|
|
112
114
|
else delete meta.transcript;
|