mixdog 0.9.95 → 0.9.97
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/Apache-2.0.txt +201 -0
- package/LICENSES/MIT.txt +56 -0
- package/LICENSES/codex-NOTICE.txt +6 -0
- package/NOTICE.md +46 -9
- package/README.md +0 -17
- package/package.json +16 -12
- package/scripts/.tmp-coverage-report.mjs +96 -0
- package/scripts/build-tui.mjs +17 -1
- package/scripts/{channel-daemon-stub.mjs → daemon-stub.mjs} +18 -12
- package/scripts/fixtures/patch-replay-corpus.json +98 -0
- package/src/defaults/mixdog-config.template.json +5 -8
- package/src/defaults/skills/setup/SKILL.md +1 -1
- package/src/lib/keychain-cjs.cjs +1 -1
- package/src/lib/mixdog-debug.cjs +2 -3
- package/src/rules/agent/30-explorer.md +7 -4
- package/src/rules/lead/01-general.md +1 -2
- package/src/rules/lead/lead-tool.md +0 -3
- package/src/rules/shared/01-tool.md +21 -29
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +31 -1
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +6 -17
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +12 -1
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +4 -13
- package/src/runtime/agent/orchestrator/config.mjs +246 -67
- package/src/runtime/agent/orchestrator/mcp/client.mjs +104 -41
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +23 -0
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +113 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +32 -11
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +89 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +144 -39
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +22 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/openai-transport-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +3 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +3 -6
- package/src/runtime/agent/orchestrator/providers/registry.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +67 -7
- package/src/runtime/agent/orchestrator/providers/stream-json-pool.mjs +291 -0
- package/src/runtime/agent/orchestrator/providers/stream-json-worker.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +36 -10
- package/src/runtime/agent/orchestrator/session/compact.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +22 -33
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +0 -24
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +21 -29
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +7 -10
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +45 -25
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +142 -84
- package/src/runtime/agent/orchestrator/session/manager/prefetch-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/session/manager/runtime-loaders.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +31 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +38 -2
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +29 -9
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +86 -8
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +71 -42
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +4 -33
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -5
- package/src/runtime/agent/orchestrator/stall-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +35 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +116 -26
- package/src/runtime/agent/orchestrator/tools/builtin/binary-file.mjs +92 -19
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +8 -9
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/fs-reachability.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +6 -15
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +12 -26
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -33
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +42 -45
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +27 -9
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +7 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +17 -39
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +73 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +0 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +3 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +30 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +142 -26
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +47 -19
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/env-scrub.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/lib/pwsh-standby-pool.mjs +83 -13
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +39 -1
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +94 -20
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +16 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +108 -12
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +12 -11
- package/src/runtime/agent/orchestrator/tools/patch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +63 -9
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +2 -2
- package/src/runtime/channels/lib/config.mjs +34 -34
- package/src/runtime/channels/lib/inbound-handler.mjs +8 -8
- package/src/runtime/channels/lib/interaction-handlers.mjs +6 -6
- package/src/runtime/channels/lib/memory-client.mjs +31 -157
- package/src/runtime/channels/lib/output-forwarder.mjs +16 -16
- package/src/runtime/channels/lib/owned-runtime.mjs +60 -60
- package/src/runtime/channels/lib/owner-heartbeat.mjs +1 -1
- package/src/runtime/channels/lib/{backend-dispatch.mjs → provider-dispatch.mjs} +6 -6
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -30
- package/src/runtime/channels/lib/scheduler.mjs +2 -2
- package/src/runtime/channels/lib/status-snapshot.mjs +3 -3
- package/src/runtime/channels/lib/tool-dispatch.mjs +4 -4
- package/src/runtime/channels/lib/worker-bootstrap.mjs +1 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +7 -7
- package/src/runtime/channels/lib/worker-main.mjs +38 -38
- package/src/runtime/channels/{backends → providers}/discord-access.mjs +1 -1
- package/src/runtime/channels/{backends → providers}/discord-gateway.mjs +1 -1
- package/src/runtime/channels/{backends → providers}/discord.mjs +3 -3
- package/src/runtime/channels/{backends → providers}/telegram.mjs +12 -12
- package/src/runtime/channels/tool-defs.mjs +1 -1
- package/src/runtime/memory/index.mjs +76 -248
- package/src/runtime/memory/lib/agent-ipc.mjs +146 -81
- package/src/runtime/memory/lib/compact-vector-cache.mjs +88 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +18 -1
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +13 -34
- package/src/runtime/memory/lib/embedding-provider.mjs +47 -26
- package/src/runtime/memory/lib/embedding-worker.mjs +30 -34
- package/src/runtime/memory/lib/http-router.mjs +9 -6
- package/src/runtime/memory/lib/ko-morph.mjs +3 -20
- package/src/runtime/memory/lib/memory-action-handlers.mjs +2 -1
- package/src/runtime/memory/lib/memory-config-flags.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -0
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +4 -2
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +1 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +4 -1
- package/src/runtime/memory/lib/memory-cycle3.mjs +3 -1
- package/src/runtime/memory/lib/memory-daemon-lifecycle.mjs +5 -0
- package/src/runtime/memory/lib/memory-log.mjs +1 -1
- package/src/runtime/memory/lib/memory-process-lock.mjs +5 -60
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/pg/process.mjs +32 -9
- package/src/runtime/memory/lib/session-ingest.mjs +1 -1
- package/src/runtime/memory/tool-defs.mjs +1 -5
- package/src/runtime/search/index.mjs +2 -2
- package/src/runtime/search/tool-defs.mjs +2 -2
- package/src/runtime/shared/abort-race.mjs +70 -0
- package/src/runtime/shared/agent-route-config.mjs +119 -0
- package/src/runtime/shared/atomic-file.mjs +80 -4
- package/src/runtime/shared/channel-notification-routing.mjs +2 -2
- package/src/runtime/shared/child-guardian.mjs +204 -108
- package/src/runtime/shared/child-spawn-gate.mjs +139 -72
- package/src/runtime/shared/config.mjs +120 -47
- package/src/runtime/shared/llm/index.mjs +1 -1
- package/src/runtime/shared/owner-fair-gate.mjs +134 -0
- package/src/runtime/shared/resource-admission.mjs +150 -100
- package/src/runtime/shared/stream-progress.mjs +6 -0
- package/src/runtime/shared/tool-execution-owner.mjs +12 -0
- package/src/runtime/shared/tool-result-summary.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +91 -27
- package/src/runtime/shared/tool-workload-gates.mjs +29 -0
- package/src/runtime/shared/turn-snapshot.mjs +47 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +14 -2
- package/src/session-runtime/channel-config-api.mjs +5 -5
- package/src/session-runtime/config-helpers.mjs +39 -37
- package/src/session-runtime/config-lifecycle.mjs +27 -27
- package/src/session-runtime/lifecycle-api.mjs +22 -3
- package/src/session-runtime/memory-runtime-prewarm.mjs +15 -0
- package/src/session-runtime/model-route-api.mjs +7 -5
- package/src/session-runtime/prewarm.mjs +1 -1
- package/src/session-runtime/provider-auth-api.mjs +0 -7
- package/src/session-runtime/provider-models.mjs +1 -1
- package/src/session-runtime/remote-control.mjs +6 -7
- package/src/session-runtime/runtime-core.mjs +63 -39
- package/src/session-runtime/runtime-tunables.mjs +4 -4
- package/src/session-runtime/self-update.mjs +1 -1
- package/src/session-runtime/session-lifecycle.mjs +45 -17
- package/src/session-runtime/session-title.mjs +1 -1
- package/src/session-runtime/session-turn-api.mjs +96 -24
- package/src/session-runtime/settings-api.mjs +12 -24
- package/src/session-runtime/tool-defs.mjs +3 -3
- package/src/session-runtime/workflow-agents-api.mjs +55 -81
- package/src/session-runtime/workflow.mjs +14 -24
- package/src/standalone/agent-dispatch-broker.mjs +198 -0
- package/src/standalone/agent-tool/helpers.mjs +2 -2
- package/src/standalone/agent-tool/spawn-flow.mjs +2 -0
- package/src/standalone/agent-tool/spawn-preset.mjs +11 -21
- package/src/standalone/agent-tool/tool-def.mjs +0 -14
- package/src/standalone/channel-admin.mjs +53 -64
- package/src/standalone/{channel-daemon-client.mjs → channel-client.mjs} +33 -19
- package/src/standalone/{channel-daemon-transport.mjs → channel-transport.mjs} +127 -46
- package/src/standalone/channel-worker.mjs +124 -647
- package/src/standalone/{backend-daemon.mjs → daemon.mjs} +270 -154
- package/src/standalone/explore-tool.mjs +187 -70
- package/src/standalone/fair-call-scheduler.mjs +264 -0
- package/src/standalone/memory-runtime-proxy.mjs +58 -1
- package/src/standalone/session-client.mjs +1134 -0
- package/src/standalone/session-protocol.mjs +192 -0
- package/src/standalone/session-runtime-pool.mjs +393 -0
- package/src/standalone/session-runtime-record.mjs +20 -0
- package/src/standalone/session-runtime-worker.mjs +203 -0
- package/src/standalone/{engine-daemon-service.mjs → session-service.mjs} +481 -224
- package/src/standalone/{engine-daemon-transport.mjs → session-transport.mjs} +390 -121
- package/src/standalone/session-wire.mjs +55 -0
- package/src/tui/App.jsx +34 -21
- package/src/tui/app/app-format.mjs +1 -1
- package/src/tui/app/app-view.jsx +5 -2
- package/src/tui/app/channel-pickers.mjs +41 -41
- package/src/tui/app/core-memory-picker.mjs +19 -19
- package/src/tui/app/doctor.mjs +5 -11
- package/src/tui/app/input-parsers.mjs +2 -2
- package/src/tui/app/message-selector.mjs +103 -0
- package/src/tui/app/onboarding-steps.mjs +3 -4
- package/src/tui/app/project-picker.mjs +80 -56
- package/src/tui/app/prompt-submit.mjs +48 -43
- package/src/tui/app/resume-picker.mjs +2 -2
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker.mjs +31 -33
- package/src/tui/app/transcript-window.mjs +38 -0
- package/src/tui/app/use-prompt-draft-flow.mjs +5 -7
- package/src/tui/app/use-prompt-handlers.mjs +86 -21
- package/src/tui/app/use-prompt-hint.mjs +3 -2
- package/src/tui/app/use-prompt-queue-history.mjs +10 -3
- package/src/tui/app/use-transcript-scroll.mjs +10 -3
- package/src/tui/app/use-transcript-window.mjs +50 -17
- package/src/tui/components/PromptInput.jsx +71 -38
- package/src/tui/components/Spinner.jsx +1 -1
- package/src/tui/components/ToolExecution.jsx +1 -1
- package/src/tui/components/prompt-input/edit-helpers.mjs +9 -11
- package/src/tui/components/prompt-input/escape-policy.mjs +42 -0
- package/src/tui/components/prompt-input/immediate-render.mjs +0 -10
- package/src/tui/components/prompt-input/interrupt-policy.mjs +10 -0
- package/src/tui/components/prompt-input/restore-policy.mjs +10 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +1 -1
- package/src/tui/dist/index.mjs +1031 -1676
- package/src/tui/hooks/useSession.mjs +16 -0
- package/src/tui/index.jsx +12 -13
- package/src/tui/{engine → session}/agent-envelope.mjs +3 -3
- package/src/tui/{engine → session}/agent-job-feed.mjs +4 -4
- package/src/tui/{engine → session}/boot-profile.mjs +2 -2
- package/src/tui/{engine → session}/context-state.mjs +3 -3
- package/src/tui/{engine → session}/labels.mjs +2 -2
- package/src/tui/{engine → session}/live-share.mjs +38 -4
- package/src/tui/{engine → session}/notice-text.mjs +2 -2
- package/src/tui/{engine → session}/notification-plan.mjs +3 -3
- package/src/tui/session/oauth-flows.mjs +140 -0
- package/src/tui/{engine → session}/prompt-history.mjs +3 -3
- package/src/tui/{engine → session}/queue-helpers.mjs +2 -2
- package/src/tui/{engine → session}/render-timing.mjs +2 -2
- package/src/tui/{engine → session}/session-api-ext.mjs +30 -20
- package/src/tui/{engine → session}/session-api.mjs +110 -93
- package/src/tui/{engine → session}/session-flow.mjs +8 -2
- package/src/tui/{engine → session}/session-stats.mjs +3 -3
- package/src/tui/{engine → session}/tool-approval.mjs +3 -3
- package/src/tui/{engine → session}/tool-call-fields.mjs +2 -2
- package/src/tui/{engine → session}/tool-card-results.mjs +8 -6
- package/src/tui/{engine → session}/tool-result-status.mjs +5 -5
- package/src/tui/{engine → session}/tool-result-text.mjs +13 -3
- package/src/tui/{engine → session}/transcript-spill.mjs +34 -34
- package/src/tui/{engine → session}/turn.mjs +38 -176
- package/src/tui/{engine-local-session.mjs → session-local.mjs} +103 -103
- package/src/tui/session.mjs +22 -0
- package/src/tui/spinner-meta.mjs +4 -4
- package/src/tui/spinner-verbs.mjs +51 -3
- package/src/ui/statusline-segments.mjs +1 -1
- package/src/ui/statusline.mjs +1 -1
- package/vendor/ink/build/components/App.js +10 -1
- package/src/session-runtime/memory-daemon-probe.mjs +0 -61
- package/src/standalone/engine-daemon-client.mjs +0 -894
- package/src/standalone/engine-daemon-local-bridge.mjs +0 -20
- package/src/standalone/engine-daemon-protocol.mjs +0 -33
- package/src/tui/engine/turn-watchdog.mjs +0 -92
- package/src/tui/engine.mjs +0 -22
- package/src/tui/hooks/useEngine.mjs +0 -16
- /package/src/runtime/agent/orchestrator/session/compact/{engine.mjs → runner.mjs} +0 -0
- /package/src/runtime/channels/{backends → providers}/discord-attachments.mjs +0 -0
- /package/src/tui/{engine → session}/agent-response-tail.mjs +0 -0
- /package/src/tui/{engine → session}/frame-batched-store.mjs +0 -0
- /package/src/tui/{engine → session}/tui-steering-persist.mjs +0 -0
|
@@ -3,6 +3,7 @@ import { createSessionTitleController } from './session-title.mjs';
|
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
|
|
5
5
|
import { performance } from 'node:perf_hooks';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import keychain from '../lib/keychain-cjs.cjs';
|
|
7
8
|
import './hitch-profile.mjs';
|
|
8
9
|
import { ensureStandaloneEnvironment } from '../standalone/seeds.mjs';
|
|
@@ -10,8 +11,8 @@ import { createStandaloneAgent } from '../standalone/agent-tool.mjs';
|
|
|
10
11
|
import { isAgentOwner } from '../runtime/agent/orchestrator/agent-owner.mjs';
|
|
11
12
|
import { EXPLORE_TOOL, runExplore } from '../standalone/explore-tool.mjs';
|
|
12
13
|
import { createStandaloneChannelWorker } from '../standalone/channel-worker.mjs';
|
|
13
|
-
import { createStandaloneMemoryRuntime } from '../standalone/memory-runtime-proxy.mjs';
|
|
14
14
|
import { createStandaloneHookBus } from '../standalone/hook-bus.mjs';
|
|
15
|
+
import { getStandaloneMemoryRuntime } from '../standalone/memory-runtime-proxy.mjs';
|
|
15
16
|
import { createRemoteTransitionQueue } from './remote-transition-queue.mjs';
|
|
16
17
|
import { writeLastSessionCwd } from '../runtime/shared/user-cwd.mjs';
|
|
17
18
|
import { cancelBackgroundTasks } from '../runtime/shared/background-tasks.mjs';
|
|
@@ -67,8 +68,8 @@ import {
|
|
|
67
68
|
saveTelegramToken,
|
|
68
69
|
saveSchedule,
|
|
69
70
|
saveWebhook,
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
setChannelProvider,
|
|
72
|
+
setChannelProviderAsync,
|
|
72
73
|
setScheduleEnabled,
|
|
73
74
|
setWebhookEnabled,
|
|
74
75
|
setWebhookConfig,
|
|
@@ -260,13 +261,10 @@ import {
|
|
|
260
261
|
SEARCH_RUNTIME,
|
|
261
262
|
SEARCH_TOOL_DEFS,
|
|
262
263
|
MEMORY_TOOL_DEFS,
|
|
263
|
-
MEMORY_RUNTIME,
|
|
264
264
|
CHANNEL_TOOL_DEFS,
|
|
265
|
-
CHANNEL_WORKER_ENTRY,
|
|
266
265
|
CODE_GRAPH_TOOL_DEFS,
|
|
267
266
|
CODE_GRAPH_RUNTIME,
|
|
268
267
|
STATUSLINE_SESSION_ROUTES,
|
|
269
|
-
SESSION_RUNTIME_DIR,
|
|
270
268
|
STANDALONE_SOURCE_ROOT,
|
|
271
269
|
STANDALONE_ROOT,
|
|
272
270
|
STANDALONE_DATA_DIR,
|
|
@@ -297,6 +295,7 @@ const searchCapableFor = makeSearchCapableFor(normalizeSearchProviderId, isSearc
|
|
|
297
295
|
const KEYCHAIN_PREWARM_WAIT_MS = 5000;
|
|
298
296
|
|
|
299
297
|
const outputStyleStatus = (dataDir = STANDALONE_DATA_DIR, opts = {}) => outputStyleStatusRaw(STANDALONE_ROOT, dataDir || STANDALONE_DATA_DIR, opts);
|
|
298
|
+
const MEMORY_RUNTIME_ENTRY = fileURLToPath(new URL('../runtime/memory/index.mjs', import.meta.url));
|
|
300
299
|
// Workflow/agent pack loaders bound to this runtime's root/data layout.
|
|
301
300
|
const {
|
|
302
301
|
listWorkflowPacks,
|
|
@@ -417,28 +416,30 @@ export async function createMixdogSessionRuntime({
|
|
|
417
416
|
// seconds. Timer is unref'd and first fires after CLEANUP_INITIAL_DELAY_MS
|
|
418
417
|
// (5min), so this adds zero boot-path cost.
|
|
419
418
|
try { mgr.startIdleCleanup?.(); } catch { /* cleanup is best-effort */ }
|
|
420
|
-
const memoryRuntime = createStandaloneMemoryRuntime({
|
|
421
|
-
// Entry constants are module-relative ('../runtime/...'); resolve against
|
|
422
|
-
// this module's dir, not STANDALONE_ROOT, or the 'src/' segment is lost.
|
|
423
|
-
entry: join(SESSION_RUNTIME_DIR, MEMORY_RUNTIME),
|
|
424
|
-
dataDir: pluginDataDir,
|
|
425
|
-
cwd,
|
|
426
|
-
});
|
|
427
419
|
rt.memoryModPromise = null;
|
|
428
420
|
rt.searchModPromise = null;
|
|
429
421
|
rt.codeGraphModPromise = null;
|
|
430
422
|
|
|
431
|
-
// Memory
|
|
432
|
-
//
|
|
433
|
-
// the user-facing toggle is `recap` (background cycles only), read via
|
|
434
|
-
// recapEnabled(config).
|
|
435
|
-
const memoryEnabled = () => true;
|
|
423
|
+
// Memory is always-on. The user-facing toggle is `recap` (background cycles
|
|
424
|
+
// only), read via recapEnabled(config).
|
|
436
425
|
const recapEnabledFn = () => recapEnabled(rt.config, true);
|
|
437
426
|
const channelsEnabled = () => moduleEnabled(rt.config, 'channels', true);
|
|
438
427
|
|
|
439
428
|
async function getMemoryModule() {
|
|
440
429
|
const startedAt = performance.now();
|
|
441
|
-
rt.memoryModPromise ??= Promise.resolve(
|
|
430
|
+
rt.memoryModPromise ??= Promise.resolve().then(() => {
|
|
431
|
+
const runtime = getStandaloneMemoryRuntime({
|
|
432
|
+
entry: MEMORY_RUNTIME_ENTRY,
|
|
433
|
+
dataDir: process.env.MIXDOG_DATA_DIR || cfgMod.getPluginData?.() || STANDALONE_DATA_DIR,
|
|
434
|
+
});
|
|
435
|
+
// Session teardown must never stop a process shared by every other live
|
|
436
|
+
// session. The daemon owns the actual stop()/deregister lifecycle.
|
|
437
|
+
return {
|
|
438
|
+
init: () => runtime.init(),
|
|
439
|
+
handleToolCall: (...args) => runtime.handleToolCall(...args),
|
|
440
|
+
buildSessionCoreMemoryPayload: (...args) => runtime.buildSessionCoreMemoryPayload(...args),
|
|
441
|
+
};
|
|
442
|
+
});
|
|
442
443
|
const mod = await rt.memoryModPromise;
|
|
443
444
|
if (typeof mod?.init === 'function') {
|
|
444
445
|
await mod.init();
|
|
@@ -469,10 +470,6 @@ export async function createMixdogSessionRuntime({
|
|
|
469
470
|
|
|
470
471
|
const nextConfig = { ...(rt.config || {}) };
|
|
471
472
|
nextConfig.presets = upsertWorkflowPreset(nextConfig.presets, 'lead', leadRoute);
|
|
472
|
-
nextConfig.workflowRoutes = {
|
|
473
|
-
...(nextConfig.workflowRoutes || {}),
|
|
474
|
-
lead: leadRoute,
|
|
475
|
-
};
|
|
476
473
|
nextConfig.default = workflowPresetId('lead');
|
|
477
474
|
|
|
478
475
|
saveConfigAndAdopt(nextConfig);
|
|
@@ -534,6 +531,20 @@ export async function createMixdogSessionRuntime({
|
|
|
534
531
|
channelStartPromise: null,
|
|
535
532
|
};
|
|
536
533
|
rt.activeTurnCount = 0;
|
|
534
|
+
rt.activeTurnAbortControllers = new Set();
|
|
535
|
+
const registerActiveTurnController = (controller) => {
|
|
536
|
+
rt.activeTurnAbortControllers.add(controller);
|
|
537
|
+
return () => rt.activeTurnAbortControllers.delete(controller);
|
|
538
|
+
};
|
|
539
|
+
const abortActiveTurns = (reason) => {
|
|
540
|
+
let aborted = false;
|
|
541
|
+
for (const controller of [...rt.activeTurnAbortControllers]) {
|
|
542
|
+
if (controller.signal.aborted) continue;
|
|
543
|
+
aborted = true;
|
|
544
|
+
try { controller.abort(reason); } catch {}
|
|
545
|
+
}
|
|
546
|
+
return aborted;
|
|
547
|
+
};
|
|
537
548
|
rt.firstTurnCompleted = false;
|
|
538
549
|
function hookTranscriptPath(sessionId) {
|
|
539
550
|
const id = clean(sessionId);
|
|
@@ -746,7 +757,6 @@ export async function createMixdogSessionRuntime({
|
|
|
746
757
|
};
|
|
747
758
|
const channelsStartedAt = performance.now();
|
|
748
759
|
const channels = createStandaloneChannelWorker({
|
|
749
|
-
entry: join(SESSION_RUNTIME_DIR, CHANNEL_WORKER_ENTRY),
|
|
750
760
|
rootDir: STANDALONE_ROOT,
|
|
751
761
|
dataDir: cfgMod.getPluginData(),
|
|
752
762
|
cwd,
|
|
@@ -971,8 +981,8 @@ export async function createMixdogSessionRuntime({
|
|
|
971
981
|
adoptConfig,
|
|
972
982
|
saveConfigAndAdopt,
|
|
973
983
|
flushConfigSave,
|
|
974
|
-
|
|
975
|
-
|
|
984
|
+
flushChannelProviderSave,
|
|
985
|
+
scheduleChannelProviderSave,
|
|
976
986
|
scheduleSkillsSave,
|
|
977
987
|
flushSkillsSave,
|
|
978
988
|
flushOutputStyleSave,
|
|
@@ -992,8 +1002,8 @@ export async function createMixdogSessionRuntime({
|
|
|
992
1002
|
getRoute: () => rt.route,
|
|
993
1003
|
cfgMod,
|
|
994
1004
|
sharedCfgMod,
|
|
995
|
-
|
|
996
|
-
|
|
1005
|
+
setChannelProvider,
|
|
1006
|
+
setChannelProviderAsync,
|
|
997
1007
|
setConfiguredShell,
|
|
998
1008
|
normalizeSystemShellConfig,
|
|
999
1009
|
normalizeSearchRouteConfig,
|
|
@@ -1198,7 +1208,6 @@ export async function createMixdogSessionRuntime({
|
|
|
1198
1208
|
reg,
|
|
1199
1209
|
cfgMod,
|
|
1200
1210
|
activeWorkflowContext,
|
|
1201
|
-
memoryEnabled,
|
|
1202
1211
|
hooks,
|
|
1203
1212
|
hookCommonPayload,
|
|
1204
1213
|
mcpClient,
|
|
@@ -1253,7 +1262,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1253
1262
|
channels,
|
|
1254
1263
|
channelsEnabled,
|
|
1255
1264
|
hasActiveAutomation,
|
|
1256
|
-
|
|
1265
|
+
flushChannelProviderSave,
|
|
1257
1266
|
invokeChannelStart,
|
|
1258
1267
|
createCurrentSession,
|
|
1259
1268
|
ensureRemoteTranscriptWriter,
|
|
@@ -1304,7 +1313,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1304
1313
|
// was toggled into) remote mode. Non-remote sessions never contend for the
|
|
1305
1314
|
// channel; see startRemote()/stopRemote() and the `/remote` toggle.
|
|
1306
1315
|
// A manual `mixdog --remote` request is deferred past the TUI's
|
|
1307
|
-
// first frame. startRemote() front-loads
|
|
1316
|
+
// first frame. startRemote() front-loads memory initialization
|
|
1308
1317
|
// (PG + forced ONNX embed warmup in the child), eager session create, and
|
|
1309
1318
|
// the channel-worker fork — and running it inline here interleaves that
|
|
1310
1319
|
// CPU/disk load with engine boot, visibly delaying the first ink frame by
|
|
@@ -1323,7 +1332,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1323
1332
|
} else {
|
|
1324
1333
|
// Automation decoupling (user decision): enabled schedules/webhooks boot
|
|
1325
1334
|
// the worker on their own — no remote flag, no remote.autoStart, and no
|
|
1326
|
-
// messaging
|
|
1335
|
+
// messaging provider. A later explicit Remote ON promotes the same
|
|
1327
1336
|
// daemon without restarting schedules or webhooks.
|
|
1328
1337
|
prewarmTimers.channelStartTimer = setTimeout(() => {
|
|
1329
1338
|
prewarmTimers.channelStartTimer = null;
|
|
@@ -1341,7 +1350,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1341
1350
|
|
|
1342
1351
|
// Pure settings-delegate methods (onboarding status/skip, autoClear, profile,
|
|
1343
1352
|
// compaction, recap/memory, channels, systemShell, update settings, channel
|
|
1344
|
-
// token save/forget,
|
|
1353
|
+
// token save/forget, setChannelProvider). Extracted to session-runtime/settings-api.mjs
|
|
1345
1354
|
// and SPREAD into the API object below so the external surface is unchanged.
|
|
1346
1355
|
const settingsApi = createSettingsApi({
|
|
1347
1356
|
getConfig: () => rt.config,
|
|
@@ -1350,7 +1359,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1350
1359
|
getRemoteEnabled: () => rt.remoteEnabled,
|
|
1351
1360
|
adoptConfig,
|
|
1352
1361
|
saveConfigAndAdopt,
|
|
1353
|
-
|
|
1362
|
+
scheduleChannelProviderSave,
|
|
1354
1363
|
scheduleSkillsSave,
|
|
1355
1364
|
cfgMod,
|
|
1356
1365
|
hasOwn,
|
|
@@ -1368,7 +1377,6 @@ export async function createMixdogSessionRuntime({
|
|
|
1368
1377
|
parseDurationMs,
|
|
1369
1378
|
formatDurationMs,
|
|
1370
1379
|
localPackageVersion,
|
|
1371
|
-
memoryEnabled,
|
|
1372
1380
|
recapEnabledFn,
|
|
1373
1381
|
channelsEnabled,
|
|
1374
1382
|
autoUpdateEnabled,
|
|
@@ -1392,11 +1400,11 @@ export async function createMixdogSessionRuntime({
|
|
|
1392
1400
|
forgetDiscordToken,
|
|
1393
1401
|
saveTelegramToken,
|
|
1394
1402
|
forgetTelegramToken,
|
|
1395
|
-
|
|
1403
|
+
setChannelProvider,
|
|
1396
1404
|
});
|
|
1397
1405
|
|
|
1398
1406
|
const channelConfigApi = createChannelConfigApi({
|
|
1399
|
-
|
|
1407
|
+
flushChannelProviderSave,
|
|
1400
1408
|
channels,
|
|
1401
1409
|
reloadChannelsSoon,
|
|
1402
1410
|
// Automation saved mid-session boots the worker (claim-if-vacant) even
|
|
@@ -1445,6 +1453,8 @@ export async function createMixdogSessionRuntime({
|
|
|
1445
1453
|
getMemoryModPromise: () => rt.memoryModPromise,
|
|
1446
1454
|
setMemoryModPromise: (v) => { rt.memoryModPromise = v; },
|
|
1447
1455
|
setSessionNeedsCwdRefresh: (v) => { rt.sessionNeedsCwdRefresh = v; },
|
|
1456
|
+
getReservedSessionId: () => rt.reservedSessionId,
|
|
1457
|
+
abortActiveTurns,
|
|
1448
1458
|
hooks,
|
|
1449
1459
|
hookCommonPayload,
|
|
1450
1460
|
mgr,
|
|
@@ -1456,7 +1466,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1456
1466
|
warmupTimers,
|
|
1457
1467
|
prewarmTimers,
|
|
1458
1468
|
flushConfigSave,
|
|
1459
|
-
|
|
1469
|
+
flushChannelProviderSave,
|
|
1460
1470
|
flushOutputStyleSave,
|
|
1461
1471
|
flushAllConfigSavesAsync,
|
|
1462
1472
|
withTeardownDeadline,
|
|
@@ -1624,6 +1634,7 @@ export async function createMixdogSessionRuntime({
|
|
|
1624
1634
|
mcpTurnGraceMs,
|
|
1625
1635
|
awaitRoutePreparation: () => routePreparation.wait(),
|
|
1626
1636
|
getReservedSessionId: () => rt.reservedSessionId,
|
|
1637
|
+
registerActiveTurnController,
|
|
1627
1638
|
sessionTitles,
|
|
1628
1639
|
});
|
|
1629
1640
|
|
|
@@ -1633,7 +1644,11 @@ export async function createMixdogSessionRuntime({
|
|
|
1633
1644
|
...providerAuthApi,
|
|
1634
1645
|
...mediaApi,
|
|
1635
1646
|
// Turn-scoped worktree review plus exact child apply_patch attribution.
|
|
1636
|
-
getTurnReviewDiff: () => getTurnSnapshotReviewDiff(
|
|
1647
|
+
getTurnReviewDiff: (options = {}) => getTurnSnapshotReviewDiff(
|
|
1648
|
+
rt.currentCwd,
|
|
1649
|
+
rt.session?.id,
|
|
1650
|
+
options,
|
|
1651
|
+
),
|
|
1637
1652
|
revertTurnReviewFile: (file) => revertTurnSnapshotReviewFile(
|
|
1638
1653
|
rt.currentCwd,
|
|
1639
1654
|
rt.session?.id,
|
|
@@ -1651,6 +1666,15 @@ export async function createMixdogSessionRuntime({
|
|
|
1651
1666
|
throw new Error(`session ${rt.session.id} is already materialized`);
|
|
1652
1667
|
}
|
|
1653
1668
|
rt.reservedSessionId = id;
|
|
1669
|
+
// Reservation is the earliest safe point to prepare keychain, memory,
|
|
1670
|
+
// provider metadata, hooks, and the provider transport. This starts no
|
|
1671
|
+
// model response and therefore incurs no inference/token usage. The first
|
|
1672
|
+
// submit joins this single-flight promise instead of paying cold setup.
|
|
1673
|
+
void createCurrentSession('reservation').catch((error) => {
|
|
1674
|
+
bootProfile('session:reservation-prewarm-failed', {
|
|
1675
|
+
error: error?.message || String(error),
|
|
1676
|
+
});
|
|
1677
|
+
});
|
|
1654
1678
|
return id;
|
|
1655
1679
|
},
|
|
1656
1680
|
get provider() {
|
|
@@ -24,10 +24,10 @@ export function readRuntimeTunables() {
|
|
|
24
24
|
statuslineUsageRefreshDelayMs: envDelayMs('MIXDOG_STATUSLINE_USAGE_REFRESH_MS', 240_000, { min: 30_000, max: 540_000 }),
|
|
25
25
|
channelStartDelayMs: envDelayMs('MIXDOG_CHANNEL_START_DELAY_MS', 10_000, { min: 0, max: 120_000 }),
|
|
26
26
|
backgroundBusyRetryMs: envDelayMs('MIXDOG_BACKGROUND_BUSY_RETRY_MS', 1_000, { min: 50, max: 10_000 }),
|
|
27
|
-
// MCP startup
|
|
28
|
-
//
|
|
29
|
-
// late-tool announcement path
|
|
30
|
-
mcpTurnGraceMs: envDelayMs('MIXDOG_MCP_TURN_GRACE_MS',
|
|
27
|
+
// MCP startup never owns the first-token critical path by default. Already
|
|
28
|
+
// connected tools fold synchronously; in-flight servers join through the
|
|
29
|
+
// late-tool announcement path. Operators may opt back into a grace window.
|
|
30
|
+
mcpTurnGraceMs: envDelayMs('MIXDOG_MCP_TURN_GRACE_MS', 0, { min: 0, max: 2_000 }),
|
|
31
31
|
// Boot-time remote start is deferred past the first frame; see the caller.
|
|
32
32
|
remoteAutoStartDelayMs: envDelayMs('MIXDOG_REMOTE_AUTOSTART_DELAY_MS', 1_500, { min: 0, max: 60_000 }),
|
|
33
33
|
providerWarmupEnabled: !envFlag('MIXDOG_DISABLE_PROVIDER_WARMUP')
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
|
|
15
15
|
const STAGE_POLL_MS = 3_000;
|
|
16
16
|
const STAGE_POLL_MAX_MS = 10 * 60 * 1000;
|
|
17
|
-
// A
|
|
17
|
+
// A daemon can host many session runtimes. Their boot controllers all
|
|
18
18
|
// need the same update state, not one forced registry request per pane.
|
|
19
19
|
const processBootChecks = new Map();
|
|
20
20
|
|
|
@@ -18,6 +18,7 @@ import { envFlag } from './env.mjs';
|
|
|
18
18
|
import { createPrewarmSchedulers } from './prewarm.mjs';
|
|
19
19
|
import { hasActiveAutomation } from '../standalone/channel-admin.mjs';
|
|
20
20
|
import { createRemoteTranscript } from './remote-transcript.mjs';
|
|
21
|
+
import { runAbortable, throwIfAborted } from '../runtime/shared/abort-race.mjs';
|
|
21
22
|
export function createSessionLifecycle({
|
|
22
23
|
rt,
|
|
23
24
|
collectProviderModels,
|
|
@@ -30,7 +31,6 @@ export function createSessionLifecycle({
|
|
|
30
31
|
reg,
|
|
31
32
|
cfgMod,
|
|
32
33
|
activeWorkflowContext,
|
|
33
|
-
memoryEnabled,
|
|
34
34
|
hooks,
|
|
35
35
|
hookCommonPayload,
|
|
36
36
|
mcpClient,
|
|
@@ -62,9 +62,10 @@ export function createSessionLifecycle({
|
|
|
62
62
|
codeGraphPrewarmEnabled,
|
|
63
63
|
prewarmState,
|
|
64
64
|
}) {
|
|
65
|
-
async function resolveMissingRouteModelForFirstTurn() {
|
|
65
|
+
async function resolveMissingRouteModelForFirstTurn(signal = null) {
|
|
66
66
|
if (routeHasModel()) return rt.route;
|
|
67
|
-
const models = await collectProviderModels();
|
|
67
|
+
const models = await runAbortable(signal, () => collectProviderModels());
|
|
68
|
+
throwIfAborted(signal);
|
|
68
69
|
const picked = models[0] || null;
|
|
69
70
|
if (!picked) {
|
|
70
71
|
throw new Error('No provider models available. Open /providers to sign in, then /model to choose a model.');
|
|
@@ -78,10 +79,14 @@ export function createSessionLifecycle({
|
|
|
78
79
|
return rt.route;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
async function refreshRouteEffort(modelMetaOverride = null, expectedRoute = null) {
|
|
82
|
+
async function refreshRouteEffort(modelMetaOverride = null, expectedRoute = null, signal = null) {
|
|
82
83
|
const targetRoute = expectedRoute || rt.route;
|
|
83
|
-
await ensureProvidersReady(ensureProviderEnabled(rt.config, targetRoute.provider));
|
|
84
|
-
const modelMeta = modelMetaOverride || await
|
|
84
|
+
await runAbortable(signal, () => ensureProvidersReady(ensureProviderEnabled(rt.config, targetRoute.provider)));
|
|
85
|
+
const modelMeta = modelMetaOverride || await runAbortable(
|
|
86
|
+
signal,
|
|
87
|
+
() => lookupModelMeta(targetRoute.provider, targetRoute.model),
|
|
88
|
+
);
|
|
89
|
+
throwIfAborted(signal);
|
|
85
90
|
// A rapid second resume/model change can replace the route while provider
|
|
86
91
|
// metadata is loading. Never let the older completion overwrite it.
|
|
87
92
|
if (expectedRoute && rt.route !== expectedRoute) return null;
|
|
@@ -127,8 +132,12 @@ export function createSessionLifecycle({
|
|
|
127
132
|
return await createCurrentSession();
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
async function createCurrentSession(reason = 'demand') {
|
|
131
|
-
|
|
135
|
+
async function createCurrentSession(reason = 'demand', options = {}) {
|
|
136
|
+
const signal = options?.signal || null;
|
|
137
|
+
throwIfAborted(signal);
|
|
138
|
+
if (rt.sessionCreatePromise) {
|
|
139
|
+
return await runAbortable(signal, () => rt.sessionCreatePromise, 'Session creation aborted');
|
|
140
|
+
}
|
|
132
141
|
if (rt.session?.id && !rt.sessionNeedsCwdRefresh) {
|
|
133
142
|
const liveSession = mgr.getSession(rt.session.id);
|
|
134
143
|
if (liveSession && liveSession.closed !== true && liveSession.status !== 'closed') {
|
|
@@ -140,23 +149,34 @@ export function createSessionLifecycle({
|
|
|
140
149
|
|
|
141
150
|
const startedAt = performance.now();
|
|
142
151
|
bootProfile('session:create:start', { mode: rt.mode, reason });
|
|
152
|
+
// A daemon reservation is deliberate user-think-time prewarm. Start the
|
|
153
|
+
// one-time agent-loop module load now so the first real prompt does not pay
|
|
154
|
+
// its ~100ms dynamic-import graph immediately before provider.send.
|
|
155
|
+
if (reason === 'reservation' && typeof mgr.prewarmAgentLoop === 'function') {
|
|
156
|
+
void mgr.prewarmAgentLoop().catch((error) => {
|
|
157
|
+
bootProfile('agent-loop:prewarm-failed', { error: error?.message || String(error) });
|
|
158
|
+
});
|
|
159
|
+
}
|
|
143
160
|
const promise = (async () => {
|
|
144
161
|
// Demand-only: this starts only after the user submits (unless an
|
|
145
162
|
// explicitly enabled prewarm caller asks for a session). Core-memory
|
|
146
163
|
// startup does not depend on keychain/provider readiness, so overlap the
|
|
147
164
|
// two cold paths instead of paying their bounded waits serially.
|
|
148
|
-
const coreMemoryContextPromise = loadCoreMemoryContext();
|
|
149
|
-
|
|
165
|
+
const coreMemoryContextPromise = Promise.resolve(loadCoreMemoryContext());
|
|
166
|
+
coreMemoryContextPromise.catch(() => {});
|
|
167
|
+
await runAbortable(signal, () => awaitKeychainPrewarm());
|
|
150
168
|
ensureConfigForRouteProvider();
|
|
151
|
-
await resolveMissingRouteModelForFirstTurn();
|
|
169
|
+
await resolveMissingRouteModelForFirstTurn(signal);
|
|
152
170
|
requireModelRoute();
|
|
153
171
|
bootProfile('session:create:route-ready', { ms: (performance.now() - startedAt).toFixed(1) });
|
|
154
172
|
// Route effort waits on provider readiness while the already-started
|
|
155
173
|
// memory load continues independently.
|
|
156
|
-
const
|
|
157
|
-
|
|
174
|
+
const expectedRoute = rt.route;
|
|
175
|
+
const [, coreMemoryContext] = await runAbortable(signal, () => Promise.all([
|
|
176
|
+
refreshRouteEffort(null, expectedRoute, signal),
|
|
158
177
|
coreMemoryContextPromise,
|
|
159
|
-
]);
|
|
178
|
+
]));
|
|
179
|
+
throwIfAborted(signal);
|
|
160
180
|
bootProfile('session:create:effort-ready', { ms: (performance.now() - startedAt).toFixed(1) });
|
|
161
181
|
const providerImpl = reg.getProvider(rt.route.provider);
|
|
162
182
|
if (!providerImpl) {
|
|
@@ -164,6 +184,7 @@ export function createSessionLifecycle({
|
|
|
164
184
|
}
|
|
165
185
|
bootProfile('session:create:provider-ready', { ms: (performance.now() - startedAt).toFixed(1) });
|
|
166
186
|
if (rt.closeRequested) throw new Error('runtime is closing');
|
|
187
|
+
throwIfAborted(signal);
|
|
167
188
|
const dataDir = cfgMod.getPluginData?.() || STANDALONE_DATA_DIR;
|
|
168
189
|
// Load the active WORKFLOW.md pack once for both summary + context block.
|
|
169
190
|
const { summary: workflow, context: workflowContext } = activeWorkflowContext(rt.config, dataDir);
|
|
@@ -187,7 +208,7 @@ export function createSessionLifecycle({
|
|
|
187
208
|
workflowContext,
|
|
188
209
|
fast: rt.route.fast === true,
|
|
189
210
|
compaction: rt.config.compaction && typeof rt.config.compaction === 'object'
|
|
190
|
-
? normalizeCompactionConfig(rt.config.compaction
|
|
211
|
+
? normalizeCompactionConfig(rt.config.compaction)
|
|
191
212
|
: undefined,
|
|
192
213
|
};
|
|
193
214
|
if (hasOwn(rt.route, 'effort') || rt.route.effectiveEffort) {
|
|
@@ -229,7 +250,10 @@ export function createSessionLifecycle({
|
|
|
229
250
|
const startSource = /resume/i.test(String(reason || ''))
|
|
230
251
|
? 'resume'
|
|
231
252
|
: (/clear/i.test(String(reason || '')) ? 'clear' : 'startup');
|
|
232
|
-
const startDispatch = await
|
|
253
|
+
const startDispatch = await runAbortable(
|
|
254
|
+
signal,
|
|
255
|
+
() => hooks.dispatch('SessionStart', hookCommonPayload({ session_id: rt.session.id, source: startSource, model: rt.route.model })),
|
|
256
|
+
);
|
|
233
257
|
const startContext = Array.isArray(startDispatch?.additionalContext)
|
|
234
258
|
? startDispatch.additionalContext.join('\n\n')
|
|
235
259
|
: String(startDispatch?.additionalContext || '');
|
|
@@ -238,7 +262,11 @@ export function createSessionLifecycle({
|
|
|
238
262
|
rt.session.messages.push({ role: 'assistant', content: '.' });
|
|
239
263
|
rt.session.updatedAt = Date.now();
|
|
240
264
|
}
|
|
241
|
-
} catch {
|
|
265
|
+
} catch {
|
|
266
|
+
throwIfAborted(signal);
|
|
267
|
+
// best-effort: ordinary hook failure never breaks session create
|
|
268
|
+
}
|
|
269
|
+
throwIfAborted(signal);
|
|
242
270
|
bootProfile('session:create:ready', {
|
|
243
271
|
ms: (performance.now() - startedAt).toFixed(1),
|
|
244
272
|
reason,
|
|
@@ -106,7 +106,7 @@ export function resolvedSystemLocale() {
|
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
/** Shared
|
|
109
|
+
/** Shared session controller used by every lead surface (TUI and desktop). */
|
|
110
110
|
export function createSessionTitleController(deps = {}) {
|
|
111
111
|
const firstAttempts = new Set();
|
|
112
112
|
const thirdAttempts = new Set();
|