mixdog 1.2.3 → 1.2.5
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/package.json +1 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/mobile-release.mjs +5 -4
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +128 -38
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/maintainer/AGENT.md +1 -1
- package/src/agents/maintainer/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -4
- package/src/agents/security/AGENT.md +1 -2
- package/src/agents/writer/AGENT.md +2 -3
- package/src/defaults/shipped-history.json +7 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/output-styles/common.md +2 -1
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +13 -13
- package/src/rules/shared/45-destructive.md +4 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- 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 +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
- package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
- package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +160 -212
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
- package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
- package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
- package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
- package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
- package/src/runtime/attachments/store.d.mts +9 -0
- package/src/runtime/attachments/store.mjs +80 -9
- package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
- package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
- package/src/runtime/computer-bridge/action-schema.mjs +178 -178
- package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
- package/src/runtime/effort-judge/judge-client.mjs +21 -4
- package/src/runtime/effort-judge/judge-worker.mjs +4 -1
- package/src/runtime/github/tool.mjs +118 -17
- package/src/runtime/media/adapters/codex-image.mjs +140 -21
- package/src/runtime/media/catalog.mjs +4 -4
- package/src/runtime/media/chatgpt-usage.mjs +55 -0
- package/src/runtime/media/defaults.mjs +37 -0
- package/src/runtime/media/jobs.mjs +12 -2
- package/src/runtime/media/lanes.mjs +12 -0
- package/src/runtime/media/tool-defs.mjs +15 -4
- package/src/runtime/media/tool.mjs +41 -12
- package/src/runtime/media/upstream-error.mjs +72 -6
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/html-browser.mjs +18 -8
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/session-search/session-search-ingest.mjs +1 -1
- package/src/runtime/shared/agent-reap-state.mjs +13 -0
- package/src/runtime/shared/atomic-file.d.mts +1 -1
- package/src/runtime/shared/background-tasks.mjs +6 -1
- package/src/runtime/shared/bounded-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/model-route-chain.d.mts +8 -0
- package/src/runtime/shared/model-route-chain.mjs +48 -0
- package/src/runtime/shared/model-route-fallback.mjs +22 -0
- package/src/runtime/shared/pid-liveness.mjs +12 -0
- package/src/runtime/shared/provider-api-key.mjs +6 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
- package/src/runtime/shared/quiet-progress.d.mts +35 -0
- package/src/runtime/shared/quiet-progress.mjs +101 -0
- package/src/runtime/shared/quota-resume-store.mjs +32 -1
- package/src/runtime/shared/read-row-numbers.mjs +44 -0
- package/src/runtime/shared/remote-intent.mjs +2 -42
- package/src/runtime/shared/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- package/src/runtime/shared/transcript-metadata.mjs +49 -1
- package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
- package/src/runtime/shared/worktrees/carry.mjs +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- package/src/runtime/shared/worktrees/include.mjs +125 -7
- package/src/runtime/shared/worktrees/lock.mjs +1 -1
- package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
- package/src/runtime/shared/worktrees/manager.mjs +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
- package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
- package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
- package/src/runtime/terminal-bridge/client.mjs +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
- package/src/session-runtime/lifecycle/shared.mjs +5 -6
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
- package/src/session-runtime/lifecycle/teardown.mjs +7 -16
- package/src/session-runtime/media-api.mjs +8 -0
- package/src/session-runtime/model-route/route-ownership.mjs +60 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -2
- package/src/session-runtime/model-route/set-route.mjs +114 -34
- package/src/session-runtime/model-route/web-search-route.mjs +7 -2
- package/src/session-runtime/model-route-api.mjs +4 -2
- package/src/session-runtime/native-web-search/routes.mjs +37 -24
- package/src/session-runtime/native-web-search.mjs +9 -8
- package/src/session-runtime/provider-auth/setup.mjs +4 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
- package/src/session-runtime/provider-models.mjs +1 -0
- package/src/session-runtime/provider-usage.mjs +4 -0
- package/src/session-runtime/route-resolution.mjs +3 -1
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +6 -0
- package/src/session-runtime/services/agent-task-status.mjs +2 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
- package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
- package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
- package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
- package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
- package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
- package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
- package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
- package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- package/src/session-runtime/session-create/session-options.mjs +7 -5
- package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
- package/src/session-runtime/workspace/admission-gate.mjs +44 -15
- package/src/session-runtime/workspace/project-branches.mjs +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/desktop-service-registry.mjs +32 -5
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
- package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
- package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
- package/src/standalone/session-service/agent-tree.mjs +28 -2
- package/src/standalone/session-service/entries/session-loads.mjs +16 -5
- package/src/standalone/session-service/entries.mjs +1 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
- package/src/standalone/session-service/quota-resume.mjs +28 -13
- package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/provider-setup/provider-items.mjs +8 -0
- package/src/tui/app/provider-setup-picker.mjs +15 -3
- package/src/tui/app/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +529 -270
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
- package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
- package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
- package/src/tui/session/quota-resume.mjs +140 -61
- package/src/tui/session/session-api/commands.mjs +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -11
- package/src/tui/session/session-api/media.mjs +2 -0
- package/src/tui/session/session-api/routes.mjs +81 -57
- package/src/tui/session/session-api/settings.mjs +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-flow/auto-clear.mjs +1 -3
- package/src/tui/session/session-flow/drain.mjs +6 -4
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
- package/src/tui/session/session-flow/queue.mjs +1 -1
- package/src/tui/session/tool-approval.mjs +17 -8
- package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
- package/src/tui/session/tui-steering-persist.mjs +3 -5
- package/src/tui/session/turn-quiet.mjs +53 -0
- package/src/tui/session/turn-stream.mjs +5 -1
- package/src/tui/session/turn.mjs +38 -31
- package/src/tui/session/worktree-setup-notice.mjs +38 -0
- package/src/tui/spinner-meta.mjs +10 -0
- package/src/tui/spinner-verbs.mjs +3 -0
- package/src/ui/statusline.mjs +13 -3
- package/src/ui/streaming-markdown-heal.mjs +70 -18
- package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
- package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
- package/src/session-runtime/turn/share-ops.mjs +0 -77
- package/src/tui/session/cross-surface-share.mjs +0 -406
- package/src/tui/session/live-share/delta.mjs +0 -153
- package/src/tui/session/live-share/mirror.mjs +0 -106
- package/src/tui/session/live-share/owner.mjs +0 -254
- package/src/tui/session/live-share/retry.mjs +0 -54
- package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
- package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
- package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
- package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
- package/src/tui/session/live-share/viewer.mjs +0 -99
- package/src/tui/session/live-share/wire.mjs +0 -44
- package/src/tui/session/live-share.mjs +0 -154
- package/src/tui/session/shared-dir-watch.mjs +0 -69
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tui/session/worktree-setup-notice.mjs - the one-line transcript notice
|
|
3
|
+
* shown while a new worktree's dependencies install (runtime.onWorktreeSetup).
|
|
4
|
+
* Only runs that install anything reach it; one notice per run, patched in
|
|
5
|
+
* place, so every surface showing the transcript (TUI, desktop, remote) sees
|
|
6
|
+
* the same line. The details (output, failures, skips) go to the agent only.
|
|
7
|
+
*/
|
|
8
|
+
const ENDINGS = {
|
|
9
|
+
completed: 'Worktree dependencies installed.',
|
|
10
|
+
cancelled: 'Installing worktree dependencies was cancelled.',
|
|
11
|
+
};
|
|
12
|
+
const INCOMPLETE = 'Some worktree dependencies were not installed; the agent has the details.';
|
|
13
|
+
|
|
14
|
+
/** Notice text and tone for one install progress event. */
|
|
15
|
+
export function worktreeSetupNotice(event) {
|
|
16
|
+
if (event.final) {
|
|
17
|
+
const text = ENDINGS[event.status] ?? INCOMPLETE;
|
|
18
|
+
return { text, tone: event.status === 'completed' ? 'info' : 'warn' };
|
|
19
|
+
}
|
|
20
|
+
const what = event.label || event.command;
|
|
21
|
+
return { text: `Installing worktree dependencies [${event.index + 1}/${event.total}]: ${what}`, tone: 'info' };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createWorktreeSetupNotices({ pushItem, patchItem, nextId }) {
|
|
25
|
+
const items = new Map();
|
|
26
|
+
return (event) => {
|
|
27
|
+
const notice = worktreeSetupNotice(event);
|
|
28
|
+
const itemId = items.get(event.id);
|
|
29
|
+
if (itemId === undefined) {
|
|
30
|
+
const id = nextId();
|
|
31
|
+
items.set(event.id, id);
|
|
32
|
+
pushItem({ kind: 'notice', id, ...notice });
|
|
33
|
+
} else {
|
|
34
|
+
patchItem(itemId, notice);
|
|
35
|
+
}
|
|
36
|
+
if (event.final) items.delete(event.id);
|
|
37
|
+
};
|
|
38
|
+
}
|
package/src/tui/spinner-meta.mjs
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* for 30s. One builder, one answer.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { quietProgressLabel, quietProgressParts } from '../runtime/shared/quiet-progress.mjs';
|
|
13
|
+
|
|
12
14
|
const compactNumberFormatter = new Intl.NumberFormat('en-US', {
|
|
13
15
|
notation: 'compact',
|
|
14
16
|
maximumFractionDigits: 1,
|
|
@@ -67,9 +69,13 @@ export function buildSpinnerMeta({
|
|
|
67
69
|
thinkingSince = 0,
|
|
68
70
|
thinkingMs = 0,
|
|
69
71
|
effort = '',
|
|
72
|
+
// The turn's published quiet state (`spinner.quiet`) and the clock it is read at.
|
|
73
|
+
quiet = null,
|
|
74
|
+
now = Date.now(),
|
|
70
75
|
verbose: _verbose = false,
|
|
71
76
|
} = {}) {
|
|
72
77
|
const tokens = Math.max(0, Number(outputTokens) || 0);
|
|
78
|
+
const quietParts = quietProgressParts(quiet, now, quiet?.warnMs);
|
|
73
79
|
const thinkingParts = spinnerThinkingParts({ thinking, thinkingSince, thinkingMs, effort });
|
|
74
80
|
const thinkingText = spinnerThinkingLabel({ thinking, thinkingSince, thinkingMs, effort });
|
|
75
81
|
return {
|
|
@@ -83,6 +89,10 @@ export function buildSpinnerMeta({
|
|
|
83
89
|
showTokens: tokens > 0,
|
|
84
90
|
thinkingText,
|
|
85
91
|
thinkingActive: Boolean(thinking || Number(thinkingSince) > 0),
|
|
92
|
+
// Quiet-time cue: structured for the desktop's i18n, English for the TUI;
|
|
93
|
+
// `escalated` once the silence reaches the stall watchdog's warn point.
|
|
94
|
+
quietParts,
|
|
95
|
+
quietText: quietProgressLabel(quietParts),
|
|
86
96
|
};
|
|
87
97
|
}
|
|
88
98
|
|
|
@@ -247,6 +247,9 @@ export const SPINNER_MODE_OVERRIDE_VERBS = {
|
|
|
247
247
|
'auto-clear': 'Auto-clearing conversation',
|
|
248
248
|
resuming: 'Resuming conversation',
|
|
249
249
|
'task-wait': '작업 대기 중',
|
|
250
|
+
// The request is sent and its response headers are pending: the model is
|
|
251
|
+
// queued or thinking server-side.
|
|
252
|
+
'model-thinking': 'Model thinking',
|
|
250
253
|
};
|
|
251
254
|
|
|
252
255
|
/**
|
package/src/ui/statusline.mjs
CHANGED
|
@@ -31,7 +31,11 @@ import {
|
|
|
31
31
|
num,
|
|
32
32
|
formatElapsed,
|
|
33
33
|
} from '../runtime/shared/statusline/statusline-format.mjs';
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
shellJobsStatus,
|
|
36
|
+
memoryCycleStatus,
|
|
37
|
+
unconfirmedShellCount,
|
|
38
|
+
} from '../runtime/shared/statusline/statusline-segments.mjs';
|
|
35
39
|
import {
|
|
36
40
|
agentStatuslinePayload,
|
|
37
41
|
classifyAgentWorkers,
|
|
@@ -397,10 +401,16 @@ function activitySegments({ sessionId, clientHostPid, agentWorkers, agentJobs, a
|
|
|
397
401
|
const n = runningWorkers.length;
|
|
398
402
|
segment(`Running ${n} Agent${n === 1 ? '' : 's'}`, agentsElapsed(runningWorkers));
|
|
399
403
|
}
|
|
400
|
-
|
|
401
|
-
|
|
404
|
+
const unconfirmed = unconfirmedShellCount(shellStatus);
|
|
405
|
+
if (shellStatus.count - unconfirmed > 0) {
|
|
406
|
+
const n = shellStatus.count - unconfirmed;
|
|
402
407
|
segment(`Running ${n} Shell${n === 1 ? '' : 's'}`, shellStatus.elapsedLabel);
|
|
403
408
|
}
|
|
409
|
+
if (unconfirmed > 0) {
|
|
410
|
+
parts.push(
|
|
411
|
+
`${YLW}⚠ ${unconfirmed} Shell${unconfirmed === 1 ? '' : 's'} termination unconfirmed${R} ${D}·${R} /shells`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
404
414
|
const webSearch = webSearchActivity(activeTools, { sessionId, clientHostPid });
|
|
405
415
|
if (webSearch.count > 0) segment('Web Searching', webSearch.elapsed);
|
|
406
416
|
// Memory cycle segment — single unified "Memory" wording for all states:
|
|
@@ -8,19 +8,47 @@ const HEALABLE_MARKDOWN_SYNTAX = /[`*_~[]/;
|
|
|
8
8
|
function openFence(text) {
|
|
9
9
|
let marker = '';
|
|
10
10
|
let length = 0;
|
|
11
|
+
let start = 0;
|
|
12
|
+
let lineStart = 0;
|
|
11
13
|
for (const rawLine of String(text ?? '').split('\n')) {
|
|
12
14
|
const fence = FENCE_LINE.exec(rawLine.replace(/\r$/, ''));
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
marker
|
|
20
|
-
|
|
15
|
+
if (fence) {
|
|
16
|
+
const marks = fence[1];
|
|
17
|
+
if (!marker) {
|
|
18
|
+
marker = marks[0];
|
|
19
|
+
length = marks.length;
|
|
20
|
+
start = lineStart;
|
|
21
|
+
} else if (marks[0] === marker && marks.length >= length && !fence[2].trim()) {
|
|
22
|
+
marker = '';
|
|
23
|
+
length = 0;
|
|
24
|
+
}
|
|
21
25
|
}
|
|
26
|
+
lineStart += rawLine.length + 1;
|
|
22
27
|
}
|
|
23
|
-
return marker ? { marker, length } : null;
|
|
28
|
+
return marker ? { marker, length, start } : null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The opening fence line arrives a token at a time: ``` → ```py → ```python.
|
|
32
|
+
// Rendered at once, the card opened unlabelled and then relabelled (and
|
|
33
|
+
// re-highlighted) per token. The card appears with its first code character:
|
|
34
|
+
// an opening line alone would paint an empty box before any code.
|
|
35
|
+
function trimPartialOpeningFence(text, fence) {
|
|
36
|
+
const lineEnd = text.indexOf('\n', fence.start);
|
|
37
|
+
return lineEnd >= 0 && /\S/.test(text.slice(lineEnd + 1)) ? text : text.slice(0, fence.start);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// A line holding only a block marker so far has no content to show, and the
|
|
41
|
+
// marker alone parses as something else: `-` or `=` under a paragraph is a
|
|
42
|
+
// setext underline (the paragraph flashed into a heading until the item text
|
|
43
|
+
// arrived), `2` is a lazy paragraph continuation until its `.` arrives, `#`
|
|
44
|
+
// grows into `##`, and a lone backtick run is literal text until it becomes a
|
|
45
|
+
// fence. Hold the line back until its first content character.
|
|
46
|
+
const PENDING_BLOCK_MARKER_LINE = /(?:^|\n)[ \t]*(?:[-+*=_#>~`]+|\d{1,9}[.)]?)[ \t]*$/;
|
|
47
|
+
|
|
48
|
+
function trimPendingBlockMarker(text) {
|
|
49
|
+
const pending = PENDING_BLOCK_MARKER_LINE.exec(text);
|
|
50
|
+
if (!pending) return text;
|
|
51
|
+
return text.slice(0, pending.index + (pending[0].startsWith('\n') ? 1 : 0));
|
|
24
52
|
}
|
|
25
53
|
|
|
26
54
|
// A closing fence arrives a token at a time. Until its run is long enough to
|
|
@@ -57,7 +85,9 @@ function closeInlineCode(text, isPendingLocalPath) {
|
|
|
57
85
|
} else if (run === open) open = 0;
|
|
58
86
|
index = end;
|
|
59
87
|
}
|
|
60
|
-
|
|
88
|
+
// An opener with nothing after it yet closes into an empty span, which
|
|
89
|
+
// parses as a literal backtick run that then vanishes into code.
|
|
90
|
+
if (open && (!text.slice(openIndex + open) || isPendingLocalPath?.(text.slice(openIndex + open)))) {
|
|
61
91
|
return text.slice(0, openIndex);
|
|
62
92
|
}
|
|
63
93
|
return open > 0 ? `${text}${'`'.repeat(open)}` : text;
|
|
@@ -93,6 +123,7 @@ function scanEmphasisRuns(masked) {
|
|
|
93
123
|
let end = index + 1;
|
|
94
124
|
while (masked[end] === marker) end += 1;
|
|
95
125
|
const length = end - index;
|
|
126
|
+
const at = index;
|
|
96
127
|
const before = index > 0 ? masked[index - 1] : '';
|
|
97
128
|
const after = end < masked.length ? masked[end] : '';
|
|
98
129
|
const beforeSpace = isMarkdownSpace(before);
|
|
@@ -102,16 +133,26 @@ function scanEmphasisRuns(masked) {
|
|
|
102
133
|
const left = !afterSpace && (!afterPunctuation || beforeSpace || beforePunctuation);
|
|
103
134
|
const right = !beforeSpace && (!beforePunctuation || afterSpace || afterPunctuation);
|
|
104
135
|
if (marker === '~') {
|
|
105
|
-
|
|
136
|
+
// A single tilde is inert, but at the end it may be half of `~~`.
|
|
137
|
+
runs.push({
|
|
138
|
+
marker,
|
|
139
|
+
length: Math.min(length, 2),
|
|
140
|
+
canOpen: left && length >= 2,
|
|
141
|
+
canClose: right && length >= 2,
|
|
142
|
+
at,
|
|
143
|
+
end,
|
|
144
|
+
});
|
|
106
145
|
} else if (marker === '_') {
|
|
107
146
|
runs.push({
|
|
108
147
|
marker,
|
|
109
148
|
length,
|
|
110
149
|
canOpen: left && (!right || beforePunctuation),
|
|
111
150
|
canClose: right && (!left || afterPunctuation),
|
|
151
|
+
at,
|
|
152
|
+
end,
|
|
112
153
|
});
|
|
113
154
|
} else {
|
|
114
|
-
runs.push({ marker, length, canOpen: left, canClose: right });
|
|
155
|
+
runs.push({ marker, length, canOpen: left, canClose: right, at, end });
|
|
115
156
|
}
|
|
116
157
|
index = end;
|
|
117
158
|
}
|
|
@@ -120,7 +161,9 @@ function scanEmphasisRuns(masked) {
|
|
|
120
161
|
|
|
121
162
|
function closeEmphasis(text) {
|
|
122
163
|
const open = [];
|
|
123
|
-
|
|
164
|
+
const runs = scanEmphasisRuns(maskCode(text));
|
|
165
|
+
const last = runs[runs.length - 1];
|
|
166
|
+
for (const run of runs) {
|
|
124
167
|
let length = run.length;
|
|
125
168
|
while (run.canClose && length > 0) {
|
|
126
169
|
let match = -1;
|
|
@@ -137,13 +180,21 @@ function closeEmphasis(text) {
|
|
|
137
180
|
length -= used;
|
|
138
181
|
open.length = opener.length > 0 ? match + 1 : match;
|
|
139
182
|
}
|
|
183
|
+
// A run ending the text that closed nothing has no content after it yet:
|
|
184
|
+
// it painted as literal `**` until the next token turned it into style.
|
|
185
|
+
if (run === last && run.end === text.length && length === run.length) {
|
|
186
|
+
return closeEmphasis(text.slice(0, run.at));
|
|
187
|
+
}
|
|
140
188
|
if (length > 0 && run.canOpen) open.push({ marker: run.marker, length });
|
|
141
189
|
}
|
|
142
|
-
|
|
190
|
+
// Closers go before trailing whitespace: `**word ` closed after the space
|
|
191
|
+
// could not close (a closing run must follow non-space) and stayed literal.
|
|
192
|
+
const body = text.trimEnd();
|
|
193
|
+
let closers = '';
|
|
143
194
|
for (let index = open.length - 1; index >= 0; index -= 1) {
|
|
144
|
-
|
|
195
|
+
closers += open[index].marker.repeat(Math.min(open[index].length, 3));
|
|
145
196
|
}
|
|
146
|
-
return
|
|
197
|
+
return closers ? `${body}${closers}${text.slice(body.length)}` : text;
|
|
147
198
|
}
|
|
148
199
|
|
|
149
200
|
function linkDestinationEnd(text, start) {
|
|
@@ -246,8 +297,9 @@ function trimPendingTableHead(text) {
|
|
|
246
297
|
export function healStreamingMarkdownTail(text, isPendingLocalPath) {
|
|
247
298
|
const source = String(text ?? '');
|
|
248
299
|
const fence = source.includes('`') || source.includes('~') ? openFence(source) : null;
|
|
249
|
-
if (fence) return trimPartialClosingFence(source, fence);
|
|
250
|
-
const
|
|
300
|
+
if (fence) return trimPartialOpeningFence(trimPartialClosingFence(source, fence), fence);
|
|
301
|
+
const unmarked = trimPendingBlockMarker(source);
|
|
302
|
+
const value = unmarked.includes('|') ? trimPendingTableHead(unmarked) : unmarked;
|
|
251
303
|
const hasSyntax = HEALABLE_MARKDOWN_SYNTAX.test(value);
|
|
252
304
|
if (!value || (!hasSyntax && !isPendingLocalPath)) return value;
|
|
253
305
|
const healed = hasSyntax
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../../../shared/llm/model-pricing-rates.mjs';
|
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import { stat } from 'node:fs/promises';
|
|
2
|
-
import { isProcessAlive } from '../store/paths-heartbeat.mjs';
|
|
3
|
-
import {
|
|
4
|
-
isCompletionNotificationEntry,
|
|
5
|
-
isStaleUserInjection,
|
|
6
|
-
lateDeliveryText,
|
|
7
|
-
normalizePendingMessageEntry,
|
|
8
|
-
pendingMessageId,
|
|
9
|
-
pendingMessageText,
|
|
10
|
-
} from './pending-message-entry.mjs';
|
|
11
|
-
import { isInternalRuntimeNotificationText } from './prompt-utils.mjs';
|
|
12
|
-
import { lifecycleTokenClosed } from './pending-lifecycle-epoch.mjs';
|
|
13
|
-
|
|
14
|
-
const HANDOFF_RETRY_MS = 1000;
|
|
15
|
-
const HANDOFF_RELEASE_SLACK_MS = 50;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* One session's spool queue, split into what this process takes and what stays
|
|
19
|
-
* on disk. A foreign user message is taken (and parked with a handoff stamp
|
|
20
|
-
* until the consumer owns a copy); an entry already handed off stays until its
|
|
21
|
-
* release window expires or its owner is gone; everything else is kept.
|
|
22
|
-
*
|
|
23
|
-
* Appends to `request.taken` / `request.released`, tightens
|
|
24
|
-
* `request.rescanDueAt` to the earliest live handoff deadline, and returns the
|
|
25
|
-
* entries the queue keeps.
|
|
26
|
-
*/
|
|
27
|
-
function takeForeignMessagesFromQueue(queue, request, handoffReleaseMs) {
|
|
28
|
-
const now = Date.now();
|
|
29
|
-
const kept = [];
|
|
30
|
-
for (const entry of queue) {
|
|
31
|
-
const id = pendingMessageId(entry);
|
|
32
|
-
const handoffAt = Number(entry?.handoffAt) || 0;
|
|
33
|
-
const handoffPid = Number(entry?.handoffPid) || 0;
|
|
34
|
-
if (handoffAt > 0) {
|
|
35
|
-
const dueAt = handoffAt + handoffReleaseMs;
|
|
36
|
-
const expired = now >= dueAt;
|
|
37
|
-
if (!expired) {
|
|
38
|
-
request.rescanDueAt = request.rescanDueAt === 0 ? dueAt : Math.min(request.rescanDueAt, dueAt);
|
|
39
|
-
}
|
|
40
|
-
if (handoffPid === process.pid) {
|
|
41
|
-
if (expired) {
|
|
42
|
-
if (id) request.released.push(id);
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
kept.push(entry);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (!expired || isProcessAlive(handoffPid)) {
|
|
49
|
-
kept.push(entry);
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
const text = pendingMessageText(entry);
|
|
54
|
-
const foreignUser =
|
|
55
|
-
id &&
|
|
56
|
-
!request.localIds.has(id) &&
|
|
57
|
-
!isCompletionNotificationEntry(entry) &&
|
|
58
|
-
text &&
|
|
59
|
-
!isInternalRuntimeNotificationText(text);
|
|
60
|
-
if (!foreignUser) {
|
|
61
|
-
kept.push(entry);
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
const normalized = normalizePendingMessageEntry(entry);
|
|
65
|
-
const structured = Array.isArray(normalized?.content) || Boolean(normalized?.options);
|
|
66
|
-
let takenText = text;
|
|
67
|
-
let content = normalized?.content ?? text;
|
|
68
|
-
if (isStaleUserInjection(entry)) {
|
|
69
|
-
takenText = lateDeliveryText(text, entry);
|
|
70
|
-
content = Array.isArray(normalized?.content)
|
|
71
|
-
? [{ type: 'text', text: takenText.slice(0, takenText.length - text.length) }, ...normalized.content]
|
|
72
|
-
: takenText;
|
|
73
|
-
}
|
|
74
|
-
request.taken.push({
|
|
75
|
-
...(structured ? { content } : {}),
|
|
76
|
-
text: takenText,
|
|
77
|
-
id,
|
|
78
|
-
...(normalized?.options ? { options: normalized.options } : {}),
|
|
79
|
-
});
|
|
80
|
-
// Park rather than delete until the consumer owns a copy.
|
|
81
|
-
kept.push({ ...entry, handoffAt: now, handoffPid: process.pid });
|
|
82
|
-
}
|
|
83
|
-
return kept;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Owns cross-process pending-message polling and the durable two-phase handoff.
|
|
88
|
-
* Queue storage and lifecycle authority stay in the parent pending-message
|
|
89
|
-
* service and are supplied as narrow callbacks.
|
|
90
|
-
*/
|
|
91
|
-
export class ForeignPendingMessageController {
|
|
92
|
-
constructor(dependencies) {
|
|
93
|
-
this._dependencies = dependencies;
|
|
94
|
-
this._scanLimit = Math.max(128, Number(process.env.MIXDOG_FOREIGN_SPOOL_SCAN_LIMIT) || 512);
|
|
95
|
-
this._handoffReleaseMs = Math.max(1000, Number(process.env.MIXDOG_FOREIGN_HANDOFF_RELEASE_MS) || 10000);
|
|
96
|
-
this._releaseTimers = new Map();
|
|
97
|
-
this._drainRequests = new Map();
|
|
98
|
-
this._scanMemo = new Map();
|
|
99
|
-
this._drainScheduled = false;
|
|
100
|
-
this._drainRunning = false;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
cancelHandoffRelease(sessionId) {
|
|
104
|
-
const existing = this._releaseTimers.get(sessionId);
|
|
105
|
-
if (existing) {
|
|
106
|
-
try {
|
|
107
|
-
clearTimeout(existing.timer);
|
|
108
|
-
} catch {
|
|
109
|
-
/* best-effort */
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
this._releaseTimers.delete(sessionId);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async drainUserInjections(sessionId) {
|
|
116
|
-
const { currentLifecycleToken, isValidSessionId } = this._dependencies;
|
|
117
|
-
if (!isValidSessionId(sessionId)) return [];
|
|
118
|
-
// One durable read decides both the epoch and the tombstone refusal.
|
|
119
|
-
const epochToken = currentLifecycleToken(sessionId);
|
|
120
|
-
if (lifecycleTokenClosed(epochToken)) return [];
|
|
121
|
-
return new Promise((resolve) => {
|
|
122
|
-
const existing = this._drainRequests.get(sessionId);
|
|
123
|
-
if (existing && existing.epochToken === epochToken) {
|
|
124
|
-
existing.waiters.push(resolve);
|
|
125
|
-
} else {
|
|
126
|
-
if (existing) this._settleDrain(existing, []);
|
|
127
|
-
this._drainRequests.set(sessionId, {
|
|
128
|
-
sessionId,
|
|
129
|
-
epochToken,
|
|
130
|
-
waiters: [resolve],
|
|
131
|
-
localIds: null,
|
|
132
|
-
taken: [],
|
|
133
|
-
released: [],
|
|
134
|
-
rescanDueAt: 0,
|
|
135
|
-
lifecycleDecided: false,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
this._scheduleDrainBatch();
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
_scheduleHandoffRelease(sessionId, delayMs = this._handoffReleaseMs) {
|
|
143
|
-
const { isValidSessionId } = this._dependencies;
|
|
144
|
-
if (!isValidSessionId(sessionId)) return;
|
|
145
|
-
const delay = Math.max(1, Number(delayMs) || 0);
|
|
146
|
-
const dueAt = Date.now() + delay;
|
|
147
|
-
const existing = this._releaseTimers.get(sessionId);
|
|
148
|
-
if (existing) {
|
|
149
|
-
if (existing.dueAt <= dueAt) return;
|
|
150
|
-
try {
|
|
151
|
-
clearTimeout(existing.timer);
|
|
152
|
-
} catch {
|
|
153
|
-
/* best-effort */
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
const timer = setTimeout(() => {
|
|
157
|
-
this._releaseTimers.delete(sessionId);
|
|
158
|
-
void this._releaseExpiredHandoffs(sessionId);
|
|
159
|
-
}, delay);
|
|
160
|
-
// The row is durable; cleanup must not keep a shutting-down process open.
|
|
161
|
-
try {
|
|
162
|
-
timer.unref?.();
|
|
163
|
-
} catch {
|
|
164
|
-
/* ignore */
|
|
165
|
-
}
|
|
166
|
-
this._releaseTimers.set(sessionId, { timer, dueAt });
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
_releaseExpiredHandoffs(sessionId) {
|
|
170
|
-
const {
|
|
171
|
-
chainSpoolTail,
|
|
172
|
-
currentLifecycleToken,
|
|
173
|
-
getSpoolTail,
|
|
174
|
-
isValidSessionId,
|
|
175
|
-
lifecycleEpochMoved,
|
|
176
|
-
normalizeStore,
|
|
177
|
-
removeInDeliveryIds,
|
|
178
|
-
setSpoolQueue,
|
|
179
|
-
updateSpool,
|
|
180
|
-
warn,
|
|
181
|
-
} = this._dependencies;
|
|
182
|
-
if (!isValidSessionId(sessionId)) return Promise.resolve(0);
|
|
183
|
-
const epochToken = currentLifecycleToken(sessionId);
|
|
184
|
-
const released = [];
|
|
185
|
-
let nextDueIn = 0;
|
|
186
|
-
const preceding = getSpoolTail(sessionId) || Promise.resolve();
|
|
187
|
-
const operation = preceding
|
|
188
|
-
.catch(() => {})
|
|
189
|
-
.then(() =>
|
|
190
|
-
updateSpool(sessionId, (raw) => {
|
|
191
|
-
released.length = 0;
|
|
192
|
-
nextDueIn = 0;
|
|
193
|
-
// A generation move transfers ownership; never clean the new queue.
|
|
194
|
-
if (lifecycleEpochMoved(sessionId, epochToken)) return undefined;
|
|
195
|
-
const next = normalizeStore(raw);
|
|
196
|
-
const queue = Array.isArray(next.sessions[sessionId]) ? next.sessions[sessionId] : [];
|
|
197
|
-
if (queue.length === 0) return undefined;
|
|
198
|
-
const now = Date.now();
|
|
199
|
-
const kept = [];
|
|
200
|
-
for (const entry of queue) {
|
|
201
|
-
const handoffAt = Number(entry?.handoffAt) || 0;
|
|
202
|
-
const handoffPid = Number(entry?.handoffPid) || 0;
|
|
203
|
-
if (handoffAt > 0 && handoffPid === process.pid) {
|
|
204
|
-
const remaining = this._handoffReleaseMs - (now - handoffAt);
|
|
205
|
-
if (remaining <= 0) {
|
|
206
|
-
const id = pendingMessageId(entry);
|
|
207
|
-
if (id) released.push(id);
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
|
-
nextDueIn = nextDueIn === 0 ? remaining : Math.min(nextDueIn, remaining);
|
|
211
|
-
}
|
|
212
|
-
kept.push(entry);
|
|
213
|
-
}
|
|
214
|
-
if (released.length === 0) return undefined;
|
|
215
|
-
setSpoolQueue(next, sessionId, kept);
|
|
216
|
-
next.updatedAt = now;
|
|
217
|
-
return next;
|
|
218
|
-
})
|
|
219
|
-
)
|
|
220
|
-
.then(() => {
|
|
221
|
-
if (released.length > 0) removeInDeliveryIds(sessionId, released);
|
|
222
|
-
if (nextDueIn > 0) {
|
|
223
|
-
this._scheduleHandoffRelease(sessionId, nextDueIn + HANDOFF_RELEASE_SLACK_MS);
|
|
224
|
-
}
|
|
225
|
-
return released.length;
|
|
226
|
-
})
|
|
227
|
-
.catch((err) => {
|
|
228
|
-
warn(`[session] foreign-injection handoff release failed sessionId=${sessionId}: ${err?.message || err}\n`);
|
|
229
|
-
// The rows remain durable, so contention and I/O failures retry.
|
|
230
|
-
this._scheduleHandoffRelease(sessionId, HANDOFF_RETRY_MS);
|
|
231
|
-
return 0;
|
|
232
|
-
});
|
|
233
|
-
return chainSpoolTail(sessionId, operation);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
_rememberScan(sessionId, mtime, rescanDueAt) {
|
|
237
|
-
this._scanMemo.delete(sessionId);
|
|
238
|
-
this._scanMemo.set(sessionId, { mtime, rescanDueAt: Number(rescanDueAt) || 0 });
|
|
239
|
-
while (this._scanMemo.size > this._scanLimit) {
|
|
240
|
-
const oldest = this._scanMemo.keys().next().value;
|
|
241
|
-
if (oldest === undefined) break;
|
|
242
|
-
this._scanMemo.delete(oldest);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
_scanNeeded(sessionId, mtime, now) {
|
|
247
|
-
const memo = this._scanMemo.get(sessionId);
|
|
248
|
-
if (!memo || memo.mtime !== mtime) return true;
|
|
249
|
-
return memo.rescanDueAt > 0 && now >= memo.rescanDueAt;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
_settleDrain(request, value) {
|
|
253
|
-
for (const resolve of request.waiters) {
|
|
254
|
-
try {
|
|
255
|
-
resolve(value);
|
|
256
|
-
} catch {
|
|
257
|
-
/* a consumer cannot break the batch */
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
_scheduleDrainBatch() {
|
|
263
|
-
if (this._drainScheduled || this._drainRunning || this._drainRequests.size === 0) return;
|
|
264
|
-
this._drainScheduled = true;
|
|
265
|
-
setImmediate(() => {
|
|
266
|
-
this._drainScheduled = false;
|
|
267
|
-
void this._flushDrainBatch();
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
async _flushDrainBatch() {
|
|
272
|
-
if (this._drainRunning) return;
|
|
273
|
-
this._drainRunning = true;
|
|
274
|
-
const batch = [...this._drainRequests.values()];
|
|
275
|
-
this._drainRequests.clear();
|
|
276
|
-
try {
|
|
277
|
-
// Each session drains against its own shard and lock, so one busy
|
|
278
|
-
// session never delays (or fails) another's intake.
|
|
279
|
-
await Promise.all(batch.map((request) => this._drainOne(request)));
|
|
280
|
-
} finally {
|
|
281
|
-
this._drainRunning = false;
|
|
282
|
-
this._scheduleDrainBatch();
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async _drainOne(request) {
|
|
287
|
-
const {
|
|
288
|
-
addInDeliveryIds,
|
|
289
|
-
lifecycleInvalidated,
|
|
290
|
-
localIds,
|
|
291
|
-
normalizeStore,
|
|
292
|
-
removeInDeliveryIds,
|
|
293
|
-
setSpoolQueue,
|
|
294
|
-
spoolPath,
|
|
295
|
-
updateSpool,
|
|
296
|
-
warn,
|
|
297
|
-
} = this._dependencies;
|
|
298
|
-
const { sessionId, epochToken } = request;
|
|
299
|
-
try {
|
|
300
|
-
let mtime = 0;
|
|
301
|
-
try {
|
|
302
|
-
mtime = (await stat(spoolPath(sessionId))).mtimeMs || 0;
|
|
303
|
-
} catch {
|
|
304
|
-
this._settleDrain(request, []);
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
if (!this._scanNeeded(sessionId, mtime, Date.now()) || lifecycleInvalidated(sessionId, epochToken)) {
|
|
308
|
-
this._settleDrain(request, []);
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
request.localIds = localIds(sessionId);
|
|
312
|
-
request.taken = [];
|
|
313
|
-
request.released = [];
|
|
314
|
-
request.rescanDueAt = 0;
|
|
315
|
-
request.lifecycleDecided = false;
|
|
316
|
-
await updateSpool(
|
|
317
|
-
sessionId,
|
|
318
|
-
(raw) => {
|
|
319
|
-
const next = normalizeStore(raw);
|
|
320
|
-
if (lifecycleInvalidated(sessionId, epochToken)) return undefined;
|
|
321
|
-
request.lifecycleDecided = true;
|
|
322
|
-
const queue = Array.isArray(next.sessions[sessionId]) ? next.sessions[sessionId] : [];
|
|
323
|
-
if (queue.length === 0) return undefined;
|
|
324
|
-
const kept = takeForeignMessagesFromQueue(queue, request, this._handoffReleaseMs);
|
|
325
|
-
if (request.taken.length === 0 && request.released.length === 0) return undefined;
|
|
326
|
-
setSpoolQueue(next, sessionId, kept);
|
|
327
|
-
next.updatedAt = Date.now();
|
|
328
|
-
return next;
|
|
329
|
-
},
|
|
330
|
-
{ timeoutMs: 0 }
|
|
331
|
-
);
|
|
332
|
-
if (request.lifecycleDecided) this._rememberScan(sessionId, mtime, request.rescanDueAt);
|
|
333
|
-
if (request.taken.length > 0) {
|
|
334
|
-
addInDeliveryIds(sessionId, request.taken.map((item) => item?.id).filter(Boolean));
|
|
335
|
-
this._scheduleHandoffRelease(sessionId, this._handoffReleaseMs + HANDOFF_RELEASE_SLACK_MS);
|
|
336
|
-
}
|
|
337
|
-
if (request.released.length > 0) removeInDeliveryIds(sessionId, request.released);
|
|
338
|
-
this._settleDrain(request, request.taken);
|
|
339
|
-
} catch (err) {
|
|
340
|
-
if (err?.code !== 'ELOCKCONTENDED') {
|
|
341
|
-
warn(`[session] foreign-injection drain failed: ${err?.message || err}\n`);
|
|
342
|
-
}
|
|
343
|
-
this._settleDrain(request, []);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|