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
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { __mixdogMemoryLog } from './lib/memory-log.mjs';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// V8 compile cache: the memory runtime is its own long-lived child process
|
|
8
|
-
// (spawned by the channel daemon / standalone proxy) and never passes through
|
|
9
|
-
// cli.mjs, so it pays full ESM parse cost on every boot without this. Same
|
|
10
|
-
// best-effort guard as cli.mjs.
|
|
4
|
+
// V8 compile cache: the memory runtime is a separate long-lived child in
|
|
5
|
+
// product mode. The standalone MCP entry uses the same module directly.
|
|
11
6
|
try {
|
|
12
7
|
const { enableCompileCache } = await import('node:module')
|
|
13
8
|
enableCompileCache?.()
|
|
@@ -26,12 +21,6 @@ import { readPluginVersion, readPromotionCodeFingerprint } from './lib/promotion
|
|
|
26
21
|
const PLUGIN_VERSION = readPluginVersion(PLUGIN_ROOT)
|
|
27
22
|
const BOOT_PROMOTION_CODE_FINGERPRINT = readPromotionCodeFingerprint(PLUGIN_ROOT)
|
|
28
23
|
|
|
29
|
-
try { os.setPriority(os.constants.priority.PRIORITY_BELOW_NORMAL) } catch {}
|
|
30
|
-
try {
|
|
31
|
-
const { env } = await import('@huggingface/transformers')
|
|
32
|
-
env.backends.onnx.wasm.numThreads = 1
|
|
33
|
-
} catch {}
|
|
34
|
-
|
|
35
24
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
36
25
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
37
26
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'
|
|
@@ -67,9 +56,7 @@ import {
|
|
|
67
56
|
import { configureEmbedding, embedText, embedTexts, getEmbeddingDims, getEmbeddingDtype, getEmbeddingModelId, getKnownDimsForCurrentModel, isEmbeddingModelReady, primeEmbeddingDims, shutdownEmbeddingProvider, warmupEmbeddingProvider } from './lib/embedding-provider.mjs'
|
|
68
57
|
import { startLlmWorker, stopLlmWorker } from './lib/llm-worker-host.mjs'
|
|
69
58
|
import { runCycle1, runCycle2, runCycle3, runUnifiedGate, parseInterval, syncRootEmbedding, flushRawEmbeddings, applySimpleStatus, applyUpdate, applyMerge, CYCLE2_ACTIVE_TARGET_CAP } from './lib/memory-cycle.mjs'
|
|
70
|
-
import {
|
|
71
|
-
import { initProviders } from '../agent/orchestrator/providers/registry.mjs'
|
|
72
|
-
import { makeAgentDispatch } from '../agent/orchestrator/agent-runtime/agent-dispatch.mjs'
|
|
59
|
+
import { callAgentDispatch } from './lib/agent-ipc.mjs'
|
|
73
60
|
import { getInFlightCycle1 } from './lib/memory-cycle1.mjs'
|
|
74
61
|
import { claimAndMarkScheduledCycle, markCycleRequest, resolveCoalesceMaxRetries, scheduleCoalescedCycleRetry } from './lib/memory-cycle-requests.mjs'
|
|
75
62
|
import { searchRelevantHybrid } from './lib/memory-recall-store.mjs'
|
|
@@ -110,8 +97,14 @@ import {
|
|
|
110
97
|
assertSecondaryPgAttachable as _assertSecondaryPgAttachable,
|
|
111
98
|
} from './lib/memory-config-flags.mjs'
|
|
112
99
|
const IS_MEMORY_ENTRY = !!process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
|
|
113
|
-
|
|
100
|
+
if (IS_MEMORY_ENTRY) {
|
|
101
|
+
process.removeAllListeners('warning')
|
|
102
|
+
process.on('warning', () => {})
|
|
103
|
+
try { os.setPriority(os.constants.priority.PRIORITY_BELOW_NORMAL) } catch {}
|
|
104
|
+
}
|
|
105
|
+
const USE_ARG_DATA_DIR = IS_MEMORY_ENTRY
|
|
114
106
|
const DATA_DIR = process.env.MIXDOG_DATA_DIR || (USE_ARG_DATA_DIR ? process.argv[2] : '') || resolvePluginData()
|
|
107
|
+
const INTEGRATED_DAEMON_HOST = process.env.MIXDOG_DAEMON_HOST === '1' && !IS_MEMORY_ENTRY
|
|
115
108
|
if (!DATA_DIR) {
|
|
116
109
|
__mixdogMemoryLog('[memory-service] memory data dir not set and no explicit data dir provided\n')
|
|
117
110
|
process.exit(1)
|
|
@@ -132,9 +125,6 @@ function memoryProfile(event, fields = {}) {
|
|
|
132
125
|
import {
|
|
133
126
|
parsePositivePid,
|
|
134
127
|
isPidAliveLocal,
|
|
135
|
-
tryAcquireMemoryOwnerLock as _tryAcquireMemoryOwnerLock,
|
|
136
|
-
releaseMemoryOwnerLock as _releaseMemoryOwnerLock,
|
|
137
|
-
killPreviousServer as _killPreviousServer,
|
|
138
128
|
acquireLock as _acquireLock,
|
|
139
129
|
releaseLock as _releaseLock,
|
|
140
130
|
} from './lib/memory-process-lock.mjs'
|
|
@@ -175,19 +165,6 @@ const _daemonLifecycle = createMemoryDaemonLifecycle({
|
|
|
175
165
|
const { touchDaemonIdleTimer, registerClient, deregisterClient } = _daemonLifecycle
|
|
176
166
|
|
|
177
167
|
const LOCK_FILE = path.join(DATA_DIR, '.memory-service.lock')
|
|
178
|
-
// Owner-election lock. Separate from LOCK_FILE so single-instance mode keeps
|
|
179
|
-
// its kill-the-previous protocol while multi-instance fork-proxy workers use
|
|
180
|
-
// atomic CAS for takeover. Created via fs.openSync(path,'wx') — node guarantees
|
|
181
|
-
// EEXIST when another process won the race.
|
|
182
|
-
const OWNER_LOCK_FILE = path.join(DATA_DIR, '.memory-owner.lock')
|
|
183
|
-
|
|
184
|
-
function tryAcquireMemoryOwnerLock() {
|
|
185
|
-
return _tryAcquireMemoryOwnerLock(OWNER_LOCK_FILE, __mixdogMemoryLog)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function releaseMemoryOwnerLock() {
|
|
189
|
-
return _releaseMemoryOwnerLock(OWNER_LOCK_FILE)
|
|
190
|
-
}
|
|
191
168
|
|
|
192
169
|
const BASE_PORT = 3350
|
|
193
170
|
const MAX_PORT = 3357
|
|
@@ -196,10 +173,6 @@ let _traceDb = null
|
|
|
196
173
|
|
|
197
174
|
const MEMORY_INSTRUCTIONS_TEXT = ''
|
|
198
175
|
|
|
199
|
-
function killPreviousServer(pid) {
|
|
200
|
-
return _killPreviousServer(pid, __mixdogMemoryLog)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
176
|
function acquireLock() {
|
|
204
177
|
return _acquireLock(LOCK_FILE, __mixdogMemoryLog)
|
|
205
178
|
}
|
|
@@ -358,36 +331,9 @@ async function _initStore() {
|
|
|
358
331
|
} else {
|
|
359
332
|
__mixdogMemoryLog('[memory-service] secondary mode; skipping llm worker\n')
|
|
360
333
|
}
|
|
361
|
-
//
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
// has disconnected IPC, so the legacy callAgentDispatch() IPC path is dead on
|
|
365
|
-
// arrival. Mirror the channels worker boot (channels/index.mjs:
|
|
366
|
-
// loadAgentConfig() + initProviders) so the registry is populated before any
|
|
367
|
-
// cycle1 dispatch. The gate MUST match _startCycle1Run's makeAgentDispatch
|
|
368
|
-
// injection condition: cycle1 may dispatch in-process whenever cycles are
|
|
369
|
-
// enabled OR the llm worker is enabled (both exclude secondary mode), so
|
|
370
|
-
// registering only under the llm-worker gate would leave a hole where
|
|
371
|
-
// MIXDOG_MEMORY_DISABLE_LLM_WORKER=1 + cycles enabled hits an empty registry
|
|
372
|
-
// and fails with "Provider not found". Non-fatal: a failure here is logged
|
|
373
|
-
// and cycle1's own callLlm surfaces the unresolved-provider error per call.
|
|
374
|
-
// Registry must be available whenever cycles COULD run in this process, not
|
|
375
|
-
// just when they are currently enabled: recap can be toggled on at runtime
|
|
376
|
-
// (memoryCyclesEnabled() now includes the recap flag), so gate registry init
|
|
377
|
-
// on the cycle-capable conditions (not secondary, env not hard-disabled) OR
|
|
378
|
-
// the llm worker gate — never on the runtime recap flag itself, or enabling
|
|
379
|
-
// recap later would hit an empty registry and fail with "Provider not found".
|
|
380
|
-
const cyclesCapable = !memorySecondaryMode() && !envFlagEnabled('MIXDOG_MEMORY_DISABLE_CYCLES')
|
|
381
|
-
if (cyclesCapable || memoryLlmWorkerEnabled()) {
|
|
382
|
-
try {
|
|
383
|
-
const agentCfg = loadAgentConfig()
|
|
384
|
-
const providersStartedAt = performance.now()
|
|
385
|
-
await initProviders(agentCfg.providers || {})
|
|
386
|
-
memoryProfile('providers:init:done', { ms: (performance.now() - providersStartedAt).toFixed(1) })
|
|
387
|
-
} catch (e) {
|
|
388
|
-
process.stderr.write(`[memory-service] initProviders failed (non-fatal): ${e instanceof Error ? e.message : String(e)}\n`)
|
|
389
|
-
}
|
|
390
|
-
}
|
|
334
|
+
// Provider/session/agent modules live once in the daemon. Memory
|
|
335
|
+
// cycles cross the authenticated loopback broker instead of initializing a
|
|
336
|
+
// second registry in this process.
|
|
391
337
|
_bootTimestamp = Date.now()
|
|
392
338
|
const offsetsStartedAt = performance.now()
|
|
393
339
|
await loadTranscriptOffsets()
|
|
@@ -437,7 +383,7 @@ async function setCycleLastRun(kind, ts) {
|
|
|
437
383
|
// getters (getDb/getConfig/setConfig) plus runners and LLM adapters.
|
|
438
384
|
const CYCLE_STATE_FILE = path.join(DATA_DIR, 'memory-cycle-state.json')
|
|
439
385
|
|
|
440
|
-
const _cycleLlmAdapters = createCycleLlmAdapters({
|
|
386
|
+
const _cycleLlmAdapters = createCycleLlmAdapters({ callAgentDispatch })
|
|
441
387
|
const { getCycle1CallLlm, getCycle2CallLlm, getCycle3CallLlm } = _cycleLlmAdapters
|
|
442
388
|
|
|
443
389
|
const _cycleScheduler = createCycleScheduler({
|
|
@@ -620,31 +566,61 @@ export { TOOL_DEFS, handleToolCall, buildSessionCoreMemoryPayload }
|
|
|
620
566
|
export { MEMORY_INSTRUCTIONS_TEXT as instructions }
|
|
621
567
|
export { acquireLock, releaseLock }
|
|
622
568
|
export { cwdFromTranscriptPath }
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
569
|
+
|
|
570
|
+
/** In-process write surface used by the unified channel/session daemon. */
|
|
571
|
+
export async function appendEntry(data = {}) {
|
|
572
|
+
await init()
|
|
573
|
+
const role = String(data.role ?? 'user')
|
|
574
|
+
const content = String(data.content ?? '')
|
|
575
|
+
const cleaned = cleanMemoryText(content)
|
|
576
|
+
if (!cleaned || !cleaned.trim()) return { error: content ? 'empty after clean' : 'content required' }
|
|
577
|
+
const sourceRef = String(data.sourceRef ?? `manual:${Date.now()}-${process.pid}`)
|
|
578
|
+
const sessionId = data.sessionId ?? null
|
|
579
|
+
const tsMs = parseTsToMs(data.ts ?? Date.now())
|
|
580
|
+
const projectId = resolveProjectScope(typeof data.cwd === 'string' && data.cwd ? data.cwd : null)
|
|
581
|
+
const result = await db.query(`
|
|
582
|
+
INSERT INTO entries(ts, role, content, source_ref, session_id, project_id)
|
|
583
|
+
VALUES ($1, $2, $3, $4, $5, $6)
|
|
584
|
+
ON CONFLICT DO NOTHING
|
|
585
|
+
RETURNING id
|
|
586
|
+
`, [tsMs, role, cleaned, sourceRef, sessionId, projectId])
|
|
587
|
+
const insertedId = result.rows[0]?.id ?? null
|
|
588
|
+
return {
|
|
589
|
+
ok: true,
|
|
590
|
+
id: insertedId !== null ? Number(insertedId) : null,
|
|
591
|
+
changes: Number(result.rowCount ?? result.affectedRows ?? 0),
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/** In-process transcript ingest surface used by the unified daemon. */
|
|
596
|
+
export async function ingestTranscript(filePath, { cwd } = {}) {
|
|
597
|
+
await init()
|
|
598
|
+
if (!filePath) return { error: 'filePath required' }
|
|
599
|
+
const ingested = await ingestTranscriptFile(filePath, { cwd })
|
|
600
|
+
return { ok: true, ingested }
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/** Direct trace sink for agent orchestration running in this daemon process. */
|
|
604
|
+
export async function recordTraceEvents(events = []) {
|
|
605
|
+
await init()
|
|
606
|
+
if (!Array.isArray(events)) throw new TypeError('events must be an array')
|
|
607
|
+
if (events.length > 500) throw new RangeError('too many events (max 500)')
|
|
608
|
+
if (!_traceDb) {
|
|
609
|
+
_traceDb = await openTraceDatabase(DATA_DIR)
|
|
610
|
+
registerTraceExitDrain(_traceDb)
|
|
611
|
+
}
|
|
612
|
+
enqueueTraceEvents(_traceDb, events)
|
|
613
|
+
void insertAgentCalls(_traceDb, events).catch((error) => {
|
|
614
|
+
__mixdogMemoryLog(`[trace] insertAgentCalls error: ${error?.message}\n`)
|
|
629
615
|
})
|
|
616
|
+
return { ok: true, queued: events.length }
|
|
630
617
|
}
|
|
631
618
|
export async function init() {
|
|
632
619
|
if (_initialized) return
|
|
633
620
|
__mixdogMemoryLog(`[boot-time] tag=memory-init-start tMs=${Date.now()}\n`)
|
|
634
|
-
if (process.env.MIXDOG_WORKER_MODE === '1' && process.send) {
|
|
635
|
-
// Single-worker daemon: acquire the owner lock (which reclaims a crashed
|
|
636
|
-
// predecessor's stale, dead-PID lock). If a LIVE peer still holds it — an
|
|
637
|
-
// anomaly, since server-main forks exactly one memory worker — exit so
|
|
638
|
-
// server-main respawns us instead of running a second owner.
|
|
639
|
-
if (!tryAcquireMemoryOwnerLock()) {
|
|
640
|
-
__mixdogMemoryLog('[memory-service] live peer holds owner lock — exiting for respawn\n')
|
|
641
|
-
process.exit(0)
|
|
642
|
-
}
|
|
643
|
-
process.on('exit', releaseMemoryOwnerLock)
|
|
644
|
-
}
|
|
645
621
|
const runtimeReady = _beginRuntimeInit()
|
|
646
622
|
let boundPort = null
|
|
647
|
-
if (!memorySecondaryMode()) {
|
|
623
|
+
if (!memorySecondaryMode() && !INTEGRATED_DAEMON_HOST) {
|
|
648
624
|
boundPort = await _startHttpServer()
|
|
649
625
|
advertiseMemoryPort(boundPort)
|
|
650
626
|
try {
|
|
@@ -663,11 +639,10 @@ export async function init() {
|
|
|
663
639
|
} else {
|
|
664
640
|
await runtimeReady
|
|
665
641
|
}
|
|
642
|
+
__mixdogMemoryLog(`[memory-service] init() complete (entries unified mode, version=${PLUGIN_VERSION})\n`)
|
|
666
643
|
if (process.env.MIXDOG_WORKER_MODE === '1' && process.send) {
|
|
667
|
-
|
|
668
|
-
sendMemoryWorkerMessage({ type: 'ready', port: boundPort })
|
|
644
|
+
safeIpcSend(process, { type: 'ready', port: boundPort })
|
|
669
645
|
}
|
|
670
|
-
__mixdogMemoryLog(`[memory-service] init() complete (entries unified mode, version=${PLUGIN_VERSION})\n`)
|
|
671
646
|
touchDaemonIdleTimer('init')
|
|
672
647
|
}
|
|
673
648
|
|
|
@@ -702,49 +677,11 @@ export async function stop() {
|
|
|
702
677
|
await closeDatabase(DATA_DIR)
|
|
703
678
|
// Stop the PG postmaster after the connection pools have been drained.
|
|
704
679
|
// closeDatabase() only ends the client pool; without this the child
|
|
705
|
-
// postmaster keeps running after the
|
|
680
|
+
// postmaster keeps running after the unified daemon exits.
|
|
706
681
|
if (!memorySecondaryMode()) {
|
|
707
682
|
try {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
// (kind check — guards against a stale/foreign pid reusing this pid
|
|
711
|
-
// number for an unrelated process) and (b) that pid is alive AND not
|
|
712
|
-
// this process. Any read/parse failure or ambiguous state falls back
|
|
713
|
-
// to stopping PG (previous unconditional behavior) rather than
|
|
714
|
-
// risking an orphaned PG postmaster.
|
|
715
|
-
const anotherOwnerAlive = await (async () => {
|
|
716
|
-
try {
|
|
717
|
-
const { readSingletonOwner } = await import('../shared/singleton-owner.mjs')
|
|
718
|
-
const ownerPath = path.join(DATA_DIR, 'memory-runtime-owner.json')
|
|
719
|
-
const { owner, alive } = readSingletonOwner(ownerPath)
|
|
720
|
-
if (!alive) return false
|
|
721
|
-
if (owner?.kind !== 'memory-runtime-daemon') return false
|
|
722
|
-
const ownerPid = Number(owner?.pid)
|
|
723
|
-
if (!Number.isInteger(ownerPid) || ownerPid === process.pid) return false
|
|
724
|
-
// Best-effort process-name check (mirrors supervisor.mjs's
|
|
725
|
-
// isPostgresPid pattern) — confirms the pid is actually a node
|
|
726
|
-
// process before trusting it as a live sibling memory owner.
|
|
727
|
-
// Falls back to true (trust the owner file) when the platform
|
|
728
|
-
// check is unavailable or inconclusive.
|
|
729
|
-
try {
|
|
730
|
-
if (process.platform === 'win32') {
|
|
731
|
-
const { execFileSync } = await import('node:child_process')
|
|
732
|
-
const out = execFileSync('tasklist', ['/FI', `PID eq ${ownerPid}`, '/FO', 'CSV', '/NH'], { encoding: 'utf8', windowsHide: true })
|
|
733
|
-
if (!String(out || '').toLowerCase().includes('node')) return false
|
|
734
|
-
} else if (process.platform === 'linux') {
|
|
735
|
-
const comm = fs.readFileSync(`/proc/${ownerPid}/comm`, 'utf8').trim()
|
|
736
|
-
if (!comm.includes('node')) return false
|
|
737
|
-
}
|
|
738
|
-
} catch { /* inconclusive — trust the owner file (already alive+kind-matched) */ }
|
|
739
|
-
return true
|
|
740
|
-
} catch { return false }
|
|
741
|
-
})()
|
|
742
|
-
if (anotherOwnerAlive) {
|
|
743
|
-
__mixdogMemoryLog('[memory-service] shutdown: another live memory owner holds memory-runtime-owner.json — leaving PG running\n')
|
|
744
|
-
} else {
|
|
745
|
-
const { stopPgForShutdown } = await import('./lib/pg/supervisor.mjs')
|
|
746
|
-
await stopPgForShutdown()
|
|
747
|
-
}
|
|
683
|
+
const { stopPgForShutdown } = await import('./lib/pg/supervisor.mjs')
|
|
684
|
+
await stopPgForShutdown()
|
|
748
685
|
} catch {}
|
|
749
686
|
} else {
|
|
750
687
|
__mixdogMemoryLog('[memory-service] secondary mode; leaving shared PG running\n')
|
|
@@ -811,120 +748,9 @@ function _startHttpServer() {
|
|
|
811
748
|
return _httpReadyPromise
|
|
812
749
|
}
|
|
813
750
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
// graceful shutdown and leaving pgdata in an inconsistent checkpoint state.
|
|
818
|
-
let _stopInFlight = false
|
|
819
|
-
let _syncPgStopRequested = false
|
|
820
|
-
const _workerSignalHandler = (sig) => {
|
|
821
|
-
if (_stopInFlight) {
|
|
822
|
-
__mixdogMemoryLog(`[memory-worker] ${sig} — stop already in flight, ignoring\n`)
|
|
823
|
-
return
|
|
824
|
-
}
|
|
825
|
-
_stopInFlight = true
|
|
826
|
-
_syncPgStopRequested = true
|
|
827
|
-
__mixdogMemoryLog(`[memory-worker] received ${sig} — calling stop() for clean shutdown\n`)
|
|
828
|
-
const _exitTimer = setTimeout(() => {
|
|
829
|
-
__mixdogMemoryLog(`[memory-worker] stop() timed out after 6000ms — forcing exit(2)\n`)
|
|
830
|
-
process.exit(2)
|
|
831
|
-
}, 6000)
|
|
832
|
-
stop().then(() => {
|
|
833
|
-
clearTimeout(_exitTimer)
|
|
834
|
-
__mixdogMemoryLog(`[memory-worker] stop() complete — exiting cleanly\n`)
|
|
835
|
-
process.exit(0)
|
|
836
|
-
}).catch((e) => {
|
|
837
|
-
clearTimeout(_exitTimer)
|
|
838
|
-
__mixdogMemoryLog(`[memory-worker] stop() error on ${sig}: ${e && (e.message || e)}\n`)
|
|
839
|
-
process.exit(1)
|
|
840
|
-
})
|
|
841
|
-
}
|
|
842
|
-
process.on('SIGTERM', () => _workerSignalHandler('SIGTERM'))
|
|
843
|
-
process.on('SIGINT', () => _workerSignalHandler('SIGINT'))
|
|
844
|
-
|
|
845
|
-
// Windows-safe last resort: SIGTERM may TerminateProcess before the async
|
|
846
|
-
// stop() path runs, orphaning PG mid-write. Best-effort sync pg_ctl stop on
|
|
847
|
-
// exit (no-op after a completed graceful stop). Skip in secondary mode — we
|
|
848
|
-
// do not own the shared PG there.
|
|
849
|
-
if (!memorySecondaryMode()) process.on('exit', () => {
|
|
850
|
-
// Do not stop shared PG on an unexpected Memory crash. The singleton proxy
|
|
851
|
-
// will respawn a daemon that can attach to the still-healthy cluster. The
|
|
852
|
-
// sync stop is only a last resort after an explicit shutdown signal began.
|
|
853
|
-
if (_syncPgStopRequested) {
|
|
854
|
-
try { stopPgForShutdownSync() } catch {}
|
|
855
|
-
}
|
|
856
|
-
})
|
|
857
|
-
|
|
858
|
-
// callId → AbortController for in-flight IPC calls (cancel handler uses this).
|
|
859
|
-
const _inFlightCalls = new Map()
|
|
860
|
-
|
|
861
|
-
process.on('message', async (msg) => {
|
|
862
|
-
// Handle parent-initiated graceful shutdown IPC message.
|
|
863
|
-
if (msg.type === 'shutdown') {
|
|
864
|
-
__mixdogMemoryLog('[memory-worker] received IPC shutdown — calling stop()\n')
|
|
865
|
-
_workerSignalHandler('IPC:shutdown')
|
|
866
|
-
return
|
|
867
|
-
}
|
|
868
|
-
if (msg.type === 'cancel' && msg.callId) {
|
|
869
|
-
const entry = _inFlightCalls.get(msg.callId)
|
|
870
|
-
if (entry) {
|
|
871
|
-
// Mark cancelled so the in-flight call's result/error branch below
|
|
872
|
-
// does not double-respond after the AbortController fires.
|
|
873
|
-
entry.cancelled = true
|
|
874
|
-
entry.ac.abort()
|
|
875
|
-
_inFlightCalls.delete(msg.callId)
|
|
876
|
-
sendMemoryWorkerMessage({ type: 'result', callId: msg.callId, error: 'cancelled' })
|
|
877
|
-
}
|
|
878
|
-
return
|
|
879
|
-
}
|
|
880
|
-
if (msg.type !== 'call' || !msg.callId) return
|
|
881
|
-
const entry = { ac: new AbortController(), cancelled: false }
|
|
882
|
-
_inFlightCalls.set(msg.callId, entry)
|
|
883
|
-
try {
|
|
884
|
-
let result
|
|
885
|
-
try {
|
|
886
|
-
result = await handleToolCall(msg.name, msg.args || {}, entry.ac.signal)
|
|
887
|
-
} finally {
|
|
888
|
-
_inFlightCalls.delete(msg.callId)
|
|
889
|
-
}
|
|
890
|
-
if (!entry.cancelled) sendMemoryWorkerMessage({ type: 'result', callId: msg.callId, result })
|
|
891
|
-
} catch (e) {
|
|
892
|
-
if (!entry.cancelled) sendMemoryWorkerMessage({ type: 'result', callId: msg.callId, error: e.message })
|
|
893
|
-
}
|
|
894
|
-
})
|
|
895
|
-
init().catch(e => {
|
|
896
|
-
let detail
|
|
897
|
-
try {
|
|
898
|
-
const parts = []
|
|
899
|
-
if (e?.name) parts.push(`name=${e.name}`)
|
|
900
|
-
if (e?.code) parts.push(`code=${e.code}`)
|
|
901
|
-
if (e?.errno) parts.push(`errno=${e.errno}`)
|
|
902
|
-
if (e?.syscall) parts.push(`syscall=${e.syscall}`)
|
|
903
|
-
if (e?.path) parts.push(`path=${e.path}`)
|
|
904
|
-
if (e?.message) parts.push(`message=${e.message}`)
|
|
905
|
-
let stringified = null
|
|
906
|
-
try { stringified = JSON.stringify(e, Object.getOwnPropertyNames(e || {})) } catch {}
|
|
907
|
-
if (stringified && stringified !== '{}' && stringified !== '"{}"') parts.push(`json=${stringified}`)
|
|
908
|
-
if (e?.stack) parts.push(`\nstack=\n${e.stack}`)
|
|
909
|
-
if (parts.length === 0) parts.push(`raw=${typeof e}:${String(e)}`)
|
|
910
|
-
detail = parts.join(' | ')
|
|
911
|
-
} catch (logErr) {
|
|
912
|
-
detail = `(error formatting failed: ${logErr?.message}) raw=${String(e)}`
|
|
913
|
-
}
|
|
914
|
-
__mixdogMemoryLog(`[memory-worker] init failed: ${detail}\n`)
|
|
915
|
-
// Signal degraded state to parent before exiting so it records the failure
|
|
916
|
-
// rather than treating this as a normal pre-ready crash.
|
|
917
|
-
sendMemoryWorkerMessage({ type: 'ready', degraded: true, error: detail.slice(0, 800) })
|
|
918
|
-
process.exit(1)
|
|
919
|
-
})
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
// Standalone MCP launcher path. When this module is the entry script AND no
|
|
923
|
-
// MIXDOG_WORKER_MODE flag is set, we own stdio and bring up the full MCP
|
|
924
|
-
// server with acquireLock + StdioServerTransport. Server-main spawnWorker
|
|
925
|
-
// also forks this file with MIXDOG_WORKER_MODE='1'; that path uses the IPC
|
|
926
|
-
// handler block above and acquireLock/init() as the single memory owner.
|
|
927
|
-
if (IS_MEMORY_ENTRY && process.env.MIXDOG_WORKER_MODE !== '1') {
|
|
751
|
+
// Standalone MCP launcher path. Product mode imports this module into the
|
|
752
|
+
// unified daemon; running the module directly owns stdio for MCP clients.
|
|
753
|
+
if (IS_MEMORY_ENTRY) {
|
|
928
754
|
;(async () => {
|
|
929
755
|
acquireLock()
|
|
930
756
|
process.on('exit', releaseLock)
|
|
@@ -941,10 +767,12 @@ if (IS_MEMORY_ENTRY && process.env.MIXDOG_WORKER_MODE !== '1') {
|
|
|
941
767
|
process.on('SIGINT', stopFromSignal)
|
|
942
768
|
process.on('SIGTERM', stopFromSignal)
|
|
943
769
|
await init()
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
770
|
+
if (!(process.env.MIXDOG_WORKER_MODE === '1' && process.send)) {
|
|
771
|
+
const transport = new StdioServerTransport()
|
|
772
|
+
await mcp.connect(transport)
|
|
773
|
+
await new Promise((resolve) => { mcp.onclose = resolve })
|
|
774
|
+
await stop()
|
|
775
|
+
}
|
|
948
776
|
})().catch((err) => {
|
|
949
777
|
__mixdogMemoryLog(`[memory-service] startup failed: ${err.stack || err.message}\n`)
|
|
950
778
|
process.exit(1)
|