shennian 0.5.0 → 0.5.2
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/README.md +2 -2
- package/dist/publish-build-manifest.json +165 -125
- package/dist/src/agents/acp/adapter.js +2 -2
- package/dist/src/agents/acp/capability-cache.js +2 -2
- package/dist/src/agents/acp/catalog.js +2 -2
- package/dist/src/agents/acp/manifests.js +2 -2
- package/dist/src/agents/claude.js +8 -6
- package/dist/src/agents/codex.js +2 -2
- package/dist/src/agents/command-spec.js +4 -4
- package/dist/src/agents/cursor.js +1 -1
- package/dist/src/agents/custom-recovery-conformance.js +2 -2
- package/dist/src/agents/gemini.js +1 -1
- package/dist/src/agents/model-registry/discovery.js +3 -3
- package/dist/src/agents/model-registry/service.js +1 -1
- package/dist/src/agents/model-registry.js +1 -1
- package/dist/src/agents/openclaw.js +2 -2
- package/dist/src/agents/opencode.js +1 -1
- package/dist/src/agents/pi-coding-agent.js +3 -4
- package/dist/src/agents/pi-session-ownership.js +2 -2
- package/dist/src/agents/spawn-errors.js +1 -0
- package/dist/src/agents/windows-agent-paths.js +1 -0
- package/dist/src/commands/agent-readiness.js +2 -2
- package/dist/src/commands/daemon-service-spec.js +1 -1
- package/dist/src/commands/daemon.js +6 -6
- package/dist/src/commands/queue.js +1 -0
- package/dist/src/commands/room.js +3 -3
- package/dist/src/config/index.js +2 -2
- package/dist/src/fs/atomic-rename.js +1 -0
- package/dist/src/index.js +3 -3
- package/dist/src/native-fusion/claude-entry-parser.js +7 -0
- package/dist/src/native-fusion/local-repository.js +2 -2
- package/dist/src/native-fusion/native-source-deletions.js +2 -2
- package/dist/src/native-fusion/parsers.js +1 -3
- package/dist/src/native-fusion/state.js +2 -2
- package/dist/src/personal-sync/epoch.js +2 -2
- package/dist/src/personal-sync/identity.js +2 -2
- package/dist/src/relay/client.js +1 -1
- package/dist/src/room/activation-service.js +6 -6
- package/dist/src/room/attachment-cache.js +2 -2
- package/dist/src/room/host-session-observations.js +2 -2
- package/dist/src/room/managed-context.js +1 -1
- package/dist/src/room/managed-room-ipc.js +2 -2
- package/dist/src/room/mirror-sync-service.js +1 -1
- package/dist/src/room/public-attachment-cache.js +2 -2
- package/dist/src/room/room-error-guidance.js +1 -0
- package/dist/src/room/session-registry.js +2 -2
- package/dist/src/security/managed-agent-policy.js +1 -1
- package/dist/src/security/managed-agent-runtime.js +1 -1
- package/dist/src/session/attachment-transfer-store.js +2 -2
- package/dist/src/session/canonical-store.js +5 -5
- package/dist/src/session/deletion-sync-state.js +2 -2
- package/dist/src/session/handlers/agent-workspace-validation.js +1 -1
- package/dist/src/session/handlers/chat-adapter-config.js +1 -1
- package/dist/src/session/handlers/chat-events.js +2 -2
- package/dist/src/session/handlers/chat-recovery.js +1 -1
- package/dist/src/session/handlers/chat.js +1 -1
- package/dist/src/session/manager.js +1 -1
- package/dist/src/session/native-cleanup-outbox.js +2 -2
- package/dist/src/session/queue-diagnostics.js +1 -0
- package/dist/src/session/queue-dispatch-failure.js +1 -0
- package/dist/src/session/queue-helpers.js +5 -5
- package/dist/src/session/queue-retry.js +1 -1
- package/dist/src/session/queue-storage.js +2 -2
- package/dist/src/session/queue.js +1 -1
- package/dist/src/session/room-reply-notice.js +1 -0
- package/dist/src/session/run-recovery/journal.js +2 -2
- package/dist/src/session/run-stall.js +1 -0
- package/dist/src/session/store.js +2 -2
- package/dist/src/session/tool-detail-store.js +2 -2
- package/node_modules/@shennian/wire/dist/agent-capabilities.js +1 -1
- package/node_modules/@shennian/wire/dist/agent-workspace.js +1 -144
- package/node_modules/@shennian/wire/dist/envelope.js +1 -1
- package/node_modules/@shennian/wire/dist/events.js +1 -1
- package/node_modules/@shennian/wire/dist/external-message-format.js +3 -70
- package/node_modules/@shennian/wire/dist/frames.js +1 -1
- package/node_modules/@shennian/wire/dist/fs.js +2 -7
- package/node_modules/@shennian/wire/dist/index.js +1 -21
- package/node_modules/@shennian/wire/dist/machine.js +1 -1
- package/node_modules/@shennian/wire/dist/message-payload.js +8 -307
- package/node_modules/@shennian/wire/dist/methods.js +1 -3
- package/node_modules/@shennian/wire/dist/native-session.js +1 -1
- package/node_modules/@shennian/wire/dist/project-fs.js +1 -462
- package/node_modules/@shennian/wire/dist/project-path.js +1 -25
- package/node_modules/@shennian/wire/dist/project.js +1 -3
- package/node_modules/@shennian/wire/dist/relay-connectivity.js +1 -29
- package/node_modules/@shennian/wire/dist/room.js +1 -20
- package/node_modules/@shennian/wire/dist/schedule.js +1 -1
- package/node_modules/@shennian/wire/dist/session-sync.js +1 -123
- package/node_modules/@shennian/wire/dist/session.js +1 -60
- package/node_modules/@shennian/wire/dist/tool-detail.js +1 -9
- package/node_modules/@shennian/wire/dist/voice-chief.js +1 -3
- package/package.json +3 -8
- package/dist/bin/shennian.d.ts +0 -2
- package/dist/src/agent-env.d.ts +0 -44
- package/dist/src/agents/acp/adapter.d.ts +0 -82
- package/dist/src/agents/acp/auth-state.d.ts +0 -3
- package/dist/src/agents/acp/auth.d.ts +0 -7
- package/dist/src/agents/acp/capability-cache.d.ts +0 -14
- package/dist/src/agents/acp/catalog.d.ts +0 -11
- package/dist/src/agents/acp/client-services.d.ts +0 -37
- package/dist/src/agents/acp/discovery.d.ts +0 -10
- package/dist/src/agents/acp/events.d.ts +0 -4
- package/dist/src/agents/acp/manifests.d.ts +0 -63
- package/dist/src/agents/acp/metrics.d.ts +0 -24
- package/dist/src/agents/acp/package-commands.d.ts +0 -4
- package/dist/src/agents/acp/process-client.d.ts +0 -41
- package/dist/src/agents/acp/process-tree.d.ts +0 -2
- package/dist/src/agents/acp/types.d.ts +0 -31
- package/dist/src/agents/acp/watcher.d.ts +0 -22
- package/dist/src/agents/adapter.d.ts +0 -180
- package/dist/src/agents/auth-status.d.ts +0 -4
- package/dist/src/agents/claude-managed-permissions.d.ts +0 -33
- package/dist/src/agents/claude.d.ts +0 -69
- package/dist/src/agents/codex-managed-permissions.d.ts +0 -32
- package/dist/src/agents/codex-managed-room-tools.d.ts +0 -41
- package/dist/src/agents/codex-protocol.d.ts +0 -103
- package/dist/src/agents/codex-runtime.d.ts +0 -91
- package/dist/src/agents/codex-utils.d.ts +0 -29
- package/dist/src/agents/codex.d.ts +0 -59
- package/dist/src/agents/command-spec.d.ts +0 -55
- package/dist/src/agents/config-status.d.ts +0 -18
- package/dist/src/agents/cursor-managed-permissions.d.ts +0 -28
- package/dist/src/agents/cursor.d.ts +0 -44
- package/dist/src/agents/custom-managed-runtime.d.ts +0 -37
- package/dist/src/agents/custom-recovery-conformance.d.ts +0 -2
- package/dist/src/agents/custom.d.ts +0 -62
- package/dist/src/agents/detect.d.ts +0 -23
- package/dist/src/agents/event-terminal-gate.d.ts +0 -16
- package/dist/src/agents/external-channel-instructions.d.ts +0 -4
- package/dist/src/agents/gemini.d.ts +0 -32
- package/dist/src/agents/manager.d.ts +0 -57
- package/dist/src/agents/model-registry/cache.d.ts +0 -4
- package/dist/src/agents/model-registry/discovery.d.ts +0 -4
- package/dist/src/agents/model-registry/opencode-api.d.ts +0 -2
- package/dist/src/agents/model-registry/parsers.d.ts +0 -20
- package/dist/src/agents/model-registry/runner.d.ts +0 -6
- package/dist/src/agents/model-registry/service.d.ts +0 -10
- package/dist/src/agents/model-registry/types.d.ts +0 -39
- package/dist/src/agents/model-registry.d.ts +0 -17
- package/dist/src/agents/native-capabilities.d.ts +0 -10
- package/dist/src/agents/openclaw.d.ts +0 -29
- package/dist/src/agents/opencode-managed-permissions.d.ts +0 -25
- package/dist/src/agents/opencode.d.ts +0 -46
- package/dist/src/agents/pi-coding-agent-managed-permissions.d.ts +0 -7
- package/dist/src/agents/pi-coding-agent.d.ts +0 -63
- package/dist/src/agents/pi-managed-extension.d.ts +0 -12
- package/dist/src/agents/pi-managed-model-broker.d.ts +0 -27
- package/dist/src/agents/pi-managed-model-broker.js +0 -1
- package/dist/src/agents/pi-rpc-client.d.ts +0 -31
- package/dist/src/agents/pi-session-ownership.d.ts +0 -2
- package/dist/src/agents/platform-instructions.d.ts +0 -5
- package/dist/src/agents/runtime-compatibility.d.ts +0 -11
- package/dist/src/agents/workbuddy-managed-permissions.d.ts +0 -37
- package/dist/src/agents/workbuddy.d.ts +0 -63
- package/dist/src/commands/agent-readiness.d.ts +0 -17
- package/dist/src/commands/agent.d.ts +0 -2
- package/dist/src/commands/daemon-instance-lock.d.ts +0 -21
- package/dist/src/commands/daemon-process.d.ts +0 -6
- package/dist/src/commands/daemon-service-spec.d.ts +0 -26
- package/dist/src/commands/daemon-start-wait.d.ts +0 -9
- package/dist/src/commands/daemon-state.d.ts +0 -57
- package/dist/src/commands/daemon-windows.d.ts +0 -33
- package/dist/src/commands/daemon.d.ts +0 -67
- package/dist/src/commands/integration.d.ts +0 -3
- package/dist/src/commands/logout.d.ts +0 -3
- package/dist/src/commands/manager.d.ts +0 -2
- package/dist/src/commands/pair-authorization.d.ts +0 -3
- package/dist/src/commands/pair-browser.d.ts +0 -44
- package/dist/src/commands/pair-qr.d.ts +0 -4
- package/dist/src/commands/pair.d.ts +0 -19
- package/dist/src/commands/room.d.ts +0 -16
- package/dist/src/commands/runtime.d.ts +0 -2
- package/dist/src/commands/schedule.d.ts +0 -2
- package/dist/src/commands/tools.d.ts +0 -2
- package/dist/src/commands/upgrade.d.ts +0 -31
- package/dist/src/commands/worker.d.ts +0 -11
- package/dist/src/config/index.d.ts +0 -58
- package/dist/src/daemon-ipc/agent-readiness.d.ts +0 -15
- package/dist/src/daemon-ipc/client.d.ts +0 -8
- package/dist/src/daemon-ipc/control.d.ts +0 -16
- package/dist/src/daemon-ipc/json.d.ts +0 -3
- package/dist/src/daemon-ipc/paths.d.ts +0 -15
- package/dist/src/daemon-ipc/protocol.d.ts +0 -31
- package/dist/src/daemon-ipc/secret.d.ts +0 -3
- package/dist/src/daemon-ipc/server.d.ts +0 -20
- package/dist/src/daemon-log.d.ts +0 -9
- package/dist/src/env-path.d.ts +0 -15
- package/dist/src/fs/boundary.d.ts +0 -23
- package/dist/src/fs/handler.d.ts +0 -26
- package/dist/src/fs/security.d.ts +0 -2
- package/dist/src/fs/text-decoder.d.ts +0 -10
- package/dist/src/index.d.ts +0 -1
- package/dist/src/log-redaction.d.ts +0 -4
- package/dist/src/log-reporter.d.ts +0 -41
- package/dist/src/manager/prompt.d.ts +0 -2
- package/dist/src/manager/registry.d.ts +0 -184
- package/dist/src/manager/retired-external-channel-compat.d.ts +0 -78
- package/dist/src/manager/runtime.d.ts +0 -90
- package/dist/src/manager/worker-ipc.d.ts +0 -28
- package/dist/src/manager/worker-markdown.d.ts +0 -10
- package/dist/src/native-fusion/codex-files.d.ts +0 -10
- package/dist/src/native-fusion/codex-message-parser.d.ts +0 -9
- package/dist/src/native-fusion/codex-parser.d.ts +0 -8
- package/dist/src/native-fusion/codex-user-input.d.ts +0 -11
- package/dist/src/native-fusion/config.d.ts +0 -1
- package/dist/src/native-fusion/file-identity.d.ts +0 -9
- package/dist/src/native-fusion/file-watcher.d.ts +0 -26
- package/dist/src/native-fusion/local-repository.d.ts +0 -90
- package/dist/src/native-fusion/native-source-deletions.d.ts +0 -47
- package/dist/src/native-fusion/opencode-parser.d.ts +0 -29
- package/dist/src/native-fusion/parser-common.d.ts +0 -35
- package/dist/src/native-fusion/parsers.d.ts +0 -13
- package/dist/src/native-fusion/service.d.ts +0 -64
- package/dist/src/native-fusion/session-header.d.ts +0 -13
- package/dist/src/native-fusion/session-native-sources.d.ts +0 -24
- package/dist/src/native-fusion/source-visibility-audit.d.ts +0 -16
- package/dist/src/native-fusion/source-visibility.d.ts +0 -25
- package/dist/src/native-fusion/state.d.ts +0 -4
- package/dist/src/native-fusion/types.d.ts +0 -82
- package/dist/src/personal-sync/epoch.d.ts +0 -17
- package/dist/src/personal-sync/identity.d.ts +0 -1
- package/dist/src/personal-sync/machine-authority.d.ts +0 -12
- package/dist/src/personal-sync/metrics.d.ts +0 -25
- package/dist/src/personal-sync/paths.d.ts +0 -5
- package/dist/src/region.d.ts +0 -15
- package/dist/src/relay/client.d.ts +0 -81
- package/dist/src/room/activation-audit.d.ts +0 -15
- package/dist/src/room/activation-policy.d.ts +0 -8
- package/dist/src/room/activation-service.d.ts +0 -77
- package/dist/src/room/attachment-cache.d.ts +0 -44
- package/dist/src/room/attachment-upload.d.ts +0 -20
- package/dist/src/room/device-authorization-client.d.ts +0 -91
- package/dist/src/room/host-session-observations.d.ts +0 -54
- package/dist/src/room/invite-bootstrap.d.ts +0 -49
- package/dist/src/room/invite-qr.d.ts +0 -6
- package/dist/src/room/live-delivery.d.ts +0 -5
- package/dist/src/room/managed-context.d.ts +0 -49
- package/dist/src/room/managed-prompt-composer.d.ts +0 -47
- package/dist/src/room/managed-room-binding.d.ts +0 -69
- package/dist/src/room/managed-room-ipc.d.ts +0 -65
- package/dist/src/room/mirror-sync-service.d.ts +0 -49
- package/dist/src/room/public-attachment-cache.d.ts +0 -34
- package/dist/src/room/public-room-client.d.ts +0 -37
- package/dist/src/room/registration-authority.d.ts +0 -4
- package/dist/src/room/room-action-client-types.d.ts +0 -137
- package/dist/src/room/room-action-client.d.ts +0 -116
- package/dist/src/room/room-binding-client.d.ts +0 -62
- package/dist/src/room/session-registry.d.ts +0 -158
- package/dist/src/runtime-distribution.d.ts +0 -7
- package/dist/src/schedules/personal-context.d.ts +0 -2
- package/dist/src/schedules/server-client.d.ts +0 -19
- package/dist/src/security/managed-agent-credential-paths.d.ts +0 -6
- package/dist/src/security/managed-agent-executable.d.ts +0 -19
- package/dist/src/security/managed-agent-policy.d.ts +0 -66
- package/dist/src/security/managed-agent-runtime.d.ts +0 -44
- package/dist/src/session/archive-zip.d.ts +0 -10
- package/dist/src/session/attachment-reference.d.ts +0 -2
- package/dist/src/session/attachment-transfer-store.d.ts +0 -45
- package/dist/src/session/canonical-store.d.ts +0 -104
- package/dist/src/session/deletion-sync-state.d.ts +0 -20
- package/dist/src/session/deletion-sync-validation.d.ts +0 -2
- package/dist/src/session/deletion-synchronizer.d.ts +0 -9
- package/dist/src/session/handlers/agent-capabilities.d.ts +0 -3
- package/dist/src/session/handlers/agent-config.d.ts +0 -7
- package/dist/src/session/handlers/agent-control.d.ts +0 -4
- package/dist/src/session/handlers/agent-workspace-validation.d.ts +0 -28
- package/dist/src/session/handlers/agents.d.ts +0 -11
- package/dist/src/session/handlers/chat-adapter-config.d.ts +0 -11
- package/dist/src/session/handlers/chat-context.d.ts +0 -31
- package/dist/src/session/handlers/chat-events.d.ts +0 -5
- package/dist/src/session/handlers/chat-recovery.d.ts +0 -4
- package/dist/src/session/handlers/chat-session-lifecycle.d.ts +0 -9
- package/dist/src/session/handlers/chat.d.ts +0 -6
- package/dist/src/session/handlers/control.d.ts +0 -5
- package/dist/src/session/handlers/fs.d.ts +0 -14
- package/dist/src/session/handlers/message-status.d.ts +0 -3
- package/dist/src/session/handlers/pi-validation-session.d.ts +0 -7
- package/dist/src/session/handlers/pi-validation-session.js +0 -1
- package/dist/src/session/handlers/project-fs.d.ts +0 -11
- package/dist/src/session/handlers/remote-access.d.ts +0 -4
- package/dist/src/session/handlers/room-managed.d.ts +0 -6
- package/dist/src/session/handlers/session-refresh.d.ts +0 -3
- package/dist/src/session/handlers/title.d.ts +0 -3
- package/dist/src/session/handlers/tool-detail.d.ts +0 -3
- package/dist/src/session/handlers/voice-window.d.ts +0 -3
- package/dist/src/session/history-subscriptions.d.ts +0 -29
- package/dist/src/session/index-publisher.d.ts +0 -3
- package/dist/src/session/manager-event-authority.d.ts +0 -3
- package/dist/src/session/manager.d.ts +0 -95
- package/dist/src/session/native-cleanup-outbox.d.ts +0 -64
- package/dist/src/session/native-session-lifecycle.d.ts +0 -56
- package/dist/src/session/project-fs-store.d.ts +0 -43
- package/dist/src/session/projection.d.ts +0 -3
- package/dist/src/session/queue-control.d.ts +0 -27
- package/dist/src/session/queue-helpers.d.ts +0 -20
- package/dist/src/session/queue-message.d.ts +0 -35
- package/dist/src/session/queue-retry.d.ts +0 -11
- package/dist/src/session/queue-storage.d.ts +0 -8
- package/dist/src/session/queue-types.d.ts +0 -31
- package/dist/src/session/queue.d.ts +0 -73
- package/dist/src/session/queued-chat-dispatch.d.ts +0 -12
- package/dist/src/session/run-recovery/barrier.d.ts +0 -12
- package/dist/src/session/run-recovery/coordinator.d.ts +0 -32
- package/dist/src/session/run-recovery/journal.d.ts +0 -30
- package/dist/src/session/run-recovery/schema.d.ts +0 -48
- package/dist/src/session/store.d.ts +0 -128
- package/dist/src/session/tool-detail-store.d.ts +0 -17
- package/dist/src/session/turn-trigger.d.ts +0 -43
- package/dist/src/session/types.d.ts +0 -93
- package/dist/src/tools/markdown-to-pdf.d.ts +0 -42
- package/dist/src/upgrade/channel.d.ts +0 -5
- package/dist/src/upgrade/distribution.d.ts +0 -21
- package/dist/src/upgrade/engine.d.ts +0 -104
- package/dist/src/upgrade/scheduler.d.ts +0 -60
- package/dist/src/upgrade/updater-bootstrap.d.ts +0 -12
- package/dist/src/upgrade/updater-launcher.d.ts +0 -37
- package/dist/src/upgrade/updater-protocol.d.ts +0 -40
- package/dist/src/upgrade/updater-service-entry.d.ts +0 -7
- package/dist/src/upgrade/updater-worker.d.ts +0 -57
- package/dist/src/windows-shell.d.ts +0 -6
- package/node_modules/@shennian/wire/dist/agent-capabilities.d.ts +0 -16
- package/node_modules/@shennian/wire/dist/agent-workspace.d.ts +0 -133
- package/node_modules/@shennian/wire/dist/envelope.d.ts +0 -7
- package/node_modules/@shennian/wire/dist/events.d.ts +0 -125
- package/node_modules/@shennian/wire/dist/external-message-format.d.ts +0 -37
- package/node_modules/@shennian/wire/dist/frames.d.ts +0 -33
- package/node_modules/@shennian/wire/dist/fs.d.ts +0 -107
- package/node_modules/@shennian/wire/dist/index.d.ts +0 -21
- package/node_modules/@shennian/wire/dist/machine.d.ts +0 -160
- package/node_modules/@shennian/wire/dist/message-payload.d.ts +0 -71
- package/node_modules/@shennian/wire/dist/methods.d.ts +0 -5
- package/node_modules/@shennian/wire/dist/native-session.d.ts +0 -20
- package/node_modules/@shennian/wire/dist/project-fs.d.ts +0 -146
- package/node_modules/@shennian/wire/dist/project-path.d.ts +0 -4
- package/node_modules/@shennian/wire/dist/project.d.ts +0 -16
- package/node_modules/@shennian/wire/dist/relay-connectivity.d.ts +0 -30
- package/node_modules/@shennian/wire/dist/room.d.ts +0 -190
- package/node_modules/@shennian/wire/dist/schedule.d.ts +0 -37
- package/node_modules/@shennian/wire/dist/session-sync.d.ts +0 -406
- package/node_modules/@shennian/wire/dist/session.d.ts +0 -465
- package/node_modules/@shennian/wire/dist/tool-detail.d.ts +0 -38
- package/node_modules/@shennian/wire/dist/voice-chief.d.ts +0 -116
|
@@ -1 +1 @@
|
|
|
1
|
-
import R from"node:crypto";import{getRegisteredAgents as b,unregisterAgent as k}from"../agents/adapter.js";import{resetCommandSpecCache as S}from"../agents/command-spec.js";import{loadConfig as w}from"../config/index.js";import{handleUpgradeStart as I,handleUpgradeStatus as A}from"../commands/upgrade.js";import{handleAgentsRefresh as T,handleModelsRefresh as P,refreshMachineAgents as C}from"./handlers/agents.js";import{AcpDiscoveryWatcher as M}from"../agents/acp/watcher.js";import{handleAgentCapabilitiesList as x}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as D,handleAgentConfigGet as F,handleAgentConfigTest as E,handleAgentConfigUpsert as Q}from"./handlers/agent-config.js";import{handleChatAbort as j,handleChatSend as z}from"./handlers/chat.js";import{recoverJournaledRun as B}from"./handlers/chat-recovery.js";import{handleSessionRefresh as O}from"./handlers/session-refresh.js";import{handleSessionToolDetail as W}from"./handlers/tool-detail.js";import{handleSessionTitleSet as H}from"./handlers/title.js";import{handleSessionMessageStatus as U}from"./handlers/message-status.js";import{handleAgentWorkspaceValidation as _}from"./handlers/agent-workspace-validation.js";import{handleVoiceSessionBodyWindow as J}from"./handlers/voice-window.js";import{handleRemoteAccessPause as $}from"./handlers/remote-access.js";import{cleanupPendingTransfers as V,handleFsLs as L,handleFsRead as N,handleFsRename as G,handleFsWrite as K,handleFsTransferAbort as X,handleFsTransferChunk as Z,handleFsTransferFinish as Y,handleFsTransferStart as q,handleFsExportMarkdownPdf as ee,handleFsExportMarkdownPdfSetup as se,handleFsArchiveZip as te}from"./handlers/fs.js";import{handleRegionProbe as ae,handleRegionSwitch as re,handleUpgradeSetPolicy as ne}from"./handlers/control.js";import{ManagerRuntimeService as ie,setManagerRuntimeService as u}from"../manager/runtime.js";import{ChatQueueManager as oe}from"./queue.js";import{createAuthorizedFsRoot as ce,createAuthorizedFsRootAsync as le,resolveAuthorizedPath as he,resolveAuthorizedPathAsync as ue,resolveSessionWorkDir as de}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/pi-coding-agent.js";import"../agents/manager.js";import{registerCustomAgent as me}from"../agents/custom.js";import{handleManagedRoomBind as pe,handleManagedRoomRestart as ge,discardPreBindingSession as fe}from"./handlers/room-managed.js";import{getDaemonInstallationId as d,listSessionRecords as h,purgeCanonicalSession as ve,purgeSessionRecord as ye,recordSession as Re,upsertMessage as be}from"./store.js";import{requestSessionIndexPublish as ke}from"./index-publisher.js";import{reportUpgradeAggregateMetric as Se}from"../log-reporter.js";import{PersonalHistorySubscriptions as we}from"./history-subscriptions.js";import{sweepAttachmentTransfers as Ie}from"./attachment-transfer-store.js";import{NativeSourceDeletionStore as Ae}from"../native-fusion/native-source-deletions.js";import{collectLocalNativeSources as Te}from"../native-fusion/session-native-sources.js";import{purgeToolDetails as Pe}from"./tool-detail-store.js";import{NativeSessionCleanupOutbox as Ce}from"./native-cleanup-outbox.js";import{assertPersonalSyncIdentity as o}from"../personal-sync/epoch.js";import{ActiveRunJournal as Me}from"./run-recovery/journal.js";import{RunRecoveryBarrier as xe}from"./run-recovery/barrier.js";import{RunRecoveryCoordinator as De}from"./run-recovery/coordinator.js";import{ProjectFsHandleStore as Fe}from"./project-fs-store.js";import{handleProjectFsRequest as Ee}from"./handlers/project-fs.js";import{handleAgentPermissionResponse as Qe,handleAcpAgentRequest as je}from"./handlers/agent-control.js";import{SessionDeletionSynchronizer as ze}from"./deletion-synchronizer.js";import{dispatchManagedChat as Be,dispatchQueuedChat as Oe,interruptQueuedChat as We}from"./queued-chat-dispatch.js";const He=50;import{resolveSessionWorkDir as Js}from"../fs/boundary.js";function Ue(){return"\u795E\u5FF5\u5347\u7EA7\u4E2D\u65AD\u4E86\u672C\u6B21\u8FD0\u884C\u3002\u5DF2\u5B8C\u6210\u7684\u56DE\u590D\u6216\u64CD\u4F5C\u4ECD\u7136\u6709\u6548\uFF0C\u672A\u5B8C\u6210\u90E8\u5206\u53EF\u91CD\u8BD5\u3002\u539F\u4F1A\u8BDD\u5DF2\u4FDD\u7559\u3002"}class Hs{client;nativeFusion;cliVersion;upgradePolicyController;managedRoomBinder;remoteAccessPauseController;managedRoomContextRevoker;managedRoomExecutor;trustedProjectFsRequestResolver;getAgentSnapshot;scheduleHandler;getScheduleQueue(){return this.chatQueue}sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;historySubscriptions;nativeCleanupOutbox;activityProbeTimer=null;attachmentCleanupTimer=null;activeRequests=0;acpDiscoveryWatcher;runJournal;recoveryBarrier=new xe;recoveryCoordinator;recoveryPass=null;prepareManagedRecovery;projectFsHandleStore=new Fe;deletionSynchronizer;constructor(e,t=null,s,n=null,r=null,l=null,m=null,p=null,g=null,f=null,v=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=n,this.managedRoomBinder=r,this.remoteAccessPauseController=l,this.managedRoomContextRevoker=m,this.managedRoomExecutor=p,this.trustedProjectFsRequestResolver=f,this.getAgentSnapshot=v,this.runJournal=g??new Me(d());for(const a of this.runJournal.loadPendingReconciliation().records)this.recoveryBarrier.begin(a.sessionId);this.recoveryCoordinator=new De({journal:this.runJournal,barrier:this.recoveryBarrier,recover:(a,i)=>B(this.getRuntime(),a,i),commitTerminal:(a,i)=>this.commitRecoveryTerminal(a,i),isCanonicalTerminal:a=>{const i=h().find(y=>y.sessionId===a.sessionId),c=`terminal:${R.createHash("sha256").update(`${a.runId}\0`).digest("hex")}`;return i?.lastAttentionId===c},onOutcome:a=>Se({kind:"recovery",adapterType:a.adapterType,result:a.result,stage:a.result==="continued"?"continue":a.result==="reattached"?"reattach":a.result==="resumed"?"resume":a.result==="terminal_reconciled"?"inspect":"terminal",durationMs:a.durationMs,retries:Math.max(0,a.attempts-1),...a.reason?{errorCode:a.reason}:{}})}),this.managerRuntime=new ie({getRuntime:()=>this.getRuntime(),getAgentSnapshot:this.getAgentSnapshot??void 0,dispatchReq:a=>this.handleReq(a,{propagateErrors:!0})}),this.chatQueue=new oe({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a),dispatchManagedReq:(a,i)=>Be(this.getRuntime(),a,i),dispatchQueuedReq:(a,i)=>Oe(this.getRuntime(),a,i),interruptQueuedSession:a=>We(this.getRuntime(),a)}),this.deletionSynchronizer=new ze(e,a=>this.applySessionDeletion(a)),this.historySubscriptions=new we(this.client),this.nativeCleanupOutbox=new Ce({logger:console.info}),this.acpDiscoveryWatcher=new M(async()=>{S(),await C(this.getRuntime())}),this.nativeFusion?.setExternalTerminalHandler?.(a=>{this.handleExternalTerminal(a)}),this.nativeFusion?.setExternalClaimHandler?.((a,i)=>{this.chatQueue.noteExternalClaim(a,i)}),this.nativeCleanupOutbox.start(),u(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents();try{this.acpDiscoveryWatcher.start()}catch(a){console.warn(`[acp.discovery] watcher unavailable: ${a instanceof Error?a.message:String(a)}`)}this.activityProbeTimer=setInterval(()=>{this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.(),this.attachmentCleanupTimer=setInterval(()=>{const a=new Set([...h().map(i=>i.workDir),...Array.from(this.pendingTransfers.values()).map(i=>i.rootPath)]);for(const i of a)try{Ie(this.resolvePath(i))}catch(c){console.error("[attachment.cleanup] failed",c instanceof Error?c.message:String(c))}},6e4),this.attachmentCleanupTimer.unref?.()}executeManagedManagerAction(e){return this.managerRuntime.executeScopedWorkerAction(e.managerSessionId,e.action,e.params,e.roomOrigin)}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),resolveAuthorizedPathAsync:(e,t)=>this.resolveAuthorizedPathAsync(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController,revokeManagedRoomContextToken:this.managedRoomContextRevoker,managedRoomExecutor:this.managedRoomExecutor,runJournal:this.runJournal,recoveryBarrier:this.recoveryBarrier,prepareManagedRecovery:this.prepareManagedRecovery}}async resumePendingAcpAuthentication(e){const t=[...this.sessions.values()].find(s=>s.agentType===e&&s.adapter.hasPendingAuthenticationRetry?.());return t?.adapter.resumeAfterExternalAuthentication?(await t.adapter.resumeAfterExternalAuthentication(),!0):!1}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}prepareForUpgrade(e){this.recoveryBarrier.freezeDispatch();const t=this.runJournal.markPlannedUpgrade(e);return this.runJournal.sync(),{activeRunCount:t}}cancelUpgradePreparation(){this.recoveryBarrier.unfreezeDispatch()}async recoverInterruptedRuns(){this.recoveryPass??=this.recoveryCoordinator.recoverAll(),await this.recoveryPass}getPendingRecoveryCount(){return this.runJournal.loadPendingReconciliation().records.length}revokeProjectFsHandles(){this.projectFsHandleStore.revokeAll()}async commitRecoveryTerminal(e,t){const s=this.sessions.get(e.sessionId);s&&(s.currentRunId=null,s.currentRunPhase=null,s.journalRunId=null,s.heartbeatTimer&&(clearInterval(s.heartbeatTimer),s.heartbeatTimer=null)),this.runTextAcc.delete(`${e.sessionId}:${e.providerRunId??e.runId}`),this.publishSessionActivity(e.sessionId,null);const n=Ue();be(e.sessionId,{id:`upgrade-recovery-terminal-${e.runId}`,sessionId:e.sessionId,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:"error",content:n,error:!0,recoveryState:t.result,recoveryReason:t.reason})}),Re({sessionId:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,workDir:e.workDir,agentSessionId:e.agentSessionId,modelId:e.modelId,status:"failed",attentionId:`upgrade-recovery:${e.runId}`,lastActivityAt:new Date().toISOString()}),this.managerRuntime.noteAgentEvent(e.sessionId,{state:"error",runId:e.providerRunId??e.runId,seq:e.lastObservedEventSeq+1,message:n}),ke(this.client);const r=e.lastObservedEventSeq+1;this.client.sendAgentEvent({type:"event",event:"agent",payload:t.result==="interrupted_by_upgrade"?{state:"interrupted_by_upgrade",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason}:{state:"recovery_failed",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason,...t.message?{message:t.message}:{}},seq:r,id:`agent-recovery-terminal-${e.runId}`}),this.chatQueue.noteTerminal(e.sessionId)}setManagedRoomTurnPreparer(e){this.chatQueue.setManagedRoomTurnPreparer(e)}setManagedAgentDirectTurnPreparer(e){this.chatQueue.setManagedAgentDirectTurnPreparer(e)}setManagedRecoveryPreparer(e){this.prepareManagedRecovery=e}async enqueueManagedRoomBatch(e){const t=e.map(s=>{const n=h().find(r=>r.sessionId===s.params.sessionId);return{context:s.context,params:{...s.params,modelId:n?.modelId??s.params.modelId,sessionMode:n?.sessionMode??s.params.sessionMode,managerConfig:n?.managerConfig??s.params.managerConfig,managerDefaultWorkerAgentType:n?.managerDefaultWorkerAgentType??s.params.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:n?.managerDefaultWorkerModelId??s.params.managerDefaultWorkerModelId}}});await this.chatQueue.enqueueManagedRoomBatch(t)}async retireManagedRoomSession(e){this.chatQueue.purgeSession(e),await fe(this.getRuntime(),e)}discardPendingManagedRoomMessages(e){return this.chatQueue.discardPendingManagedRoomMessages(e)}async synchronizeSessionDeletions(){await this.deletionSynchronizer.synchronize()}async applySessionDeletion(e){const t=new Ae({daemonInstallationId:d()});let s=[];try{s=Te(e.sessionId,{records:h()})}catch(r){console.warn("[session.deletions] local native source lookup failed",{error:r instanceof Error?r.message:String(r)})}t.recordSession(e);for(const r of[...e.sources,...s]){const l=t.find(r.agentType,r.sourceSessionKey);l&&l.sessionId!==e.sessionId||t.record({...e,...r})}this.runJournal.markSessionAborted(e.sessionId),this.recoveryBarrier.end(e.sessionId);const n=this.sessions.get(e.sessionId);if(n){this.revokeManagedRoomToken(n);try{await n.adapter.stop()}catch{}this.sessions.delete(e.sessionId)}this.historySubscriptions.closeSession(e.sessionId),this.nativeFusion?.handleSessionDeleted(e.sessionId),this.chatQueue.purgeSession(e.sessionId),Pe(e.sessionId),ve(e.sessionId),ye(e.sessionId),this.runTextAcc.delete(e.sessionId),this.publishSessionActivity(e.sessionId,null),this.nativeCleanupOutbox.enqueue(e),this.nativeCleanupOutbox.kick()}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async handleExternalTerminal(e){const t=this.sessions.get(e);t&&(t.journalRunId&&(this.recoveryCoordinator.completeFromProvider(e,t.journalRunId),t.journalRunId=null),this.sessions.delete(e),this.revokeManagedRoomToken(t),t.heartbeatTimer&&clearInterval(t.heartbeatTimer),t.adapter.removeAllListeners(),await t.adapter.stop().catch(()=>{})),this.chatQueue.noteTerminal(e)}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(t.heartbeatTimer||!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const n=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:n,canStop:s.canStop??!0});const r=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:r,runPhase:s.runPhase,canStop:s.canStop??!0},seq:r,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of b())t.startsWith("custom:")&&k(t);const e=w();for(const[t,s]of Object.entries(e.customAgents??{}))me(t,s)}async handleReq(e,t={}){const s=this.getRuntime();let n;this.activeRequests++;try{switch(e.method){case"schedule.deliver":if(!this.scheduleHandler)throw new Error("schedules_unavailable");await this.scheduleHandler(e);break;case"chat.send":if(e.params.scheduledDelivery)throw new Error("schedule_source_untrusted");o(e.params),this.recoveryBarrier.isDispatchFrozen()||this.recoveryBarrier.isRecovering(String(e.params.sessionId??""))?n={durableQueueHandoff:await this.chatQueue.handleEnqueue({...e,method:"chat.enqueue"})}:await z(s,e);break;case"chat.enqueue":o(e.params),n={durableQueueHandoff:await this.chatQueue.handleEnqueue(e)};break;case"chat.queue.get":o(e.params),await this.chatQueue.handleGet(e);break;case"chat.queue.edit":o(e.params),await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":o(e.params),await this.chatQueue.handleDelete(e);break;case"chat.queue.promote":o(e.params),await this.chatQueue.handlePromote(e);break;case"chat.abort":o(e.params),await j(s,e);break;case"session.refresh":o(e.params),await O(s,e);break;case"session.history.open":this.historySubscriptions.handleOpen(e);break;case"session.history.sync":this.historySubscriptions.handleSync(e);break;case"session.history.page":this.historySubscriptions.handlePage(e);break;case"session.history.close":this.historySubscriptions.handleClose(e);break;case"session.body.replica.subscribe":this.historySubscriptions.handleReplicaSubscribe(e);break;case"session.body.replica.unsubscribe":this.historySubscriptions.handleReplicaUnsubscribe(e);break;case"session.history":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"upgrade_required"});break;case"session.message.status":U(s,e);break;case"session.tool.detail":await W(s,e);break;case"voice.session.body.window":J(s,e);break;case"session.title.set":await H(s,e);break;case"room.agent.bind-managed":await pe(s,this.managedRoomBinder,e);break;case"room.agent.restart-managed":await ge(s,this.managedRoomBinder,e);break;case"fs.ls":await L(s,e);break;case"project.fs.open":case"project.fs.list":case"project.fs.read":case"project.fs.close":await Ee(this.client,this.projectFsHandleStore,e,this.trustedProjectFsRequestResolver);break;case"fs.read":await N(s,e);break;case"fs.write":await K(s,e);break;case"fs.export.markdown-pdf":await ee(s,e);break;case"fs.export.markdown-pdf.setup":await se(s,e);break;case"fs.archive.zip":await te(s,e);break;case"fs.rename":await G(s,e);break;case"fs.transfer.start":await q(s,e);break;case"fs.transfer.chunk":await Z(s,e);break;case"fs.transfer.finish":await Y(s,e);break;case"fs.transfer.abort":await X(s,e);break;case"region.probe":await ae(s,e);break;case"region.switch":await re(s,e);break;case"upgrade.start":await I(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0,prepareForUpgrade:r=>this.prepareForUpgrade(r),cancelUpgradePreparation:()=>this.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()}});break;case"upgrade.status":await A(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await ne(s,e);break;case"machine.remote-access.pause":await $(this.client,this.remoteAccessPauseController,e);break;case"agents.refresh":await T(s,e);break;case"agent.permission.respond":await Qe(s,e);break;case"agent.auth.start":case"agent.auth.logout":case"agent.session-options.get":case"agent.external-sessions.list":case"agent.external-sessions.import":case"agent.external-sessions.close":case"agent.external-sessions.delete":await je(s,e);break;case"models.refresh":await P(s,e);break;case"agent.config.get":await F(s,e);break;case"agent.config.upsert":await Q(s,e);break;case"agent.config.clear":await D(s,e);break;case"agent.config.test":await E(s,e);break;case"agent.workspace.validate":await _(s,e);break;case"agent.capabilities.list":await x(s,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(r){if(t.propagateErrors)throw r;this.client.sendRes({type:"res",id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)})}finally{this.activeRequests--}return n}evictIdleSessions(){if(this.sessions.size<He)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(this.revokeManagedRoomToken(e.session),e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return de(e)}resolveAuthorizedPath(e,t){return he(e,ce(t))}async resolveAuthorizedPathAsync(e,t){return ue(e,await le(t))}async cleanup(){this.chatQueue.stop(),this.projectFsHandleStore.revokeAll(),this.acpDiscoveryWatcher.stop(),this.nativeFusion?.setExternalTerminalHandler?.(null),this.nativeCleanupOutbox.stop(),this.historySubscriptions.closeAll(),this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null),this.attachmentCleanupTimer&&(clearInterval(this.attachmentCleanupTimer),this.attachmentCleanupTimer=null);for(const[,e]of this.sessions)this.revokeManagedRoomToken(e),e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),e.adapter.removeAllListeners(),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),V(this.getRuntime()),await this.managerRuntime.stop(),u(null)}revokeManagedRoomToken(e){const t=e.managedRoomContextToken;e.managedRoomContextToken=null,t&&this.managedRoomContextRevoker?.(t)}}export{Hs as SessionManager,Js as resolveSessionWorkDir,Ue as upgradeRecoveryVisibleMessage};
|
|
1
|
+
import b from"node:crypto";import{getRegisteredAgents as S,unregisterAgent as k}from"../agents/adapter.js";import{resetCommandSpecCache as w}from"../agents/command-spec.js";import{loadConfig as A}from"../config/index.js";import{handleUpgradeStart as I,handleUpgradeStatus as T}from"../commands/upgrade.js";import{handleAgentsRefresh as P,handleModelsRefresh as C,refreshMachineAgents as M}from"./handlers/agents.js";import{AcpDiscoveryWatcher as x}from"../agents/acp/watcher.js";import{handleAgentCapabilitiesList as D}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as F,handleAgentConfigGet as E,handleAgentConfigTest as Q,handleAgentConfigUpsert as j}from"./handlers/agent-config.js";import{handleChatAbort as z,handleChatSend as O}from"./handlers/chat.js";import{recoverJournaledRun as B}from"./handlers/chat-recovery.js";import{handleSessionRefresh as W}from"./handlers/session-refresh.js";import{handleSessionToolDetail as _}from"./handlers/tool-detail.js";import{handleSessionTitleSet as H}from"./handlers/title.js";import{handleSessionMessageStatus as U}from"./handlers/message-status.js";import{handleAgentWorkspaceValidation as J}from"./handlers/agent-workspace-validation.js";import{handleVoiceSessionBodyWindow as $}from"./handlers/voice-window.js";import{handleRemoteAccessPause as V}from"./handlers/remote-access.js";import{cleanupPendingTransfers as L,handleFsLs as N,handleFsRead as G,handleFsRename as K,handleFsWrite as X,handleFsTransferAbort as Z,handleFsTransferChunk as Y,handleFsTransferFinish as q,handleFsTransferStart as ee,handleFsExportMarkdownPdf as se,handleFsExportMarkdownPdfSetup as te,handleFsArchiveZip as ae}from"./handlers/fs.js";import{handleRegionProbe as re,handleRegionSwitch as ne,handleUpgradeSetPolicy as ie}from"./handlers/control.js";import{ManagerRuntimeService as oe,setManagerRuntimeService as u}from"../manager/runtime.js";import{ChatQueueManager as ce}from"./queue.js";import{createAuthorizedFsRoot as le,createAuthorizedFsRootAsync as he,resolveAuthorizedPath as ue,resolveAuthorizedPathAsync as de,resolveSessionWorkDir as me}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/pi-coding-agent.js";import"../agents/manager.js";import{registerCustomAgent as pe}from"../agents/custom.js";import{handleManagedRoomBind as ge,handleManagedRoomRestart as fe,discardPreBindingSession as ve}from"./handlers/room-managed.js";import{getDaemonInstallationId as d,listSessionRecords as h,purgeCanonicalSession as ye,purgeSessionRecord as Re,recordSession as be,upsertMessage as Se}from"./store.js";import{requestSessionIndexPublish as m}from"./index-publisher.js";import{checkRunStalls as ke}from"./run-stall.js";import{reportUpgradeAggregateMetric as we}from"../log-reporter.js";import{PersonalHistorySubscriptions as Ae}from"./history-subscriptions.js";import{sweepAttachmentTransfers as Ie}from"./attachment-transfer-store.js";import{NativeSourceDeletionStore as Te}from"../native-fusion/native-source-deletions.js";import{collectLocalNativeSources as Pe}from"../native-fusion/session-native-sources.js";import{purgeToolDetails as Ce}from"./tool-detail-store.js";import{NativeSessionCleanupOutbox as Me}from"./native-cleanup-outbox.js";import{assertPersonalSyncIdentity as o}from"../personal-sync/epoch.js";import{ActiveRunJournal as xe}from"./run-recovery/journal.js";import{RunRecoveryBarrier as De}from"./run-recovery/barrier.js";import{RunRecoveryCoordinator as Fe}from"./run-recovery/coordinator.js";import{ProjectFsHandleStore as Ee}from"./project-fs-store.js";import{handleProjectFsRequest as Qe}from"./handlers/project-fs.js";import{handleAgentPermissionResponse as je,handleAcpAgentRequest as ze}from"./handlers/agent-control.js";import{SessionDeletionSynchronizer as Oe}from"./deletion-synchronizer.js";import{dispatchManagedChat as Be,dispatchQueuedChat as We,interruptQueuedChat as _e}from"./queued-chat-dispatch.js";const He=50;import{resolveSessionWorkDir as Vs}from"../fs/boundary.js";function Ue(){return"\u795E\u5FF5\u5347\u7EA7\u4E2D\u65AD\u4E86\u672C\u6B21\u8FD0\u884C\u3002\u5DF2\u5B8C\u6210\u7684\u56DE\u590D\u6216\u64CD\u4F5C\u4ECD\u7136\u6709\u6548\uFF0C\u672A\u5B8C\u6210\u90E8\u5206\u53EF\u91CD\u8BD5\u3002\u539F\u4F1A\u8BDD\u5DF2\u4FDD\u7559\u3002"}class Us{client;nativeFusion;cliVersion;upgradePolicyController;managedRoomBinder;remoteAccessPauseController;managedRoomContextRevoker;managedRoomExecutor;trustedProjectFsRequestResolver;getAgentSnapshot;scheduleHandler;getScheduleQueue(){return this.chatQueue}sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;historySubscriptions;nativeCleanupOutbox;activityProbeTimer=null;attachmentCleanupTimer=null;activeRequests=0;acpDiscoveryWatcher;runJournal;recoveryBarrier=new De;recoveryCoordinator;recoveryPass=null;prepareManagedRecovery;projectFsHandleStore=new Ee;deletionSynchronizer;constructor(e,t=null,s,n=null,r=null,l=null,p=null,g=null,f=null,v=null,y=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=n,this.managedRoomBinder=r,this.remoteAccessPauseController=l,this.managedRoomContextRevoker=p,this.managedRoomExecutor=g,this.trustedProjectFsRequestResolver=v,this.getAgentSnapshot=y,this.runJournal=f??new xe(d());for(const a of this.runJournal.loadPendingReconciliation().records)this.recoveryBarrier.begin(a.sessionId);this.recoveryCoordinator=new Fe({journal:this.runJournal,barrier:this.recoveryBarrier,recover:(a,i)=>B(this.getRuntime(),a,i),commitTerminal:(a,i)=>this.commitRecoveryTerminal(a,i),isCanonicalTerminal:a=>{const i=h().find(R=>R.sessionId===a.sessionId),c=`terminal:${b.createHash("sha256").update(`${a.runId}\0`).digest("hex")}`;return i?.lastAttentionId===c},onOutcome:a=>we({kind:"recovery",adapterType:a.adapterType,result:a.result,stage:a.result==="continued"?"continue":a.result==="reattached"?"reattach":a.result==="resumed"?"resume":a.result==="terminal_reconciled"?"inspect":"terminal",durationMs:a.durationMs,retries:Math.max(0,a.attempts-1),...a.reason?{errorCode:a.reason}:{}})}),this.managerRuntime=new oe({getRuntime:()=>this.getRuntime(),getAgentSnapshot:this.getAgentSnapshot??void 0,dispatchReq:a=>this.handleReq(a,{propagateErrors:!0})}),this.chatQueue=new ce({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a),dispatchManagedReq:(a,i)=>Be(this.getRuntime(),a,i),dispatchQueuedReq:(a,i)=>We(this.getRuntime(),a,i),interruptQueuedSession:a=>_e(this.getRuntime(),a)}),this.deletionSynchronizer=new Oe(e,a=>this.applySessionDeletion(a)),this.historySubscriptions=new Ae(this.client),this.nativeCleanupOutbox=new Me({logger:console.info}),this.acpDiscoveryWatcher=new x(async()=>{w(),await M(this.getRuntime())}),this.nativeFusion?.setExternalTerminalHandler?.(a=>{this.handleExternalTerminal(a)}),this.nativeFusion?.setExternalClaimHandler?.((a,i)=>{this.chatQueue.noteExternalClaim(a,i)}),this.nativeCleanupOutbox.start(),u(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents();try{this.acpDiscoveryWatcher.start()}catch(a){console.warn(`[acp.discovery] watcher unavailable: ${a instanceof Error?a.message:String(a)}`)}this.activityProbeTimer=setInterval(()=>{ke(this.sessions.entries(),()=>m(this.client)),this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.(),this.attachmentCleanupTimer=setInterval(()=>{const a=new Set([...h().map(i=>i.workDir),...Array.from(this.pendingTransfers.values()).map(i=>i.rootPath)]);for(const i of a)try{Ie(this.resolvePath(i))}catch(c){console.error("[attachment.cleanup] failed",c instanceof Error?c.message:String(c))}},6e4),this.attachmentCleanupTimer.unref?.()}executeManagedManagerAction(e){return this.managerRuntime.executeScopedWorkerAction(e.managerSessionId,e.action,e.params,e.roomOrigin)}noteManagedRoomSendOutcome(e){for(const t of this.sessions.values()){if(t.managedRoomContextToken!==e.token)continue;const s=t.roomSendOutcome??(t.roomSendOutcome={successes:0,failureCodes:[]});e.ok?s.successes+=1:s.failureCodes.length<20&&s.failureCodes.push(e.errorCode??"managed_room_action_failed");return}}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),getAgentSnapshot:this.getAgentSnapshot??void 0,resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),resolveAuthorizedPathAsync:(e,t)=>this.resolveAuthorizedPathAsync(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController,revokeManagedRoomContextToken:this.managedRoomContextRevoker,managedRoomExecutor:this.managedRoomExecutor,runJournal:this.runJournal,recoveryBarrier:this.recoveryBarrier,prepareManagedRecovery:this.prepareManagedRecovery}}async resumePendingAcpAuthentication(e){const t=[...this.sessions.values()].find(s=>s.agentType===e&&s.adapter.hasPendingAuthenticationRetry?.());return t?.adapter.resumeAfterExternalAuthentication?(await t.adapter.resumeAfterExternalAuthentication(),!0):!1}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}prepareForUpgrade(e){this.recoveryBarrier.freezeDispatch();const t=this.runJournal.markPlannedUpgrade(e);return this.runJournal.sync(),{activeRunCount:t}}cancelUpgradePreparation(){this.recoveryBarrier.unfreezeDispatch()}async recoverInterruptedRuns(){this.recoveryPass??=this.recoveryCoordinator.recoverAll(),await this.recoveryPass}getPendingRecoveryCount(){return this.runJournal.loadPendingReconciliation().records.length}revokeProjectFsHandles(){this.projectFsHandleStore.revokeAll()}async commitRecoveryTerminal(e,t){const s=this.sessions.get(e.sessionId);s&&(s.currentRunId=null,s.currentRunPhase=null,s.journalRunId=null,s.heartbeatTimer&&(clearInterval(s.heartbeatTimer),s.heartbeatTimer=null)),this.runTextAcc.delete(`${e.sessionId}:${e.providerRunId??e.runId}`),this.publishSessionActivity(e.sessionId,null);const n=Ue();Se(e.sessionId,{id:`upgrade-recovery-terminal-${e.runId}`,sessionId:e.sessionId,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:"error",content:n,error:!0,recoveryState:t.result,recoveryReason:t.reason})}),be({sessionId:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,workDir:e.workDir,agentSessionId:e.agentSessionId,modelId:e.modelId,status:"failed",attentionId:`upgrade-recovery:${e.runId}`,lastActivityAt:new Date().toISOString()}),this.managerRuntime.noteAgentEvent(e.sessionId,{state:"error",runId:e.providerRunId??e.runId,seq:e.lastObservedEventSeq+1,message:n}),m(this.client);const r=e.lastObservedEventSeq+1;this.client.sendAgentEvent({type:"event",event:"agent",payload:t.result==="interrupted_by_upgrade"?{state:"interrupted_by_upgrade",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason}:{state:"recovery_failed",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason,...t.message?{message:t.message}:{}},seq:r,id:`agent-recovery-terminal-${e.runId}`}),this.chatQueue.noteTerminal(e.sessionId)}setManagedRoomTurnPreparer(e){this.chatQueue.setManagedRoomTurnPreparer(e)}setManagedAgentDirectTurnPreparer(e){this.chatQueue.setManagedAgentDirectTurnPreparer(e)}setManagedRecoveryPreparer(e){this.prepareManagedRecovery=e}async enqueueManagedRoomBatch(e){const t=e.map(s=>{const n=h().find(r=>r.sessionId===s.params.sessionId);return{context:s.context,params:{...s.params,modelId:n?.modelId??s.params.modelId,sessionMode:n?.sessionMode??s.params.sessionMode,managerConfig:n?.managerConfig??s.params.managerConfig,managerDefaultWorkerAgentType:n?.managerDefaultWorkerAgentType??s.params.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:n?.managerDefaultWorkerModelId??s.params.managerDefaultWorkerModelId}}});await this.chatQueue.enqueueManagedRoomBatch(t)}async retireManagedRoomSession(e){this.chatQueue.purgeSession(e),await ve(this.getRuntime(),e)}discardPendingManagedRoomMessages(e){return this.chatQueue.discardPendingManagedRoomMessages(e)}async synchronizeSessionDeletions(){await this.deletionSynchronizer.synchronize()}async applySessionDeletion(e){const t=new Te({daemonInstallationId:d()});let s=[];try{s=Pe(e.sessionId,{records:h()})}catch(r){console.warn("[session.deletions] local native source lookup failed",{error:r instanceof Error?r.message:String(r)})}t.recordSession(e);for(const r of[...e.sources,...s]){const l=t.find(r.agentType,r.sourceSessionKey);l&&l.sessionId!==e.sessionId||t.record({...e,...r})}this.runJournal.markSessionAborted(e.sessionId),this.recoveryBarrier.end(e.sessionId);const n=this.sessions.get(e.sessionId);if(n){this.revokeManagedRoomToken(n);try{await n.adapter.stop()}catch{}this.sessions.delete(e.sessionId)}this.historySubscriptions.closeSession(e.sessionId),this.nativeFusion?.handleSessionDeleted(e.sessionId),this.chatQueue.purgeSession(e.sessionId),Ce(e.sessionId),ye(e.sessionId),Re(e.sessionId),this.runTextAcc.delete(e.sessionId),this.publishSessionActivity(e.sessionId,null),this.nativeCleanupOutbox.enqueue(e),this.nativeCleanupOutbox.kick()}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async handleExternalTerminal(e){const t=this.sessions.get(e);t&&(t.journalRunId&&(this.recoveryCoordinator.completeFromProvider(e,t.journalRunId),t.journalRunId=null),this.sessions.delete(e),this.revokeManagedRoomToken(t),t.heartbeatTimer&&clearInterval(t.heartbeatTimer),t.adapter.removeAllListeners(),await t.adapter.stop().catch(()=>{})),this.chatQueue.noteTerminal(e)}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(t.heartbeatTimer||!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const n=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:n,canStop:s.canStop??!0});const r=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:r,runPhase:s.runPhase,canStop:s.canStop??!0},seq:r,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of S())t.startsWith("custom:")&&k(t);const e=A();for(const[t,s]of Object.entries(e.customAgents??{}))pe(t,s)}async handleReq(e,t={}){const s=this.getRuntime();let n;this.activeRequests++;try{switch(e.method){case"schedule.deliver":if(!this.scheduleHandler)throw new Error("schedules_unavailable");await this.scheduleHandler(e);break;case"chat.send":if(e.params.scheduledDelivery)throw new Error("schedule_source_untrusted");o(e.params),this.recoveryBarrier.isDispatchFrozen()||this.recoveryBarrier.isRecovering(String(e.params.sessionId??""))?n={durableQueueHandoff:await this.chatQueue.handleEnqueue({...e,method:"chat.enqueue"})}:await O(s,e);break;case"chat.enqueue":o(e.params),n={durableQueueHandoff:await this.chatQueue.handleEnqueue(e)};break;case"chat.queue.get":o(e.params),await this.chatQueue.handleGet(e);break;case"chat.queue.edit":o(e.params),await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":o(e.params),await this.chatQueue.handleDelete(e);break;case"chat.queue.promote":o(e.params),await this.chatQueue.handlePromote(e);break;case"chat.abort":o(e.params),await z(s,e);break;case"session.refresh":o(e.params),await W(s,e);break;case"session.history.open":this.historySubscriptions.handleOpen(e);break;case"session.history.sync":this.historySubscriptions.handleSync(e);break;case"session.history.page":this.historySubscriptions.handlePage(e);break;case"session.history.close":this.historySubscriptions.handleClose(e);break;case"session.body.replica.subscribe":this.historySubscriptions.handleReplicaSubscribe(e);break;case"session.body.replica.unsubscribe":this.historySubscriptions.handleReplicaUnsubscribe(e);break;case"session.history":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"upgrade_required"});break;case"session.message.status":U(s,e);break;case"session.tool.detail":await _(s,e);break;case"voice.session.body.window":$(s,e);break;case"session.title.set":await H(s,e);break;case"room.agent.bind-managed":await ge(s,this.managedRoomBinder,e);break;case"room.agent.restart-managed":await fe(s,this.managedRoomBinder,e);break;case"fs.ls":await N(s,e);break;case"project.fs.open":case"project.fs.list":case"project.fs.read":case"project.fs.close":await Qe(this.client,this.projectFsHandleStore,e,this.trustedProjectFsRequestResolver);break;case"fs.read":await G(s,e);break;case"fs.write":await X(s,e);break;case"fs.export.markdown-pdf":await se(s,e);break;case"fs.export.markdown-pdf.setup":await te(s,e);break;case"fs.archive.zip":await ae(s,e);break;case"fs.rename":await K(s,e);break;case"fs.transfer.start":await ee(s,e);break;case"fs.transfer.chunk":await Y(s,e);break;case"fs.transfer.finish":await q(s,e);break;case"fs.transfer.abort":await Z(s,e);break;case"region.probe":await re(s,e);break;case"region.switch":await ne(s,e);break;case"upgrade.start":await I(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0,prepareForUpgrade:r=>this.prepareForUpgrade(r),cancelUpgradePreparation:()=>this.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()}});break;case"upgrade.status":await T(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await ie(s,e);break;case"machine.remote-access.pause":await V(this.client,this.remoteAccessPauseController,e);break;case"agents.refresh":await P(s,e);break;case"agent.permission.respond":await je(s,e);break;case"agent.auth.start":case"agent.auth.logout":case"agent.session-options.get":case"agent.external-sessions.list":case"agent.external-sessions.import":case"agent.external-sessions.close":case"agent.external-sessions.delete":await ze(s,e);break;case"models.refresh":await C(s,e);break;case"agent.config.get":await E(s,e);break;case"agent.config.upsert":await j(s,e);break;case"agent.config.clear":await F(s,e);break;case"agent.config.test":await Q(s,e);break;case"agent.workspace.validate":await J(s,e);break;case"agent.capabilities.list":await D(s,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(r){if(t.propagateErrors)throw r;this.client.sendRes({type:"res",id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)})}finally{this.activeRequests--}return n}evictIdleSessions(){if(this.sessions.size<He)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(this.revokeManagedRoomToken(e.session),e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return me(e)}resolveAuthorizedPath(e,t){return ue(e,le(t))}async resolveAuthorizedPathAsync(e,t){return de(e,await he(t))}async cleanup(){this.chatQueue.stop(),this.projectFsHandleStore.revokeAll(),this.acpDiscoveryWatcher.stop(),this.nativeFusion?.setExternalTerminalHandler?.(null),this.nativeCleanupOutbox.stop(),this.historySubscriptions.closeAll(),this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null),this.attachmentCleanupTimer&&(clearInterval(this.attachmentCleanupTimer),this.attachmentCleanupTimer=null);for(const[,e]of this.sessions)this.revokeManagedRoomToken(e),e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),e.adapter.removeAllListeners(),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),L(this.getRuntime()),await this.managerRuntime.stop(),u(null)}revokeManagedRoomToken(e){const t=e.managedRoomContextToken;e.managedRoomContextToken=null,t&&this.managedRoomContextRevoker?.(t)}}export{Us as SessionManager,Vs as resolveSessionWorkDir,Ue as upgradeRecoveryVisibleMessage};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import l from"node:crypto";import r from"node:fs";import p from"node:path";import{resolvePersonalSyncV1Path as
|
|
2
|
-
`,"utf8"),r.fsyncSync(e),r.closeSync(e),e=void 0,
|
|
1
|
+
import l from"node:crypto";import r from"node:fs";import{renameSyncWithRetry as m}from"../fs/atomic-rename.js";import p from"node:path";import{resolvePersonalSyncV1Path as h}from"../personal-sync/paths.js";import{getDaemonInstallationId as y}from"../personal-sync/identity.js";import{NativeSourceDeletionStore as f}from"../native-fusion/native-source-deletions.js";import{NativeSessionLifecycleRegistry as I}from"./native-session-lifecycle.js";const d=1,S=8,b=6e4,v=360*60*1e3,u=new Set(["succeeded_archived","succeeded_deleted","succeeded_already_absent","skipped_unsupported","skipped_invalid_identity","failed_permanent"]);class T{options;lifecycle;timer=null;drainPromise=null;constructor(t={}){this.options=t,this.lifecycle=t.lifecycle??new I}start(){this.timer||(this.drain(),this.timer=setInterval(()=>{this.drain()},this.options.drainIntervalMs??b),this.timer.unref?.())}stop(){this.timer&&clearInterval(this.timer),this.timer=null}enqueue(t){if((t.nativeCleanupPolicy??"none")!=="auto")return[];const s=this.read(!0),i=[];for(const e of t.sources){const o=this.jobId(t,e.agentType,e.sourceSessionKey),n=s.jobs[o];if(n){i.push(n);continue}const c={schemaVersion:d,daemonInstallationId:this.installationId(),jobId:o,sessionId:t.sessionId,deletionRevision:t.deletionRevision,agentType:e.agentType,sourceSessionKey:e.sourceSessionKey,...t.workDir?{workDir:t.workDir}:{},requestedAt:t.deletedAt,state:"pending",attempts:0};s.jobs[o]=c,i.push(c)}return i.some(e=>e.state==="pending")&&this.write(s),i}kick(){this.drain()}async drain(){return this.drainPromise?await this.drainPromise:(this.drainPromise=this.drainOnce().finally(()=>{this.drainPromise=null}),await this.drainPromise)}listJobs(){return Object.values(this.read(!0).jobs).sort((t,s)=>t.deletionRevision-s.deletionRevision||t.jobId.localeCompare(s.jobId))}async drainOnce(){for(;;){const t=this.read(!0),s=this.now(),i=Object.values(t.jobs).filter(o=>o.state==="pending"||o.state==="retry_wait"&&(!o.nextAttemptAt||Date.parse(o.nextAttemptAt)<=s.getTime())).sort((o,n)=>o.deletionRevision-n.deletionRevision||o.jobId.localeCompare(n.jobId))[0];if(!i)return;i.state="running",i.attempts+=1,delete i.nextAttemptAt,this.write(t);let e;if(!this.sourceGuard(i))e={outcome:"invalid_identity"};else try{e=await this.lifecycle.execute(i.agentType,i.sourceSessionKey,{workDir:i.workDir})}catch{e={outcome:"transient",errorCode:"lifecycle_unexpected_failure"}}this.applyResult(i.jobId,e)}}applyResult(t,s){const i=this.read(!1),e=i.jobs[t];if(!e||u.has(e.state))return;const o=this.now().toISOString();switch(s.outcome){case"archived":e.state="succeeded_archived";break;case"deleted":e.state="succeeded_deleted";break;case"already_absent":e.state="succeeded_already_absent";break;case"unsupported":e.state="skipped_unsupported";break;case"invalid_identity":e.state="skipped_invalid_identity";break;case"permanent":e.state="failed_permanent",e.lastErrorCode=s.errorCode;break;case"transient":{if(e.lastErrorCode=s.errorCode,e.attempts>=(this.options.maxAttempts??S)){e.state="failed_permanent";break}e.state="retry_wait";const n=Math.min((this.options.retryBaseMs??5e3)*2**Math.max(0,e.attempts-1),v);e.nextAttemptAt=new Date(this.now().getTime()+n).toISOString(),delete e.completedAt,this.write(i),this.log(e,s.errorCode);return}}e.completedAt=o,delete e.nextAttemptAt,this.write(i),this.log(e,e.lastErrorCode??s.outcome)}sourceGuard(t){if(this.options.sourceGuard)return this.options.sourceGuard(t);const s=new f({rootDir:this.rootDir(),daemonInstallationId:this.installationId()}).find(t.agentType,t.sourceSessionKey);return!!(s&&s.sessionId===t.sessionId&&s.deletionRevision===t.deletionRevision)}log(t,s){this.options.logger?.("[native-cleanup] job state changed",{job:t.jobId.slice(0,12),provider:t.agentType,state:t.state,result:s,attempts:t.attempts})}read(t){const s=this.filePath();if(!r.existsSync(s))return this.emptyFile();const i=JSON.parse(r.readFileSync(s,"utf8"));if(i.schemaVersion!==d||i.daemonInstallationId!==this.installationId()||!i.jobs||typeof i.jobs!="object"||Array.isArray(i.jobs))throw new Error("invalid native cleanup outbox");let e=!1;for(const[o,n]of Object.entries(i.jobs)){if(o!==n.jobId||n.schemaVersion!==d||n.daemonInstallationId!==this.installationId()||!n.sessionId||!n.agentType||!n.sourceSessionKey||!Number.isSafeInteger(n.deletionRevision)||n.deletionRevision<1||!Number.isSafeInteger(n.attempts)||n.attempts<0||!u.has(n.state)&&n.state!=="pending"&&n.state!=="running"&&n.state!=="retry_wait")throw new Error("invalid native cleanup job");t&&n.state==="running"&&(n.state="pending",e=!0)}return e&&this.write(i),i}write(t){w(this.filePath(),t)}emptyFile(){return{schemaVersion:d,daemonInstallationId:this.installationId(),jobs:{}}}jobId(t,s,i){return l.createHash("sha256").update(`${this.installationId()}\0${t.deletionRevision}\0${s}\0${i}`).digest("hex")}installationId(){return this.options.daemonInstallationId??y()}rootDir(){return this.options.rootDir??h()}filePath(){return p.join(this.rootDir(),"native-session-cleanup-outbox.json")}now(){return this.options.now?.()??new Date}}function w(a,t){const s=p.dirname(a);r.mkdirSync(s,{recursive:!0,mode:448});const i=`${a}.tmp-${process.pid}-${l.randomBytes(6).toString("hex")}`;let e;try{if(e=r.openSync(i,"wx",384),r.writeFileSync(e,`${JSON.stringify(t,null,2)}
|
|
2
|
+
`,"utf8"),r.fsyncSync(e),r.closeSync(e),e=void 0,m(i,a),process.platform!=="win32"){const o=r.openSync(s,"r");try{r.fsyncSync(o)}finally{r.closeSync(o)}}}finally{e!==void 0&&r.closeSync(e);try{r.unlinkSync(i)}catch{}}}export{T as NativeSessionCleanupOutbox};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{diagnoseWorkDir as D,queueRecoveryGuidance as a}from"./queue-dispatch-failure.js";function s(l,e=Date.now(),u=D){const i=Object.entries(l.sessions).flatMap(([n,o])=>{if(!o.length)return[];const p=o.map(t=>{const d=u(t.workDir),r=t.dispatchBlock,c=!!(r&&r.retryAt>e),k=t.externalQueuedSubmissionId?"handed_to_codex_desktop":c?"blocked":r?"retrying":"waiting";return{messageId:t.id,ageSeconds:Math.max(0,Math.round((e-Date.parse(t.createdAt))/1e3)),delivery:k,agentType:t.agentType,modelId:t.modelId??null,workDir:t.workDir,workDirStatus:d?d.replace("agent_workdir_",""):"ok",origin:t.trigger?.kind??"personal",...r?{block:{code:r.code,...r.attempts?{attempts:r.attempts}:{},...c?{retryInSeconds:Math.ceil((r.retryAt-e)/1e3)}:{},...a(r.code,{workDir:t.workDir})?{whatToDo:a(r.code,{workDir:t.workDir})}:{}}}:{}}});return[{sessionId:n,pending:p}]});return{pendingCount:i.reduce((n,o)=>n+o.pending.length,0),sessions:i}}export{s as buildQueueDiagnostics};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import w from"node:fs";import{classifyQueueError as x}from"./queue-helpers.js";import{readQueue as h,writeQueue as A}from"./queue-storage.js";import{upsertMessage as f}from"./store.js";import{describeRoomReplyFailure as E}from"./room-reply-notice.js";import{TerminalQueuedChatDispatchError as k}from"./queue-message.js";const D={agent_workdir_not_found:({workDir:e})=>`\u8FD9\u6761\u6D88\u606F\u7ED1\u5B9A\u7684\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u5B58\u5728${e?`\uFF1A${e}`:""}\u3002\u8BF7\u5728\u8FD9\u53F0\u7535\u8111\u6062\u590D\u8BE5\u76EE\u5F55\uFF08\u88AB\u79FB\u52A8\u3001\u5220\u9664\uFF0C\u6216\u6240\u5728\u78C1\u76D8\u672A\u6302\u8F7D\uFF09\uFF0C\u6216\u56DE\u5230\u795E\u5FF5\u4E3A\u8FD9\u4E2A\u5BF9\u8BDD\u6539\u9009\u4E00\u4E2A\u5B58\u5728\u7684\u76EE\u5F55\u3002`,agent_workdir_not_directory:({workDir:e})=>`\u8FD9\u6761\u6D88\u606F\u7ED1\u5B9A\u7684\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u662F\u6587\u4EF6\u5939${e?`\uFF1A${e}`:""}\u3002\u8BF7\u56DE\u5230\u795E\u5FF5\u4E3A\u8FD9\u4E2A\u5BF9\u8BDD\u6539\u9009\u4E00\u4E2A\u6587\u4EF6\u5939\u3002`,agent_workdir_unavailable:({workDir:e})=>`\u65E0\u6743\u8BBF\u95EE\u8FD9\u6761\u6D88\u606F\u7ED1\u5B9A\u7684\u5DE5\u4F5C\u76EE\u5F55${e?`\uFF1A${e}`:""}\u3002\u8BF7\u5728\u8FD9\u53F0\u7535\u8111\u68C0\u67E5\u8BE5\u76EE\u5F55\u7684\u8BBF\u95EE\u6743\u9650\uFF0C\u6216\u56DE\u5230\u795E\u5FF5\u6539\u9009\u76EE\u5F55\u3002`,codex_windows_runtime_unavailable:"\u672A\u627E\u5230\u53EF\u8FD0\u884C\u7684 Windows Codex CLI\u3002\u8BF7\u5728\u8FD9\u53F0\u7535\u8111\u786E\u8BA4 Windows Codex \u5DF2\u5B89\u88C5\u5E76\u53EF\u767B\u5F55\uFF0C\u5C06\u5176\u76EE\u5F55\u52A0\u5165\u7528\u6237 PATH\uFF0C\u6216\u5C06 SHENNIAN_CODEX_PATH \u8BBE\u4E3A\u8BE5 CLI \u7684\u5B8C\u6574\u8DEF\u5F84\u540E\u91CD\u542F\u795E\u5FF5 Client\uFF1B\u518D\u5237\u65B0 AI \u5217\u8868\u3002\u4E0D\u4F1A\u6539\u7528 WSL\u3002",codex_session_capability_unavailable:"\u5F53\u524D Codex \u672A\u63D0\u4F9B\u6B64\u4F1A\u8BDD\u6240\u9700\u7684 Desktop \u63A5\u53E3\u3002\u8BF7\u6838\u5BF9 Windows Codex CLI \u9009\u62E9\u548C\u5B9E\u9645\u63A5\u53E3\u652F\u6301\uFF0C\u5FC5\u8981\u65F6\u7531\u4F60\u624B\u52A8\u66F4\u65B0 Codex\uFF0C\u518D\u5237\u65B0 AI \u5217\u8868\uFF1B\u4E0D\u4F1A\u53E6\u5EFA\u4E0D\u517C\u5BB9\u7684\u5BF9\u8BDD\u3002",codex_command_unavailable:"\u65E0\u6CD5\u542F\u52A8\u5DF2\u9009\u62E9\u7684 Codex CLI\u3002\u8BF7\u786E\u8BA4\u8BE5\u7A0B\u5E8F\u4ECD\u5B58\u5728\u4E14\u53EF\u8FD0\u884C\uFF0C\u518D\u5237\u65B0 AI \u5217\u8868\u3002",managed_agent_runtime_changed:"\u5F53\u524D Codex \u7684 Windows / WSL \u73AF\u5883\u4E0E\u539F\u6388\u6743\u4E0D\u540C\u3002\u8BF7\u6062\u590D\u539F\u8FD0\u884C\u73AF\u5883\u5E76\u5237\u65B0 AI \u5217\u8868\uFF1B\u4E0D\u8981\u901A\u8FC7\u6362\u7ED1\u6216\u65B0\u5EFA\u5BF9\u8BDD\u5904\u7406\u8FD9\u4E9B\u5F85\u53D1\u9001\u6D88\u606F\u3002",codex_managed_permission_profile_unavailable:"\u5F53\u524D Codex \u672A\u63D0\u4F9B\u6240\u9700\u7684\u9650\u5236\u6743\u9650\u80FD\u529B\u3002\u8BF7\u68C0\u67E5\u6240\u9009 Codex \u548C\u667A\u80FD\u4F53\u6743\u9650\u8BBE\u7F6E\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u653E\u5BBD\u6743\u9650\u3002\u4FEE\u590D\u540E\u5237\u65B0 AI \u5217\u8868\u3002",codex_managed_config_read_invalid:"\u5F53\u524D Codex \u672A\u8FD4\u56DE\u53EF\u9A8C\u8BC1\u7684\u6743\u9650\u914D\u7F6E\u3002\u8BF7\u68C0\u67E5\u6240\u9009 Codex \u662F\u5426\u53EF\u6B63\u5E38\u542F\u52A8\uFF0C\u4FEE\u590D\u540E\u5237\u65B0 AI \u5217\u8868\u3002",managed_agent_host_full_confirmation_required:"\u5F53\u524D\u667A\u80FD\u4F53\u6743\u9650\u5C1A\u672A\u83B7\u6709\u6548\u6388\u6743\u3002\u8BF7\u5728\u667A\u80FD\u4F53\u8BBE\u7F6E\u4E2D\u6838\u5BF9\u5E76\u4FDD\u5B58\u6240\u9700\u6743\u9650\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u6539\u4E3A\u5168\u90E8\u6743\u9650\u3002"};function b(e,t={}){const n=D[e];return typeof n=="function"?n(t):n}function $(e){if(!e)return null;try{return w.statSync(e).isDirectory()?null:"agent_workdir_not_directory"}catch(t){const n=t.code;return n==="ENOENT"||n==="ENOTDIR"?"agent_workdir_not_found":n==="EACCES"||n==="EPERM"?"agent_workdir_unavailable":null}}const v=4;function m(e,t){return(((e instanceof Error?e.message:String(e)).replace(/^Agent send failed:\s*/i,"").split(/\r?\n/).map(s=>s.trim()).find(Boolean)??"")||t).slice(0,160)}const S=new Set(["queued_dispatch_cancelled","queue_stopped"]);function L(e){const t=e.map(r=>r.dispatchBlock?.retryAt??0),n=Math.max(0,...t);return n>Date.now()?n:void 0}function M(e){const{error:t,sessionId:n,batch:r}=e,s=t instanceof k,o=r[0],_=x(t instanceof Error?t.message:String(t),s?"terminal_dispatch_failed":"transient_dispatch_failed"),a=!s&&(e.diagnoseWorkDir??$)(o?.workDir)||_,c=b(a,{workDir:o?.workDir});if(!s&&c&&o){const i=h(),g=new Set(r.map(d=>d.id)),p=(i.sessions[n]??[]).filter(d=>g.has(d.id));if(!p.length)return{drainAgain:!1,transientFailure:!1};const C=p.some(d=>d.dispatchBlock?.code!==a),I=Date.now()+6e4;for(const d of p){const y=d.id===o.id||d.dispatchBlock?.notice;d.dispatchBlock={code:a,retryAt:I,...y?{notice:!0}:{}}}return A(i),f(n,{id:`queue-recovery-${o.id}`,sessionId:n,role:"agent",ts:Date.parse(o.createdAt),payload:`\u6D88\u606F\u5C1A\u672A\u4EA4\u7ED9 AI\uFF0C\u5DF2\u4FDD\u7559\uFF0C\u7B49\u5F85\u6062\u590D\uFF1A${c} \u914D\u7F6E\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u52FF\u91CD\u590D\u53D1\u9001\u3002`}),e.publish(),C&&e.log("dispatch.blocked",{failureClass:a}),{drainAgain:!1,transientFailure:!1}}const l=!!(o&&!o.trigger&&!o.clientMessageId&&Date.now()-Date.parse(o.createdAt)>=10*6e4&&e.isManagedWorker),u=a==="managed_agent_restricted_room_unsupported";if(u&&o&&f(n,{id:`room-reply-notice-${o.id}`,sessionId:n,role:"agent",ts:Date.now(),payload:`\u672C\u8F6E\u672A\u80FD\u5728\u7FA4\u91CC\u56DE\u590D\uFF1A${E(a)}\u3002`}),s||a==="managed_claim_source_binding_conflict"||u||l){o&&!u&&!S.has(m(t,a))&&(f(n,{id:`queue-failed-${o.id}`,sessionId:n,role:"agent",ts:Date.now(),payload:`\u6D88\u606F\u672A\u80FD\u9001\u8FBE\uFF0C\u4E14\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\uFF1A${m(t,a)}\u3002\u8BF7\u68C0\u67E5\u540E\u91CD\u65B0\u53D1\u9001\u3002`}),e.publish());const i=e.removeBatch();return e.log("dispatch.terminal-failure",{batchCount:r.length,queueMessageId:o?.id,pendingCount:i,failureClass:l?"stale_legacy_managed_worker_dispatch_failure":a}),{drainAgain:i>0,transientFailure:!1}}return e.log("dispatch.transient-failure",{failureClass:a}),o&&q(e,a,m(t,a)),{drainAgain:!1,transientFailure:!0}}function q(e,t,n){const{sessionId:r,batch:s}=e,o=s[0],_=h(),a=new Set(s.map(i=>i.id)),c=(_.sessions[r]??[]).filter(i=>a.has(i.id));if(!c.length)return;const l=(c.find(i=>i.id===o.id)?.dispatchBlock?.attempts??0)+1,u=l===v;for(const i of c){const g=i.dispatchBlock?.notice||u&&i.id===o.id;i.dispatchBlock={code:t,retryAt:0,attempts:l,...g?{notice:!0}:{}}}A(_),u&&(f(r,{id:`queue-recovery-${o.id}`,sessionId:r,role:"agent",ts:Date.parse(o.createdAt),payload:`\u6D88\u606F\u5C1A\u672A\u9001\u8FBE\uFF0C\u5DF2\u4FDD\u7559\u5E76\u5728\u81EA\u52A8\u91CD\u8BD5\uFF08\u5DF2\u5C1D\u8BD5 ${l} \u6B21\uFF09\u3002\u539F\u56E0\uFF1A${n}\u3002\u5982\u957F\u65F6\u95F4\u6CA1\u6709\u53D8\u5316\uFF0C\u8BF7\u68C0\u67E5\u8FD9\u53F0\u7535\u8111\u4E0A\u7684\u795E\u5FF5\u548C AI \u662F\u5426\u6B63\u5E38\u8FD0\u884C\u3002`}),e.publish())}function O(e){for(const t of e)t.dispatchBlock?.notice&&f(t.sessionId,{id:`queue-recovery-${t.id}`,sessionId:t.sessionId,role:"agent",ts:Date.parse(t.createdAt),payload:"\u5DF2\u6062\u590D\uFF1A\u539F\u5F85\u53D1\u9001\u6D88\u606F\u5DF2\u6210\u529F\u4EA4\u7ED9 AI\uFF0C\u65E0\u9700\u91CD\u590D\u53D1\u9001\u3002"})}export{$ as diagnoseWorkDir,M as handleQueueDispatchFailure,L as queueBlockedUntil,b as queueRecoveryGuidance,O as resolveQueueRecoveryNotice};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{listSessionRecords as p}from"./store.js";function
|
|
2
|
-
${n.map(r=>
|
|
1
|
+
import{listSessionRecords as p}from"./store.js";const _={allowedRoomActions:["send"],propagateWorkerRoomOrigin:!1};function I(n,r){return n?{roomOrigin:n.roomOrigin,allowedRoomActions:n.roomOrigin?["send"]:[],managerEvent:!0}:r?_:void 0}function b(n,r){const e=d(r);if(e)return n.find(i=>d(i)===e)??null;if(r.origin!=="external")return null;const t=g(r);return n.find(i=>g(i)===t)??null}function R(n){const{dispatchBlock:r,origin:e,managedRoom:t,managedAgentDirect:i,trigger:a,externalQueuedSubmissionId:o,...u}=n;return u}function S(n){const r=n.reduce((o,u)=>{const l=c(u);return o===null||l<o?l:o},null);if(r===null)return[];const e=n.filter(o=>c(o)===r),t=e[0];if(!t)return[];if(s(t))return[t];if(t.trigger?.kind==="manager_worker"||t.trigger?.kind==="scheduled")return[t];const i=f(t),a=[];for(const o of e){if(f(o)!==i)break;a.push(o)}return a}function s(n){if(n.origin==="external"||n.origin==="room"||n.managedRoom)return!1;const r=n.trigger?.kind;return r==null||r==="personal"||r==="managed_direct"}function y(n){return n?.trim()||void 0}function D(n,r){const e=n.find(t=>t.id===r&&s(t));return e?[e]:[]}function c(n){const r=m(n).kind;return r==="personal"||r==="managed_direct"?0:r==="manager_event"||r==="manager_worker"?1:2}function m(n){const r=n.trigger;return r?r.kind==="room_activation"?{kind:r.kind,registryKey:r.registryKey}:r.kind==="manager_worker"?{kind:r.kind,parentSessionId:r.parentSessionId,roomOrigin:r.roomOrigin??null}:r.kind==="manager_event"?{kind:r.kind,roomOrigin:r.roomOrigin??null}:{kind:r.kind}:n.managedRoom?{kind:"room_activation",registryKey:n.managedRoom.registryKey}:n.managedAgentDirect?{kind:"managed_direct"}:{kind:"personal"}}function f(n){return JSON.stringify({agentType:n.agentType,sessionMode:n.sessionMode??null,workDir:n.workDir,agentSessionId:n.agentSessionId??null,modelId:y(n.modelId)??null,systemPrompt:n.systemPrompt??null,reasoningEffort:n.reasoningEffort??null,managerConfig:n.managerConfig??null,managerDefaultWorkerAgentType:n.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:n.managerDefaultWorkerModelId??null,externalChannel:n.externalChannel??null,replyTarget:n.replyTarget??null,roomRegistryKey:n.managedRoom?.registryKey??null,trigger:m(n)})}function M(n){return n.every(r=>r.managedRoom)?`[\u7FA4\u6D88\u606F]
|
|
2
|
+
${n.map(r=>k(r.text)).filter(Boolean).join(`
|
|
3
3
|
|
|
4
4
|
`)}`:`[\u8FDE\u7EED\u7528\u6237\u6D88\u606F]
|
|
5
5
|
${n.map((r,e)=>`<\u6D88\u606F ${e+1}>
|
|
6
6
|
${r.text.trim()}`).join(`
|
|
7
7
|
|
|
8
|
-
`)}`}function
|
|
8
|
+
`)}`}function k(n){const r=n.trim(),e=r.match(/^\[群消息\][ \t]+<([^>\n]+)>\n([\s\S]*)$/);return e?`<${e[1]}>
|
|
9
9
|
${e[2]}`:r.startsWith(`[\u7FA4\u6D88\u606F]
|
|
10
|
-
`)?r.slice(6):r}function
|
|
11
|
-
`)}function
|
|
10
|
+
`)?r.slice(6):r}function g(n){const r=d(n);return r?`id:${r}`:["body",h(n.text),...(n.attachments??[]).map(e=>e.path||`${e.name}:${e.mimeType}`)].join(`
|
|
11
|
+
`)}function d(n){const r=typeof n.clientMessageId=="string"?n.clientMessageId.trim():"";if(r)return r;const e=typeof n.id=="string"?n.id.trim():"";return e&&!e.startsWith("queue-")?e:""}function O(n){const r=new Set,e=[];for(const t of n){const i=t.path||`${t.name}:${t.mimeType}`;r.has(i)||(r.add(i),e.push(t))}return e.length?e:void 0}function h(n){return String(n||"").replace(/\s+/g," ").trim()}function T(n,r){const e=n.toLowerCase();if(e.includes("managed claim session conflicts with source binding"))return"managed_claim_source_binding_conflict";const t=e.match(/\b(?:managed_(?:agent|room)|agent_validation|acp|native|codex)_[a-z0-9_]+\b/)?.[0];return t||(e.includes("no rollout found")?"missing_rollout":e.includes("managed_room_permission_snapshot_mismatch")?"managed_room_permission_snapshot_mismatch":e.includes("managed_room_prompt_snapshot_mismatch")?"managed_room_prompt_snapshot_mismatch":e.includes("managed_room_turn_preparer_unavailable")?"managed_room_turn_preparer_unavailable":e.includes("timeout")?"timeout":e.includes("connection")?"connection_error":r)}function C(n,r){if(n.sessions.has(r.sessionId))return null;const e=p().find(t=>t.sessionId===r.sessionId)?.agentSessionId?.trim();return!e||e.startsWith("managed:")?null:e}export{_ as OWNER_DIRECT_TURN_OPTIONS,T as classifyQueueError,O as dedupeQueuedAttachments,b as findDuplicateQueuedMessage,M as formatQueuedBatch,s as isControllableQueueMessage,I as managedDirectTurnOptions,y as normalizeQueuedModelId,C as resolveManagedRoomNativeSessionId,R as stripLocalQueueFields,S as takeCompatibleBatch,D as takeControllableMessage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class c{drain;timers=new Map;failures=new Map;stopped=!1;constructor(t){this.drain=t}schedule(t,e=!1,r=0){if(this.stopped||this.timers.has(t))return;const i=e?(this.failures.get(t)??0)+1:0;this.failures.set(t,Math.min(i,6));const a=Math.max(r-Date.now(),e?Math.min(1e3*2**(i-1),3e4):1e3),s=setTimeout(()=>{this.timers.delete(t),this.drain(t)},a);s.unref?.(),this.timers.set(t,s)}cancel(t){const e=this.timers.get(t);e&&clearTimeout(e),this.timers.delete(t),this.failures.delete(t)}stop(){this.stopped=!0;for(const t of this.timers.keys())this.cancel(t)}}export{c as QueueRetryScheduler};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
`,{encoding:"utf8",mode:384,flag:"wx"});const n
|
|
1
|
+
import n from"node:fs";import{renameSyncWithRetry as a}from"../fs/atomic-rename.js";import{randomUUID as f}from"node:crypto";import{resolvePersonalSyncV1Path as i}from"../personal-sync/paths.js";function c(){try{const e=JSON.parse(n.readFileSync(i("outbound-queue.json"),"utf-8"));return{sessions:e.sessions&&typeof e.sessions=="object"?e.sessions:{}}}catch(e){if(e.code==="ENOENT"||e instanceof Error&&e.message.startsWith("ENOENT:"))return{sessions:{}};throw e}}function u(e){const o=i();n.mkdirSync(o,{recursive:!0,mode:448});const t=i("outbound-queue.json"),s=`${t}.tmp-${process.pid}-${f()}`;try{n.writeFileSync(s,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,{encoding:"utf8",mode:384,flag:"wx"});const r=n.openSync(s,"r+");if(typeof r=="number")try{n.fsyncSync(r)}finally{n.closeSync(r)}a(s,t)}finally{try{n.unlinkSync(s)}catch{}}}function l(e){const o=c();o.sessions[e]&&(delete o.sessions[e],u(o))}function p(){const e=c();let o=!1;for(const t of Object.values(e.sessions))for(const s of t){const r=s.trigger;!r||r.kind!=="manager_event"&&r.kind!=="manager_worker"||!r.roomOrigin||(delete r.roomOrigin,o=!0)}o&&u(e)}export{p as clearPersistedManagerRoomOrigins,l as purgeQueuedSessionData,c as readQueue,u as writeQueue};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NativeSourceDeletionStore as O}from"../native-fusion/native-source-deletions.js";import{QueueRetryScheduler as j}from"./queue-retry.js";import{findDuplicateQueuedMessage as x,stripLocalQueueFields as N,takeCompatibleBatch as z,formatQueuedBatch as $,dedupeQueuedAttachments as J,classifyQueueError as T,normalizeQueuedModelId as q,resolveManagedRoomNativeSessionId as C,managedDirectTurnOptions as E}from"./queue-helpers.js";import{CODEX_DESKTOP_SEND_UNAVAILABLE as K}from"@shennian/wire";import{isCodexThreadTailInterrupted as G}from"../native-fusion/codex-files.js";import{mergeProjectedSessions as H}from"./projection.js";import{assertFinishedAttachmentReferences as U,markAttachmentReferences as V}from"./attachment-transfer-store.js";import{appendMessage as A,getMessageDeliveryStatus as w,listSessionRecords as Q,recordSession as B,tombstoneMessage as X,upsertMessage as Y}from"./store.js";import{requestSessionIndexPublish as D}from"./index-publisher.js";import{clearPersistedManagerRoomOrigins as Z,purgeQueuedSessionData as ee,readQueue as m,writeQueue as k}from"./queue-storage.js";import{parsePersonalAttachmentReferences as te}from"./attachment-reference.js";import{getPersonalSyncIdentity as P}from"../personal-sync/epoch.js";import{getDaemonInstallationId as b}from"../personal-sync/identity.js";import{isTrustedManagerEvent as ne}from"./manager-event-authority.js";import{getQueueSnapshot as se,handleQueueDelete as ae,handleQueueEdit as ie,handleQueueGet as re,handleQueuePromote as oe}from"./queue-control.js";import{TerminalQueuedChatDispatchError as R,nowIso as W,queueEnvelope as _,queueMessageFromParams as L}from"./queue-message.js";import{purgeQueuedSessionData as xe}from"./queue-storage.js";import{TerminalQueuedChatDispatchError as qe}from"./queue-message.js";class Ce{opts;validateScheduledTarget;async enqueueScheduled(e){return this.handleEnqueue(e,!0)}draining=new Set;promoting=new Set;disposed=!1;retries=new j(e=>{this.wakeSession(e)});deletions=new O;inFlightMessageIds=new Map;deferredLogState=new Map;prepareManagedRoomTurn=null;prepareManagedAgentDirectTurn=null;constructor(e){this.opts=e,Z(),setTimeout(()=>this.drainIdleQueues(),0).unref?.()}stop(){this.disposed=!0,this.retries.stop()}getSnapshot(e){return se({getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:t=>this.broadcast(t)},e)}isImmediateSendAvailable(e){const t=this.opts.getRuntime(),n=t.sessions.get(e);return n?.currentRunId?n.journalRunId?t.runJournal?.get(e,n.journalRunId)?.deliveryMode==="direct":!1:!0}setManagedRoomTurnPreparer(e){this.prepareManagedRoomTurn=e}setManagedAgentDirectTurnPreparer(e){this.prepareManagedAgentDirectTurn=e}async enqueueManagedRoomBatch(e){if(e.length===0)return;const t=this.opts.getRuntime(),n=m(),s=new Set,r=new Map;let u=!1;for(const o of e){const a=o.params;if(this.deletions.hasSession(a.sessionId)){delete n.sessions[a.sessionId],u=!0;continue}if(!a.sessionId||!a.text||!a.agentType||!a.workDir)throw new Error("sessionId, text, agentType and workDir are required");const d=L({...P(b()),...a});typeof a.roomMessageCreatedAt=="string"&&Number.isFinite(Date.parse(a.roomMessageCreatedAt))&&(d.createdAt=new Date(a.roomMessageCreatedAt).toISOString()),d.origin="room",d.managedRoom=o.context,d.trigger={kind:"room_activation",...o.context};const c=n.sessions[a.sessionId]??[],g=x(c,d),f=d.clientMessageId??d.id,M=w(a.sessionId,f);if(!g&&M.state==="not_found")c.push(d),n.sessions[a.sessionId]=c,r.set(`${d.sessionId}\0${f}`,d),s.add(a.sessionId),u=!0;else if(g&&M.state==="not_found")r.set(`${g.sessionId}\0${f}`,g),s.add(a.sessionId);else if(g&&M.state==="queued")s.add(a.sessionId);else if(g){const y=c.filter(S=>S.id!==g.id);y.length?n.sessions[a.sessionId]=y:delete n.sessions[a.sessionId],u=!0}}u&&k(n);let i;for(const o of s)try{for(const a of r.values())a.sessionId===o&&(A(o,_(a),"queued"),B({sessionId:o,agentType:a.agentType,sessionMode:a.sessionMode,managerConfig:a.managerConfig,workDir:a.workDir,agentSessionId:C(t,a),modelId:a.modelId}));this.logLifecycle("enqueue.persisted",o,{origin:"room",pendingCount:m().sessions[o]?.length??0}),this.broadcast(o),this.wakeSession(o)}catch(a){i=a,this.logLifecycle("enqueue.commit-failed",o,{failureClass:T(a instanceof Error?a.message:"","canonical_commit_failed")},"error"),this.retries.schedule(o,!0)}if(s.size&&D(t.client),i)throw i}async handleEnqueue(e,t=!1){const n=this.opts.getRuntime(),s=e.params;if(s.scheduledTask&&!t)throw new Error("schedule_source_untrusted");if((s.managerEventId||s.managerEventRoomOrigin||s.managedWorkerParentSessionId||s.managerWorkerRoomOrigin||e.params.managerWorkerNativeFull||e.params.managedRecoverySource)&&!ne(e))throw new Error("manager_event_source_untrusted");const r=!!(t&&s.scheduledTask?.bindingId);if(H(s.sessionListProjection),!s.sessionId||!s.text||!s.agentType||!s.workDir)return n.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId, text, agentType and workDir are required"}),!1;const u=E(s.managerEventId?{roomOrigin:s.managerEventRoomOrigin}:null,!!s.managedAgentDirect),i=s.managedAgentDirect||r?await this.prepareManagedAgentDirectTurn?.(s.sessionId,u):null;if((s.managedAgentDirect||r)&&!i)throw new Error("managed_agent_context_unavailable");const o=i?Q().find(F=>F.sessionId===s.sessionId):null,a=i?{...s,...i,agentType:i.agentType,sessionMode:i.sessionMode,managerConfig:i.managerConfig,workDir:i.workDir,agentSessionId:i.agentSessionId?.startsWith("managed:")?o?.agentSessionId&&!o.agentSessionId.startsWith("managed:")?o.agentSessionId:null:i.agentSessionId,modelId:o?.modelId??void 0,systemPrompt:i.systemPrompt,externalChannel:s.managedAgentDirect?null:s.externalChannel,replyTarget:s.managedAgentDirect?null:s.replyTarget,managerDefaultWorkerAgentType:i.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:i.managerDefaultWorkerModelId}:s,d=n.resolvePath(a.workDir),c=te(a.attachments);c?.length&&U(d,c);const g={text:a.text,attachments:c,localized:!1},f=n.sessions.get(a.sessionId);if(a.agentType==="codex"&&a.agentSessionId&&f?.currentRunId?.startsWith("dispatch:")&&G(a.agentSessionId))return n.client.sendRes({type:"res",id:e.id,ok:!1,error:K}),!1;i?.managedRoomContextToken&&n.revokeManagedRoomContextToken?.(i.managedRoomContextToken);const M=await this.isSessionBusy(a.sessionId),y=m(),S=y.sessions[a.sessionId]??[],h=L({...a,text:g.text,attachments:g.attachments,systemPrompt:i?null:a.systemPrompt});i&&(s.managedAgentDirect&&(h.managedAgentDirect=!0),h.trigger?.kind!=="manager_event"&&h.trigger?.kind!=="scheduled"&&(h.trigger={kind:"managed_direct"}));const v=h.clientMessageId??h.id,l=w(a.sessionId,v);if(l.state!=="not_found")return n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:l.state==="queued",queueMessageId:h.id,...l,queue:this.getSnapshot(a.sessionId)}}),!0;const I=x(S,h);I||(y.sessions[a.sessionId]=[...S,h],k(y));const p=I??h;return B({sessionId:p.sessionId,agentType:p.agentType,sessionMode:p.sessionMode,managerConfig:p.managerConfig,workDir:p.workDir,agentSessionId:p.agentSessionId,modelId:p.modelId}),A(p.sessionId,_(p),"queued"),V(n.resolvePath(p.workDir),p.attachments??[]),D(n.client),this.logLifecycle("enqueue.persisted",a.sessionId,{origin:a.origin??"app",queueMessageId:p.id,pendingCount:(m().sessions[a.sessionId]??[]).length}),this.broadcast(a.sessionId),n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:!0,queueMessageId:I?.id??h.id,...w(a.sessionId,I?.clientMessageId??I?.id??h.clientMessageId??h.id),queue:this.getSnapshot(a.sessionId),...g.localized?{localizedAttachments:!0}:{}}}),M?this.retries.schedule(a.sessionId):this.wakeSession(a.sessionId),!0}async handleGet(e){await re(this.queueControlContext(),e)}async handleEdit(e){await ie(this.queueControlContext(),e)}async handleDelete(e){await ae(this.queueControlContext(),e)}queueControlContext(){return{getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:e=>this.broadcast(e)}}async handlePromote(e){await oe({...this.queueControlContext(),promoting:this.promoting,draining:this.draining,isImmediateSendAvailable:t=>this.isImmediateSendAvailable(t),canInjectActiveBatch:(t,n)=>this.canInjectActiveBatch(t,n),interruptQueuedSession:this.opts.interruptQueuedSession,dispatchQueuedMessages:t=>this.dispatchQueuedMessages(t),markExternalQueued:(t,n)=>this.markExternalQueued(t,n),removeBatch:(t,n)=>this.removeBatch(t,n),wakeSession:t=>this.wakeSession(t)},e)}noteTerminal(e){const t=m().sessions[e]?.find(n=>!!n.externalQueuedSubmissionId);t&&this.noteExternalClaim(e,t.clientMessageId??t.id),this.wakeSession(e)}purgeSession(e){ee(e),this.retries.cancel(e)}discardPendingManagedRoomMessages(e){if(this.deletions.hasSession(e)){const i=m().sessions[e]?.length??0;return this.purgeSession(e),i}const t=m(),n=t.sessions[e]??[],s=this.inFlightMessageIds.get(e)??new Set,r=n.filter(i=>i.managedRoom&&!s.has(i.id));if(r.length===0)return 0;const u=n.filter(i=>!r.includes(i));u.length?t.sessions[e]=u:delete t.sessions[e],k(t);for(const i of r)X(e,i.clientMessageId??i.id);return D(this.opts.getRuntime().client),this.logLifecycle("managed-room.discarded-paused",e,{discardedCount:r.length,pendingCount:u.length}),this.broadcast(e),r.length}wakeSession(e){this.drainNext(e).catch(()=>{this.logLifecycle("drain.retry-required",e,{},"error"),this.retries.schedule(e,!0)})}drainIdleQueues(){if(this.disposed)return;const e=m();for(const t of Object.keys(e.sessions))this.wakeSession(t)}async drainNext(e){if(this.disposed||this.draining.has(e)||this.promoting.has(e))return;this.draining.add(e);let t=!1,n=!1,s=[];try{if(this.deletions.hasSession(e)){this.purgeSession(e);return}if(await this.isSessionBusy(e)){const c=m().sessions[e]?.length??0,g=this.deferredLogState.get(e),f=Date.now();(!g||g.pendingCount!==c||f-g.at>=3e4)&&(this.logLifecycle("drain.deferred",e,{pendingCount:c}),this.deferredLogState.set(e,{at:f,pendingCount:c}));return}this.deferredLogState.delete(e);const r=m(),u=r.sessions[e]??[],i=u.filter(c=>{const g=c.clientMessageId??c.id,f=w(e,g).state;return f==="queued"||f==="not_found"});if(i.length!==u.length&&(i.length?r.sessions[e]=i:delete r.sessions[e],k(r),this.logLifecycle("drain.pruned-terminal",e,{prunedCount:u.length-i.length,pendingCount:i.length})),i.some(c=>!!c.externalQueuedSubmissionId)){this.broadcast(e);return}const o=z(i);if(o.length===0){this.broadcast(e);return}s=o,this.inFlightMessageIds.set(e,new Set(o.map(c=>c.id))),this.logLifecycle("dispatch.start",e,{batchCount:o.length,queueMessageId:o[0].id,origin:o[0].origin??"app"}),this.broadcast(e);for(const c of o)Y(e,_(c),"queued");const a=await this.dispatchQueuedMessages(o);if(a.deliveryMode==="external_owner_queue"){this.markExternalQueued(o,a.queuedSubmissionId),this.logLifecycle("dispatch.external-queued",e,{batchCount:o.length,queueMessageId:o[0].id}),this.broadcast(e);return}const d=this.removeBatch(e,o);this.logLifecycle("dispatch.accepted",e,{batchCount:o.length,queueMessageId:o[0].id,pendingCount:d}),this.deferredLogState.delete(e),t=d>0,this.broadcast(e)}catch(r){const u=T(r instanceof Error?r.message:String(r),r instanceof R?"terminal_dispatch_failed":"transient_dispatch_failed"),i=s[0],o=!!(i&&!i.trigger&&!i.clientMessageId&&Date.now()-Date.parse(i.createdAt)>=10*6e4&&this.opts.getRuntime().managerRuntime?.isManagedWorkerSession(e));if(r instanceof R||u==="managed_claim_source_binding_conflict"||o){const d=this.removeBatch(e,s);this.logLifecycle("dispatch.terminal-failure",e,{batchCount:s.length,queueMessageId:s[0]?.id,pendingCount:d,failureClass:o?"stale_legacy_managed_worker_dispatch_failure":u},"error"),t=d>0}else n=!0,this.logLifecycle("dispatch.transient-failure",e,{failureClass:u},"error");this.broadcast(e)}finally{this.inFlightMessageIds.delete(e),this.draining.delete(e);const r=m().sessions[e]??[];r.length?(this.broadcast(e),r.some(u=>!!u.externalQueuedSubmissionId)?this.retries.cancel(e):t?queueMicrotask(()=>this.wakeSession(e)):this.retries.schedule(e,n)):this.retries.cancel(e)}}noteExternalClaim(e,t){const n=m(),s=n.sessions[e]??[],r=s.filter(u=>(u.clientMessageId??u.id)!==t);r.length!==s.length&&(r.length?n.sessions[e]=r:delete n.sessions[e],k(n),this.broadcast(e))}canInjectActiveBatch(e,t){if(!e.adapter.supportsActiveInput||!e.adapter.injectActiveInput||!e.journalRunId)return!1;const n=this.opts.getRuntime().runJournal?.get(t[0].sessionId,e.journalRunId),s=t[0].trigger?.kind==="managed_direct"||t[0].managedAgentDirect?null:"personal";return!!(s&&t[0].systemPrompt==null&&n&&n.source===s&&n.deliveryMode==="direct"&&n.agentType===t[0].agentType&&n.workDir===e.workDir&&n.agentSessionId===e.agentSessionId&&n.modelId===(t[0].modelId??null)&&n.reasoningEffort===(t[0].reasoningEffort??null))}removeBatch(e,t){if(t.length===0)return m().sessions[e]?.length??0;const n=m(),s=new Set(t.map(u=>u.id)),r=(n.sessions[e]??[]).filter(u=>!s.has(u.id));return r.length?n.sessions[e]=r:delete n.sessions[e],k(n),r.length}logLifecycle(e,t,n,s="info"){const r=`[chat.queue] ${JSON.stringify({at:W(),event:e,sessionId:t,...n})}`;s==="error"?console.error(r):console.info(r)}async dispatchQueuedMessages(e){const t=e[0],n=t.trigger?.kind==="scheduled"?t.trigger:null;if(n&&await this.validateScheduledTarget?.({sessionId:t.sessionId,...n})!=="ready")throw new R("schedule_target_unavailable");const s=e.flatMap(l=>{if(l.trigger?.kind==="room_activation"){const{kind:I,...p}=l.trigger;return[p]}return!l.trigger&&l.managedRoom?[l.managedRoom]:[]}),r=e.find(l=>l.trigger?.kind==="manager_event")?.trigger,u=e.some(l=>l.trigger?.kind==="managed_direct"||!!l.managedAgentDirect),i=u||!!n?.bindingId,o=e.find(l=>l.trigger?.kind==="manager_worker")?.trigger,a=r?.kind==="manager_event"||u,d=s.length>0?await this.prepareManagedRoomTurn?.(s):i||r?.kind==="manager_event"?await this.prepareManagedAgentDirectTurn?.(t.sessionId,E(r?.kind==="manager_event"?r:null,u)):void 0;if(s.length>0&&!d)throw new Error("managed_room_turn_preparer_unavailable");if(i&&!d)throw new Error("managed_agent_context_unavailable");if(r?.kind==="manager_event"&&this.opts.getRuntime().managerRuntime?.isManagedRoomBoundManager(t.sessionId)&&!d)throw new Error("managed_agent_context_unavailable");const c=new Set((m().sessions[t.sessionId]??[]).map(l=>l.id));if(this.disposed||this.deletions.hasSession(t.sessionId)||e.some(l=>!c.has(l.id)))throw d?.managedRoomContextToken&&this.opts.getRuntime().revokeManagedRoomContextToken?.(d.managedRoomContextToken),this.disposed?new Error("queue_stopped"):new R("queued_dispatch_cancelled");const g=d??null,f=g?.sessionMode==="manager"?g.managerConfig:null,M=e.length===1?t.text:$(e),y=J(e.flatMap(l=>l.attachments??[])),S=i||r?.kind==="manager_event"&&!!d,h=S?d.agentSessionId?.startsWith("managed:")?C(this.opts.getRuntime(),t):d.agentSessionId:s.length>0?C(this.opts.getRuntime(),t):t.agentSessionId??null,v=d?Q().find(l=>l.sessionId===t.sessionId):null;return await this.opts.dispatchQueuedReq({type:"req",id:`queue-send-${t.id}-${Date.now()}`,method:"chat.send",params:{...P(b()),sessionId:t.sessionId,text:M,agentType:S?d.agentType:t.agentType,sessionMode:g?.sessionMode??t.sessionMode,managerConfig:g?f:t.managerConfig,workDir:S?d.workDir:t.workDir,agentSessionId:h,modelId:q(v?.modelId)??q(t.modelId),systemPrompt:d?.systemPrompt??t.systemPrompt??null,managerDefaultWorkerAgentType:g?g.managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:g?g.managerDefaultWorkerModelId:t.managerDefaultWorkerModelId,reasoningEffort:t.reasoningEffort??void 0,clientMessageId:t.clientMessageId??t.id,attachments:y,externalChannel:a?void 0:t.externalChannel,replyTarget:a?void 0:t.replyTarget,roomContextRegistryKey:a?void 0:d?.roomContextRegistryKey,activationCauseMessageId:a?void 0:s.at(-1)?.causeMessageId,rootCauseMessageId:a?void 0:s.at(-1)?.rootCauseMessageId,activationSequence:a?void 0:s.at(-1)?.sequence,activationHopCount:a?void 0:s.at(-1)?.hopCount,managedRecoverySource:r?.kind==="manager_event"?"manager_event":i?"managed_direct":s.length>0?"managed_room":void 0,managerEventId:r?.kind==="manager_event"?r.eventId:void 0,managedWorkerParentSessionId:o?.kind==="manager_worker"?o.parentSessionId:void 0,managerWorkerRoomOrigin:o?.kind==="manager_worker"?o.roomOrigin:void 0,managerWorkerNativeFull:o?.kind==="manager_worker"&&this.opts.getRuntime().managerRuntime?.isExternalWorkerController(o.parentSessionId,t.workDir)||void 0,managedRoomContextToken:d?.managedRoomContextToken,scheduledDelivery:!!n,suppressExternalOwnerEcho:s.length>0||!!n||void 0,queuedBatchItems:e.map(l=>{const I=N(l);return a?{...I,systemPrompt:d?.systemPrompt??null,externalChannel:null,replyTarget:null}:I}),waitForDispatch:!0}},d??void 0)??{}}markExternalQueued(e,t){const n=m(),s=new Set(e.map(i=>i.id)),r=n.sessions[e[0].sessionId]??[];let u=!1;for(const i of r)s.has(i.id)&&(i.externalQueuedSubmissionId=t||i.id,i.updatedAt=W(),u=!0);u&&k(n)}async isSessionBusy(e){const t=this.opts.getRuntime().recoveryBarrier;if(t?.isDispatchFrozen()||t?.isRecovering(e))return!0;const n=this.opts.getRuntime().sessions.get(e);if(!n)return!1;if(n.currentRunId){if(!(n.currentRunId.startsWith("dispatch:")&&!!this.opts.getRuntime().runJournal&&!n.journalRunId)||(n.adapter.getStatus?await n.adapter.getStatus().catch(()=>null):null)?.active)return!0;this.logLifecycle("drain.recovered-stale-dispatch",e,{staleRunId:n.currentRunId}),n.currentRunId=null,n.currentRunPhase=null}if(!n.adapter.getStatus)return!1;const s=await n.adapter.getStatus().catch(()=>null);return s?.active?(s.runId&&(n.currentRunId=s.runId,n.currentRunPhase=s.runPhase??n.currentRunPhase),!0):!1}broadcast(e){this.opts.getRuntime().client.sendEvent({type:"event",event:"session.queue.update",payload:{queue:this.getSnapshot(e)}})}}export{Ce as ChatQueueManager,qe as TerminalQueuedChatDispatchError,xe as purgeQueuedSessionData};
|
|
1
|
+
import{NativeSourceDeletionStore as N}from"../native-fusion/native-source-deletions.js";import{QueueRetryScheduler as z}from"./queue-retry.js";import{findDuplicateQueuedMessage as x,stripLocalQueueFields as $,takeCompatibleBatch as T,formatQueuedBatch as J,dedupeQueuedAttachments as K,classifyQueueError as G,normalizeQueuedModelId as _,resolveManagedRoomNativeSessionId as D,managedDirectTurnOptions as q}from"./queue-helpers.js";import{CODEX_DESKTOP_SEND_UNAVAILABLE as U}from"@shennian/wire";import{isCodexThreadTailInterrupted as H}from"../native-fusion/codex-files.js";import{mergeProjectedSessions as V}from"./projection.js";import{assertFinishedAttachmentReferences as X,markAttachmentReferences as Y}from"./attachment-transfer-store.js";import{appendMessage as A,getMessageDeliveryStatus as R,listSessionRecords as E,recordSession as B,tombstoneMessage as Z,upsertMessage as ee}from"./store.js";import{handleQueueDispatchFailure as te,queueBlockedUntil as Q,resolveQueueRecoveryNotice as P}from"./queue-dispatch-failure.js";import{resetCommandSpecCache as ne}from"../agents/command-spec.js";import{requestSessionIndexPublish as w}from"./index-publisher.js";import{clearPersistedManagerRoomOrigins as se,purgeQueuedSessionData as ie,readQueue as m,writeQueue as M}from"./queue-storage.js";import{parsePersonalAttachmentReferences as re}from"./attachment-reference.js";import{getPersonalSyncIdentity as b}from"../personal-sync/epoch.js";import{getDaemonInstallationId as W}from"../personal-sync/identity.js";import{isTrustedManagerEvent as ae}from"./manager-event-authority.js";import{getQueueSnapshot as oe,handleQueueDelete as de,handleQueueEdit as ue,handleQueueGet as ge,handleQueuePromote as le}from"./queue-control.js";import{TerminalQueuedChatDispatchError as L,nowIso as F,queueEnvelope as C,queueMessageFromParams as O}from"./queue-message.js";import{purgeQueuedSessionData as Qe}from"./queue-storage.js";import{TerminalQueuedChatDispatchError as be}from"./queue-message.js";class Ae{opts;validateScheduledTarget;async enqueueScheduled(e){return this.handleEnqueue(e,!0)}draining=new Set;promoting=new Set;disposed=!1;retries=new z(e=>{this.wakeSession(e)});deletions=new N;inFlightMessageIds=new Map;deferredLogState=new Map;prepareManagedRoomTurn=null;prepareManagedAgentDirectTurn=null;constructor(e){this.opts=e,se(),setTimeout(()=>this.drainIdleQueues(),0).unref?.()}stop(){this.disposed=!0,this.retries.stop()}getSnapshot(e){return oe({getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:t=>this.broadcast(t)},e)}isImmediateSendAvailable(e){const t=this.opts.getRuntime(),n=t.sessions.get(e);return n?.currentRunId?n.journalRunId?t.runJournal?.get(e,n.journalRunId)?.deliveryMode==="direct":!1:!0}setManagedRoomTurnPreparer(e){this.prepareManagedRoomTurn=e}setManagedAgentDirectTurnPreparer(e){this.prepareManagedAgentDirectTurn=e}async enqueueManagedRoomBatch(e){if(e.length===0)return;const t=this.opts.getRuntime(),n=m(),i=new Set,o=new Map;let d=!1;for(const a of e){const s=a.params;if(this.deletions.hasSession(s.sessionId)){delete n.sessions[s.sessionId],d=!0;continue}if(!s.sessionId||!s.text||!s.agentType||!s.workDir)throw new Error("sessionId, text, agentType and workDir are required");const u=O({...b(W()),...s});typeof s.roomMessageCreatedAt=="string"&&Number.isFinite(Date.parse(s.roomMessageCreatedAt))&&(u.createdAt=new Date(s.roomMessageCreatedAt).toISOString()),u.origin="room",u.managedRoom=a.context,u.trigger={kind:"room_activation",...a.context};const g=n.sessions[s.sessionId]??[],l=x(g,u),f=u.clientMessageId??u.id,S=R(s.sessionId,f);if(!l&&S.state==="not_found")g.push(u),n.sessions[s.sessionId]=g,o.set(`${u.sessionId}\0${f}`,u),i.add(s.sessionId),d=!0;else if(l&&S.state==="not_found")o.set(`${l.sessionId}\0${f}`,l),i.add(s.sessionId);else if(l&&S.state==="queued")i.add(s.sessionId);else if(l){const y=g.filter(k=>k.id!==l.id);y.length?n.sessions[s.sessionId]=y:delete n.sessions[s.sessionId],d=!0}}d&&M(n);let r;for(const a of i)try{for(const s of o.values())s.sessionId===a&&(A(a,C(s),"queued"),B({sessionId:a,agentType:s.agentType,sessionMode:s.sessionMode,managerConfig:s.managerConfig,workDir:s.workDir,agentSessionId:D(t,s),modelId:s.modelId}));this.logLifecycle("enqueue.persisted",a,{origin:"room",pendingCount:m().sessions[a]?.length??0}),this.broadcast(a),this.wakeSession(a)}catch(s){r=s,this.logLifecycle("enqueue.commit-failed",a,{failureClass:G(s instanceof Error?s.message:"","canonical_commit_failed")},"error"),this.retries.schedule(a,!0)}if(i.size&&w(t.client),r)throw r}async handleEnqueue(e,t=!1){const n=this.opts.getRuntime(),i=e.params;if(i.scheduledTask&&!t)throw new Error("schedule_source_untrusted");if((i.managerEventId||i.managerEventRoomOrigin||i.managedWorkerParentSessionId||i.managerWorkerRoomOrigin||e.params.managerWorkerNativeFull||e.params.managedRecoverySource)&&!ae(e))throw new Error("manager_event_source_untrusted");const o=!!(t&&i.scheduledTask?.bindingId);if(V(i.sessionListProjection),!i.sessionId||!i.text||!i.agentType||!i.workDir)return n.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId, text, agentType and workDir are required"}),!1;const d=q(i.managerEventId?{roomOrigin:i.managerEventRoomOrigin}:null,!!i.managedAgentDirect),r=i.managedAgentDirect||o?await this.prepareManagedAgentDirectTurn?.(i.sessionId,d):null;if((i.managedAgentDirect||o)&&!r)throw new Error("managed_agent_context_unavailable");const a=r?E().find(j=>j.sessionId===i.sessionId):null,s=r?{...i,...r,agentType:r.agentType,sessionMode:r.sessionMode,managerConfig:r.managerConfig,workDir:r.workDir,agentSessionId:r.agentSessionId?.startsWith("managed:")?a?.agentSessionId&&!a.agentSessionId.startsWith("managed:")?a.agentSessionId:null:r.agentSessionId,modelId:a?.modelId??void 0,systemPrompt:r.systemPrompt,externalChannel:i.managedAgentDirect?null:i.externalChannel,replyTarget:i.managedAgentDirect?null:i.replyTarget,managerDefaultWorkerAgentType:r.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:r.managerDefaultWorkerModelId}:i,u=n.resolvePath(s.workDir),g=re(s.attachments);g?.length&&X(u,g);const l={text:s.text,attachments:g,localized:!1},f=n.sessions.get(s.sessionId);if(s.agentType==="codex"&&s.agentSessionId&&f?.currentRunId?.startsWith("dispatch:")&&H(s.agentSessionId))return n.client.sendRes({type:"res",id:e.id,ok:!1,error:U}),!1;r?.managedRoomContextToken&&n.revokeManagedRoomContextToken?.(r.managedRoomContextToken);const S=await this.isSessionBusy(s.sessionId),y=m(),k=y.sessions[s.sessionId]??[],h=O({...s,text:l.text,attachments:l.attachments,systemPrompt:r?null:s.systemPrompt});r&&(i.managedAgentDirect&&(h.managedAgentDirect=!0),h.trigger?.kind!=="manager_event"&&h.trigger?.kind!=="scheduled"&&(h.trigger={kind:"managed_direct"}));const v=h.clientMessageId??h.id,c=R(s.sessionId,v);if(c.state!=="not_found")return n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:c.state==="queued",queueMessageId:h.id,...c,queue:this.getSnapshot(s.sessionId)}}),!0;const I=x(k,h);I||(y.sessions[s.sessionId]=[...k,h],M(y));const p=I??h;return B({sessionId:p.sessionId,agentType:p.agentType,sessionMode:p.sessionMode,managerConfig:p.managerConfig,workDir:p.workDir,agentSessionId:p.agentSessionId,modelId:p.modelId}),A(p.sessionId,C(p),"queued"),Y(n.resolvePath(p.workDir),p.attachments??[]),w(n.client),this.logLifecycle("enqueue.persisted",s.sessionId,{origin:s.origin??"app",queueMessageId:p.id,pendingCount:(m().sessions[s.sessionId]??[]).length}),this.broadcast(s.sessionId),n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:!0,queueMessageId:I?.id??h.id,...R(s.sessionId,I?.clientMessageId??I?.id??h.clientMessageId??h.id),queue:this.getSnapshot(s.sessionId),...l.localized?{localizedAttachments:!0}:{}}}),S?this.retries.schedule(s.sessionId):this.wakeSession(s.sessionId),!0}async handleGet(e){await ge(this.queueControlContext(),e)}async handleEdit(e){await ue(this.queueControlContext(),e)}async handleDelete(e){await de(this.queueControlContext(),e)}queueControlContext(){return{getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:e=>this.broadcast(e)}}async handlePromote(e){await le({...this.queueControlContext(),promoting:this.promoting,draining:this.draining,isImmediateSendAvailable:t=>this.isImmediateSendAvailable(t),canInjectActiveBatch:(t,n)=>this.canInjectActiveBatch(t,n),interruptQueuedSession:this.opts.interruptQueuedSession,dispatchQueuedMessages:t=>this.dispatchQueuedMessages(t),markExternalQueued:(t,n)=>this.markExternalQueued(t,n),removeBatch:(t,n)=>this.removeBatch(t,n),wakeSession:t=>this.wakeSession(t)},e)}isDispatching(e){return this.inFlightMessageIds.has(e)}noteTerminal(e){const t=m().sessions[e]?.find(n=>!!n.externalQueuedSubmissionId);t&&this.noteExternalClaim(e,t.clientMessageId??t.id),this.wakeSession(e)}purgeSession(e){ie(e),this.retries.cancel(e)}discardPendingManagedRoomMessages(e){if(this.deletions.hasSession(e)){const r=m().sessions[e]?.length??0;return this.purgeSession(e),r}const t=m(),n=t.sessions[e]??[],i=this.inFlightMessageIds.get(e)??new Set,o=n.filter(r=>r.managedRoom&&!i.has(r.id));if(o.length===0)return 0;const d=n.filter(r=>!o.includes(r));d.length?t.sessions[e]=d:delete t.sessions[e],M(t);for(const r of o)Z(e,r.clientMessageId??r.id);return w(this.opts.getRuntime().client),this.logLifecycle("managed-room.discarded-paused",e,{discardedCount:o.length,pendingCount:d.length}),this.broadcast(e),o.length}wakeSession(e){this.drainNext(e).catch(()=>{this.logLifecycle("drain.retry-required",e,{},"error"),this.retries.schedule(e,!0)})}drainIdleQueues(){if(this.disposed)return;const e=m();for(const t of Object.keys(e.sessions))this.wakeSession(t)}async drainNext(e){if(this.disposed||this.draining.has(e)||this.promoting.has(e))return;this.draining.add(e);let t=!1,n=!1,i=[];try{if(this.deletions.hasSession(e)){this.purgeSession(e);return}if(await this.isSessionBusy(e)){const g=m().sessions[e]?.length??0,l=this.deferredLogState.get(e),f=Date.now();(!l||l.pendingCount!==g||f-l.at>=3e4)&&(this.logLifecycle("drain.deferred",e,{pendingCount:g}),this.deferredLogState.set(e,{at:f,pendingCount:g}));return}this.deferredLogState.delete(e);const o=m(),d=o.sessions[e]??[],r=d.filter(g=>{const l=g.clientMessageId??g.id,f=R(e,l).state;return f==="queued"||f==="not_found"});if(r.length!==d.length&&(r.length?o.sessions[e]=r:delete o.sessions[e],M(o),this.logLifecycle("drain.pruned-terminal",e,{prunedCount:d.length-r.length,pendingCount:r.length})),r.some(g=>!!g.externalQueuedSubmissionId)){this.broadcast(e);return}const a=T(r);if(a.length===0){this.broadcast(e);return}if(Q(a))return;a.some(g=>(g.dispatchBlock?.retryAt??0)>0)&&ne(),i=a,this.inFlightMessageIds.set(e,new Set(a.map(g=>g.id))),this.logLifecycle("dispatch.start",e,{batchCount:a.length,queueMessageId:a[0].id,origin:a[0].origin??"app"}),this.broadcast(e);for(const g of a)ee(e,C(g),"queued");const s=await this.dispatchQueuedMessages(a);if(s.deliveryMode==="external_owner_queue"){this.markExternalQueued(a,s.queuedSubmissionId),P(a),a.some(g=>g.dispatchBlock)&&w(this.opts.getRuntime().client),this.logLifecycle("dispatch.external-queued",e,{batchCount:a.length,queueMessageId:a[0].id}),this.broadcast(e);return}const u=this.removeBatch(e,a);P(a),a.some(g=>g.dispatchBlock)&&w(this.opts.getRuntime().client),this.logLifecycle("dispatch.accepted",e,{batchCount:a.length,queueMessageId:a[0].id,pendingCount:u}),this.deferredLogState.delete(e),t=u>0,this.broadcast(e)}catch(o){const d=te({error:o,sessionId:e,batch:i,publish:()=>w(this.opts.getRuntime().client),isManagedWorker:!!this.opts.getRuntime().managerRuntime?.isManagedWorkerSession(e),removeBatch:()=>this.removeBatch(e,i),log:(r,a)=>this.logLifecycle(r,e,a,"error")});t=d.drainAgain,n=d.transientFailure,this.broadcast(e)}finally{this.inFlightMessageIds.delete(e),this.draining.delete(e);const o=m().sessions[e]??[];o.length?(this.broadcast(e),o.some(d=>!!d.externalQueuedSubmissionId)?this.retries.cancel(e):t?queueMicrotask(()=>this.wakeSession(e)):this.retries.schedule(e,n,Q(T(o)))):this.retries.cancel(e)}}noteExternalClaim(e,t){const n=m(),i=n.sessions[e]??[],o=i.filter(d=>(d.clientMessageId??d.id)!==t);o.length!==i.length&&(o.length?n.sessions[e]=o:delete n.sessions[e],M(n),this.broadcast(e))}canInjectActiveBatch(e,t){if(!e.adapter.supportsActiveInput||!e.adapter.injectActiveInput||!e.journalRunId)return!1;const n=this.opts.getRuntime().runJournal?.get(t[0].sessionId,e.journalRunId),i=t[0].trigger?.kind==="managed_direct"||t[0].managedAgentDirect?null:"personal";return!!(i&&t[0].systemPrompt==null&&n&&n.source===i&&n.deliveryMode==="direct"&&n.agentType===t[0].agentType&&n.workDir===e.workDir&&n.agentSessionId===e.agentSessionId&&n.modelId===(t[0].modelId??null)&&n.reasoningEffort===(t[0].reasoningEffort??null))}removeBatch(e,t){if(t.length===0)return m().sessions[e]?.length??0;const n=m(),i=new Set(t.map(d=>d.id)),o=(n.sessions[e]??[]).filter(d=>!i.has(d.id));return o.length?n.sessions[e]=o:delete n.sessions[e],M(n),o.length}logLifecycle(e,t,n,i="info"){const o=`[chat.queue] ${JSON.stringify({at:F(),event:e,sessionId:t,...n})}`;i==="error"?console.error(o):console.info(o)}async dispatchQueuedMessages(e){const t=e[0],n=t.trigger?.kind==="scheduled"?t.trigger:null;if(n&&await this.validateScheduledTarget?.({sessionId:t.sessionId,...n})!=="ready")throw new L("schedule_target_unavailable");const i=e.flatMap(c=>{if(c.trigger?.kind==="room_activation"){const{kind:I,...p}=c.trigger;return[p]}return!c.trigger&&c.managedRoom?[c.managedRoom]:[]}),o=e.find(c=>c.trigger?.kind==="manager_event")?.trigger,d=e.some(c=>c.trigger?.kind==="managed_direct"||!!c.managedAgentDirect),r=d||!!n?.bindingId,a=e.find(c=>c.trigger?.kind==="manager_worker")?.trigger,s=o?.kind==="manager_event"||d,u=i.length>0?await this.prepareManagedRoomTurn?.(i):r||o?.kind==="manager_event"?await this.prepareManagedAgentDirectTurn?.(t.sessionId,q(o?.kind==="manager_event"?o:null,d)):void 0;if(i.length>0&&!u)throw new Error("managed_room_turn_preparer_unavailable");if(r&&!u)throw new Error("managed_agent_context_unavailable");if(o?.kind==="manager_event"&&this.opts.getRuntime().managerRuntime?.isManagedRoomBoundManager(t.sessionId)&&!u)throw new Error("managed_agent_context_unavailable");const g=new Set((m().sessions[t.sessionId]??[]).map(c=>c.id));if(this.disposed||this.deletions.hasSession(t.sessionId)||e.some(c=>!g.has(c.id)))throw u?.managedRoomContextToken&&this.opts.getRuntime().revokeManagedRoomContextToken?.(u.managedRoomContextToken),this.disposed?new Error("queue_stopped"):new L("queued_dispatch_cancelled");const l=u??null,f=l?.sessionMode==="manager"?l.managerConfig:null,S=e.length===1?t.text:J(e),y=K(e.flatMap(c=>c.attachments??[])),k=r||o?.kind==="manager_event"&&!!u,h=k?u.agentSessionId?.startsWith("managed:")?D(this.opts.getRuntime(),t):u.agentSessionId:i.length>0?D(this.opts.getRuntime(),t):t.agentSessionId??null,v=u?E().find(c=>c.sessionId===t.sessionId):null;return await this.opts.dispatchQueuedReq({type:"req",id:`queue-send-${t.id}-${Date.now()}`,method:"chat.send",params:{...b(W()),sessionId:t.sessionId,text:S,agentType:k?u.agentType:t.agentType,sessionMode:l?.sessionMode??t.sessionMode,managerConfig:l?f:t.managerConfig,workDir:k?u.workDir:t.workDir,agentSessionId:h,modelId:_(v?.modelId)??_(t.modelId),systemPrompt:u?.systemPrompt??t.systemPrompt??null,managerDefaultWorkerAgentType:l?l.managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:l?l.managerDefaultWorkerModelId:t.managerDefaultWorkerModelId,reasoningEffort:t.reasoningEffort??void 0,clientMessageId:t.clientMessageId??t.id,attachments:y,externalChannel:s?void 0:t.externalChannel,replyTarget:s?void 0:t.replyTarget,roomContextRegistryKey:s?void 0:u?.roomContextRegistryKey,activationCauseMessageId:s?void 0:i.at(-1)?.causeMessageId,rootCauseMessageId:s?void 0:i.at(-1)?.rootCauseMessageId,activationSequence:s?void 0:i.at(-1)?.sequence,activationHopCount:s?void 0:i.at(-1)?.hopCount,managedRecoverySource:o?.kind==="manager_event"?"manager_event":r?"managed_direct":i.length>0?"managed_room":void 0,managerEventId:o?.kind==="manager_event"?o.eventId:void 0,managedWorkerParentSessionId:a?.kind==="manager_worker"?a.parentSessionId:void 0,managerWorkerRoomOrigin:a?.kind==="manager_worker"?a.roomOrigin:void 0,managerWorkerNativeFull:a?.kind==="manager_worker"&&this.opts.getRuntime().managerRuntime?.isExternalWorkerController(a.parentSessionId,t.workDir)||void 0,managedRoomContextToken:u?.managedRoomContextToken,scheduledDelivery:!!n,suppressExternalOwnerEcho:i.length>0||!!n||void 0,queuedBatchItems:e.map(c=>{const I=$(c);return s?{...I,systemPrompt:u?.systemPrompt??null,externalChannel:null,replyTarget:null}:I}),waitForDispatch:!0}},u??void 0)??{}}markExternalQueued(e,t){const n=m(),i=new Set(e.map(r=>r.id)),o=n.sessions[e[0].sessionId]??[];let d=!1;for(const r of o)i.has(r.id)&&(r.externalQueuedSubmissionId=t||r.id,r.updatedAt=F(),d=!0);d&&M(n)}async isSessionBusy(e){const t=this.opts.getRuntime().recoveryBarrier;if(t?.isDispatchFrozen()||t?.isRecovering(e))return!0;const n=this.opts.getRuntime().sessions.get(e);if(!n)return!1;if(n.currentRunId){if(!(n.currentRunId.startsWith("dispatch:")&&!!this.opts.getRuntime().runJournal&&!n.journalRunId)||(n.adapter.getStatus?await n.adapter.getStatus().catch(()=>null):null)?.active)return!0;this.logLifecycle("drain.recovered-stale-dispatch",e,{staleRunId:n.currentRunId}),n.currentRunId=null,n.currentRunPhase=null}if(!n.adapter.getStatus)return!1;const i=await n.adapter.getStatus().catch(()=>null);return i?.active?(i.runId&&(n.currentRunId=i.runId,n.currentRunPhase=i.runPhase??n.currentRunPhase),!0):!1}broadcast(e){this.opts.getRuntime().client.sendEvent({type:"event",event:"session.queue.update",payload:{queue:this.getSnapshot(e)}})}}export{Ae as ChatQueueManager,be as TerminalQueuedChatDispatchError,Qe as purgeQueuedSessionData};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n={managed_agent_restricted_room_unsupported:"\u8BE5\u667A\u80FD\u4F53\u4F7F\u7528\u4E86\u9650\u5236\u6743\u9650\uFF0C\u6682\u4E0D\u652F\u6301\u7FA4\u804A\uFF0C\u8BF7\u5728\u667A\u80FD\u4F53\u8BBE\u7F6E\u4E2D\u6539\u7528\u5168\u90E8\u6743\u9650",managed_room_context_expired:"\u7FA4\u6743\u9650\u5DF2\u91CD\u7F6E\uFF08\u795E\u5FF5\u91CD\u542F\u6216\u88AB\u65B0\u4E00\u8F6E\u53D6\u4EE3\uFF09\uFF0C\u7B49\u4E0B\u4E00\u6B21\u88AB\u7FA4\u6D88\u606F\u5524\u9192\u540E\u4F1A\u91CD\u65B0\u6388\u6743",managed_room_context_revoked:"\u8BE5\u667A\u80FD\u4F53\u5DF2\u4E0D\u518D\u5C5E\u4E8E\u6B64\u7FA4\uFF0C\u6216\u7FA4\u7ED1\u5B9A\u5DF2\u53D8\u5316",managed_room_context_invalid:"\u672C\u673A\u6388\u6743\u5F02\u5E38\uFF0C\u8BF7\u5728\u795E\u5FF5\u4E2D\u68C0\u67E5\u673A\u5668\u914D\u5BF9\u72B6\u6001",managed_room_context_unavailable:"\u7FA4\u4E0A\u4E0B\u6587\u4E0D\u53EF\u7528\uFF0C\u8BF7\u786E\u8BA4\u795E\u5FF5\u6B63\u5728\u8FD0\u884C\u4E14\u667A\u80FD\u4F53\u4ECD\u5728\u7FA4\u91CC",managed_room_action_forbidden:"\u5F53\u524D\u8FD9\u4E00\u8F6E\u6CA1\u6709\u53D1\u9001\u6743\u9650",machine_not_authorized:"\u672C\u673A\u5C1A\u672A\u6388\u6743\uFF0C\u8BF7\u5148\u5728\u795E\u5FF5\u4E2D\u5B8C\u6210\u914D\u5BF9",room_message_empty:"\u6D88\u606F\u5185\u5BB9\u4E3A\u7A7A",room_write_forbidden:"\u8BE5\u667A\u80FD\u4F53\u6CA1\u6709\u6B64\u7FA4\u7684\u53D1\u8A00\u6743\u9650",server_unavailable:"\u65E0\u6CD5\u8FDE\u63A5\u795E\u5FF5\u670D\u52A1\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC"};function t(o){return n[o]??`\u53D1\u9001\u5931\u8D25\uFF08${o}\uFF09`}function a(o){const e=o.roomSendOutcome;if(!e||e.successes>0||e.failureCodes.length===0)return null;const r=e.failureCodes[e.failureCodes.length-1];return`\u672C\u8F6E\u672A\u80FD\u5728\u7FA4\u91CC\u56DE\u590D\uFF1A${t(r)}\u3002`}export{t as describeRoomReplyFailure,a as roomReplyFailureNotice};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
`,{encoding:"utf8",mode:384,flag:"wx"}),process.platform!=="win32"&&
|
|
1
|
+
import o from"node:fs";import{renameSyncWithRetry as u}from"../../fs/atomic-rename.js";import s from"node:path";import{createHash as S,randomUUID as y}from"node:crypto";import{resolveShennianPath as w}from"../../config/index.js";import{RUN_JOURNAL_SCHEMA_VERSION as I,isRecoverableJournalPhase as f,parseRunJournalRecord as h}from"./schema.js";function m(a,t){return S("sha256").update(`${a}\0${t}`).digest("hex")+".json"}function c(a){try{const t=o.lstatSync(a);if(t.isSymbolicLink()||!t.isFile())throw new Error("journal target is not a regular file")}catch(t){if(t.code!=="ENOENT")throw t}}function l(a){if(process.platform==="win32")return;const t=o.openSync(a,"r");try{o.fsyncSync(t)}finally{o.closeSync(t)}}function p(a){for(let t=0;t<3;t+=1){o.mkdirSync(a,{recursive:!0,mode:448});try{const r=o.lstatSync(a);if(r.isSymbolicLink()||!r.isDirectory())throw new Error("journal directory is unsafe");process.platform!=="win32"&&o.chmodSync(a,448);return}catch(r){if(r.code!=="ENOENT"||t===2)throw r}}}class D{daemonInstallationId;directory;quarantineDirectory;constructor(t,r={}){this.daemonInstallationId=t,this.directory=r.directory??w("runtime","run-recovery","active"),this.quarantineDirectory=s.join(s.dirname(this.directory),"quarantine"),p(this.directory),p(this.quarantineDirectory)}begin(t){const r=new Date().toISOString(),e={...t,schemaVersion:I,lastObservedEventSeq:-1,phase:"dispatching",upgradeJobId:null,interruptionReason:null,continueDispatchState:"none",deliveryMode:"direct",externalRunId:null,recoveryAttempts:0,recoveryReason:null,createdAt:r,updatedAt:r};return this.write(e),e}update(t,r,e){const n=this.get(t,r);if(!n)return null;const i=h({...n,...e,updatedAt:new Date().toISOString()});return this.write(i),i}get(t,r){const e=this.recordPath(t,r);try{c(e);const n=h(JSON.parse(o.readFileSync(e,"utf8")));if(n.sessionId!==t||n.runId!==r)throw new Error("journal identity mismatch");return n}catch(n){return n.code==="ENOENT"||this.quarantine(e),null}}loadRecoverable(){return this.load(t=>f(t.phase))}loadPendingReconciliation(){return this.load(t=>f(t.phase)||t.phase==="interrupted_by_upgrade"||t.phase==="recovery_failed"||t.phase==="aborted")}load(t){const r=[],e=[];for(const n of o.readdirSync(this.directory)){if(!n.endsWith(".json"))continue;const i=s.join(this.directory,n);try{c(i);const d=h(JSON.parse(o.readFileSync(i,"utf8")));if(d.daemonInstallationId!==this.daemonInstallationId)throw new Error("daemon installation identity mismatch");if(m(d.sessionId,d.runId)!==n)throw new Error("journal filename identity mismatch");t(d)&&r.push(d)}catch{e.push(this.quarantine(i))}}return r.sort((n,i)=>n.createdAt.localeCompare(i.createdAt)),{records:r,quarantined:e}}markPlannedUpgrade(t){const{records:r}=this.loadRecoverable();for(const e of r)this.update(e.sessionId,e.runId,{upgradeJobId:t,interruptionReason:"planned_upgrade"});return l(this.directory),r.length}markAborted(t,r){this.update(t,r,{phase:"aborted"})}markSessionAborted(t){const r=this.loadRecoverable().records.filter(e=>e.sessionId===t);for(const e of r)this.markAborted(e.sessionId,e.runId);return this.sync(),r.length}remove(t,r){const e=this.recordPath(t,r);c(e);try{o.unlinkSync(e)}catch(n){if(n.code!=="ENOENT")throw n}l(this.directory)}sync(){for(const t of o.readdirSync(this.directory)){if(!t.endsWith(".json"))continue;const r=s.join(this.directory,t);c(r);const e=o.openSync(r,process.platform==="win32"?"r+":"r");try{o.fsyncSync(e)}finally{o.closeSync(e)}}l(this.directory)}recordPath(t,r){return s.join(this.directory,m(t,r))}write(t){if(t.daemonInstallationId!==this.daemonInstallationId)throw new Error("daemon installation identity mismatch");const r=h(t),e=this.recordPath(r.sessionId,r.runId);c(e);const n=`${e}.tmp-${process.pid}-${y()}`;try{o.writeFileSync(n,`${JSON.stringify(r,null,2)}
|
|
2
|
+
`,{encoding:"utf8",mode:384,flag:"wx"}),process.platform!=="win32"&&o.chmodSync(n,384);const i=o.openSync(n,process.platform==="win32"?"r+":"r");try{o.fsyncSync(i)}finally{o.closeSync(i)}u(n,e),l(this.directory)}finally{try{o.unlinkSync(n)}catch{}}}quarantine(t){const r=s.join(this.quarantineDirectory,`${s.basename(t)}.${Date.now()}.${y()}.invalid`);try{return c(t),u(t,r),process.platform!=="win32"&&o.chmodSync(r,384),l(this.quarantineDirectory),r}catch{return t}}}export{D as ActiveRunJournal};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{upsertMessage as a}from"./store.js";const l=10*6e4;function d(){const t=Number(process.env.SHENNIAN_RUN_STALL_MS);return Number.isFinite(t)&&t>=1e3?t:l}const N=new Set(["waiting_approval","waiting_user_input"]);function _(t){return`AI \u5DF2\u7ECF ${Math.max(1,Math.round(t/6e4))} \u5206\u949F\u6CA1\u6709\u4EFB\u4F55\u8F93\u51FA\uFF0C\u53EF\u80FD\u5361\u4F4F\u4E86\u3002\u5982\u679C\u5B83\u6B63\u5728\u6267\u884C\u8017\u65F6\u5F88\u957F\u7684\u547D\u4EE4\uFF0C\u53EF\u4EE5\u7EE7\u7EED\u7B49\u5F85\uFF1B\u5426\u5219\u8BF7\u70B9\u51FB\u201C\u505C\u6B62\u201D\u540E\u91CD\u65B0\u53D1\u9001\u3002\u795E\u5FF5\u4E0D\u4F1A\u81EA\u52A8\u4E2D\u65AD\u5B83\uFF0C\u540E\u9762\u6392\u961F\u7684\u6D88\u606F\u4F1A\u7B49\u8FD9\u4E00\u8F6E\u7ED3\u675F\u3002`}function A(t,n,o=Date.now(),i=d()){const c=[];for(const[r,e]of t){if(!e.currentRunId||e.stalledNotice||e.currentRunPhase&&N.has(e.currentRunPhase)||e.lastProviderActivityAt===void 0)continue;const u=o-e.lastProviderActivityAt;if(u<i)continue;const s={id:`run-stalled-${e.currentRunId}`,ts:o};e.stalledNotice=s,a(r,{id:s.id,sessionId:r,role:"agent",ts:s.ts,payload:_(u)}),n(),c.push(r)}return c}function p(t,n,o){n.lastProviderActivityAt=Date.now();const i=n.stalledNotice;i&&(n.stalledNotice=null,a(t,{id:i.id,sessionId:t,role:"agent",ts:i.ts,payload:o?"\u8FD9\u4E00\u8F6E\u5DF2\u7ECF\u7ED3\u675F\uFF0C\u4E0A\u9762\u201C\u53EF\u80FD\u5361\u4F4F\u201D\u7684\u63D0\u793A\u65E0\u9700\u5904\u7406\u3002":"AI \u5DF2\u6062\u590D\u8F93\u51FA\uFF0C\u4E0A\u9762\u201C\u53EF\u80FD\u5361\u4F4F\u201D\u7684\u63D0\u793A\u65E0\u9700\u5904\u7406\u3002"}))}export{A as checkRunStalls,p as noteRunActivity,d as runStallThresholdMs};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{SESSION_SYNC_DATA_EPOCH as x,SESSION_SYNC_PROTOCOL_VERSION as I,SESSION_TITLE_SOURCE_PRIORITY as y,isInternalSession as O,isToolPayload as P,sessionPreviewFromPayload as h}from"@shennian/wire";import D from"node:crypto";import c from"node:fs";import p from"node:path";import{NativeSourceDeletionStore as G}from"../native-fusion/native-source-deletions.js";import{registerInternalNativeSource as L}from"../native-fusion/source-visibility.js";import{getDaemonInstallationId as g}from"../personal-sync/identity.js";import{PERSONAL_SYNC_V1_ROOT_NAME as q,resolvePersonalSyncV1Path as j}from"../personal-sync/paths.js";import{CanonicalSessionStore as F}from"./canonical-store.js";const _=120;function w(t){if(t.length<=_)return t;let e=t.slice(0,_);const n=e.charCodeAt(e.length-1);return n>=55296&&n<=56319&&(e=e.slice(0,-1)),e}let M=null,k=null;function R(){return j()}function u(){const t=p.join(R(),"canonical");return(!M||k!==t)&&(M=new F(t,g()),k=t),M}function T(){return p.join(R(),"session-index.json")}function d(){const t=T();if(!c.existsSync(t))return{};const e=JSON.parse(c.readFileSync(t,"utf8"));if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`invalid personal session index: ${t}`);const n=g();for(const s of Object.values(e))if(s.daemonInstallationId!==n)throw new Error(`personal session index belongs to another daemon installation: ${t}`);return e}function S(t){X(T(),t)}function b(t){return h(t.payload,120)}function A(t){if(new G({rootDir:R(),daemonInstallationId:g()}).hasSession(t))throw new Error(`session_deleted:${t}`)}function W(t){A(t.sessionId),g();const e=d(),n=e[t.sessionId],s=new Date().toISOString(),i=u().getManifest(t.sessionId)?.bodyRevision??n?.bodyRevision??0,o=u().getManifest(t.sessionId),a=H(n,t),r=t.attentionId?.trim()||null,l=Array.from(new Set([...n?.seenAttentionIds??[],...n?.lastAttentionId?[n.lastAttentionId]:[]])),f=!!(r&&!l.includes(r)),v=t.lastMessagePreview===null?{preview:null,messageId:null,at:null}:t.lastMessagePreview!==void 0&&t.lastMessagePreviewMessageId&&t.lastMessagePreviewAt?{preview:t.lastMessagePreview,messageId:t.lastMessagePreviewMessageId,at:t.lastMessagePreviewAt}:{preview:n?.lastMessagePreview??null,messageId:n?.lastMessagePreviewMessageId??null,at:n?.lastMessagePreviewAt??null},E=Date.parse(t.lastVisibleEventAt??""),C=Date.parse(n?.lastVisibleEventAt??""),U=Number.isFinite(E)&&(!Number.isFinite(C)||E>=C)?t.lastVisibleEventAt:n?.lastVisibleEventAt??null,m={daemonInstallationId:g(),sessionId:t.sessionId,agentType:t.agentType,sessionMode:t.sessionMode??n?.sessionMode,nativeSessionVisibility:O({...n,id:t.sessionId})||O({...n,...t,id:t.sessionId,sessionMode:t.sessionMode??n?.sessionMode})?"internal":"user",managerConfig:t.managerConfig??n?.managerConfig??null,workDir:t.workDir,agentSessionId:t.agentSessionId??n?.agentSessionId??null,modelId:t.modelId??n?.modelId??null,managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType??n?.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:t.managerDefaultWorkerModelId??n?.managerDefaultWorkerModelId??null,status:t.status??n?.status??"active",createdAt:n?.createdAt??s,updatedAt:s,lastActivityAt:t.lastActivityAt??n?.lastActivityAt??s,lastMessagePreview:v.preview,lastMessagePreviewMessageId:v.messageId,lastMessagePreviewAt:v.at,lastVisibleEventAt:U,localReady:n?.localReady===!0||t.localReady===!0,firstUserMessageId:n?.firstUserMessageId??t.firstUserMessageId??null,firstUserBodyRevision:n?.firstUserBodyRevision??t.firstUserBodyRevision??null,bodyRevision:i,indexRevision:(n?.indexRevision??0)+1,...a,firstAvailableSeq:o?.firstAvailableSeq??n?.firstAvailableSeq??null,visibleMessageCount:o?.visibleMessageCount??n?.visibleMessageCount??0,lastVisibleMessageId:o?.lastVisibleMessageId??n?.lastVisibleMessageId??null,attentionCount:(n?.attentionCount??0)+(f?1:0),lastAttentionId:f?r:n?.lastAttentionId??null,seenAttentionIds:f&&r?[...l,r]:l,lastBodyCommittedAt:o?.lastBodyCommittedAt??n?.lastBodyCommittedAt??null,deletionRevision:n?.deletionRevision??0,deletedAt:t.deletedAt??n?.deletedAt??null,syncedIndexRevision:n?.syncedIndexRevision??0,indexSyncState:"pending",indexSyncStateRevision:(n?.indexRevision??0)+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,indexQuarantineCode:null,titleGenerationAttemptedAt:n?.titleGenerationAttemptedAt&&n.titleGenerationNextAttemptAt!==void 0?n.titleGenerationAttemptedAt:null,titleGenerationNextAttemptAt:n?.titleGenerationNextAttemptAt??null,titleGenerationAttempts:n?.titleGenerationAttempts??0};return m.nativeSessionVisibility==="internal"&&m.agentSessionId&&L(m.sessionId,m.agentType,m.agentSessionId),e[t.sessionId]=m,S(e),m}function $(){return Object.values(d())}function le(t){if(!t)throw new Error("sessionId is required");const e=d();e[t]&&(delete e[t],S(e))}function re(t){u().purgeSession(t)}function Q(){const t=d();let e=!1;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){const o=w(i.title);if(o===i.title)continue;const a=i.indexRevision+1;t[s]={...i,title:o,indexRevision:a,indexSyncState:"pending",indexSyncStateRevision:a,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,indexQuarantineCode:null,updatedAt:n},e=!0}e&&S(t)}function de(){const t=g();return J(),z(),Q(),$().filter(e=>{const n=e.indexSyncStateRevision===e.indexRevision;return e.indexQuarantineCode||n&&(e.indexSyncState==="quarantined"||e.indexSyncState==="terminal")||n&&e.indexSyncNextAttemptAt&&Date.parse(e.indexSyncNextAttemptAt)>Date.now()?!1:e.indexRevision>e.syncedIndexRevision&&e.localReady&&!!e.firstUserMessageId&&e.firstUserBodyRevision!=null}).sort((e,n)=>e.indexRevision-n.indexRevision).map(e=>{const n=!!(e.lastMessagePreview&&e.lastMessagePreviewMessageId&&e.lastMessagePreviewAt);return{protocolVersion:I,dataEpoch:x,daemonInstallationId:t,session:{id:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,nativeSessionVisibility:e.nativeSessionVisibility,managerConfig:e.managerConfig,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null,managerDefaultWorkerAgentType:e.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:e.managerDefaultWorkerModelId??null,title:e.title,titleSource:e.titleSource,titleRevision:e.titleRevision,titleLockedByUser:e.titleLockedByUser,titleOriginEventId:e.titleOriginEventId,status:e.status??"active",workDir:e.workDir,lastMessagePreview:n?e.lastMessagePreview:null,lastMessagePreviewMessageId:n?e.lastMessagePreviewMessageId:null,lastMessagePreviewAt:n?e.lastMessagePreviewAt:null,lastVisibleEventAt:e.lastVisibleEventAt??e.lastMessagePreviewAt??null,bodyStorageMode:"machine_local",localReady:!0,firstUserBoundary:{role:"user",messageId:e.firstUserMessageId,bodyRevision:e.firstUserBodyRevision},bodyRevision:e.bodyRevision,indexRevision:e.indexRevision,firstAvailableSeq:e.firstAvailableSeq,visibleMessageCount:e.visibleMessageCount,lastVisibleMessageId:e.lastVisibleMessageId,attentionCount:e.attentionCount??0,lastAttentionId:e.lastAttentionId??null,lastBodyCommittedAt:e.lastBodyCommittedAt,deletionRevision:e.deletionRevision,lastActivityAt:e.lastActivityAt,createdAt:e.createdAt,updatedAt:e.updatedAt,deletedAt:e.deletedAt}}})}function ce(t,e){const n=d(),s=n[t];if(!(!s||e<=s.syncedIndexRevision)){if(e>s.indexRevision)throw new Error(`cannot acknowledge future index revision ${e} for ${t}`);n[t]={...s,syncedIndexRevision:e,indexSyncState:"applied",indexSyncStateRevision:e,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null},S(n)}}function ue(){const t=d();let e=0;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){if(i.deletedAt||i.indexQuarantineCode||!i.localReady)continue;const o=i.indexRevision+1;t[s]={...i,indexRevision:o,indexSyncState:"pending",indexSyncStateRevision:o,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:n},e+=1}return e>0&&S(t),e}function ge(t){const e=d(),n=e[t.sessionId];if(!n||n.indexRevision!==t.indexRevision)return"terminal";const i=(n.indexSyncStateRevision===t.indexRevision?n.indexSyncAttempts??0:0)+1;let o=t.disposition;o==="retry"&&i>=(t.maxAttempts??8)&&(o="terminal");const a=t.now??Date.now(),r=Math.min(5e3*2**Math.max(0,i-1),360*60*1e3),l=Math.round(r*.2*(Math.random()*2-1));return e[t.sessionId]={...n,indexSyncState:o==="retry"?"pending":o,indexSyncStateRevision:t.indexRevision,indexSyncAttempts:i,indexSyncNextAttemptAt:o==="retry"?new Date(a+r+l).toISOString():null,indexSyncErrorCode:t.code,indexQuarantineCode:o==="quarantined"?t.code:n.indexQuarantineCode??null},S(e),o}const Y=2*6e4;function Se(t=Date.now(),e=Y){const n=d(),s=[],i=new Date(t).toISOString();for(const o of Object.values(n)){if(o.titleSource!=="first_user_fallback"||o.titleLockedByUser||o.titleGenerationAttemptedAt||!o.title.trim()||o.syncedIndexRevision<o.indexRevision||o.titleGenerationNextAttemptAt&&Date.parse(o.titleGenerationNextAttemptAt)>t)continue;const a=o.status==="completed"||o.status==="failed",r=o.visibleMessageCount>=2;let l=null;if(o.agentType==="claude"&&r?l="agent_native_unavailable":a?l="terminal":r&&t-Date.parse(o.createdAt)>=e&&(l="grace_elapsed"),!l)continue;const f=h(o.title,240);if(!f)continue;const v=D.randomUUID();n[o.sessionId]={...o,titleGenerationAttemptedAt:i,titleGenerationNextAttemptAt:null,titleGenerationAttempts:(o.titleGenerationAttempts??0)+1},s.push({sessionId:o.sessionId,requestId:v,titleSeed:f,baseTitleRevision:o.titleRevision,eligibility:l})}return s.length>0&&S(n),s}function fe(t,e=Date.now()){const n=d(),s=n[t];if(!s?.titleGenerationAttemptedAt||s.titleSource!=="first_user_fallback")return null;const i=Math.max(1,s.titleGenerationAttempts??1),o=Math.min(10*6e4,3e4*2**Math.min(i-1,5)),a=new Date(e+o).toISOString();return n[t]={...s,titleGenerationAttemptedAt:null,titleGenerationNextAttemptAt:a},S(n),a}function ve(t,e){const s=d()[t];return!s||s.titleLockedByUser||y[s.titleSource]>=y.shennian_generated||e.titleRevision<=s.titleRevision?!1:(W({sessionId:t,agentType:s.agentType,sessionMode:s.sessionMode,managerConfig:s.managerConfig,workDir:s.workDir,agentSessionId:s.agentSessionId,modelId:s.modelId,status:s.status,title:e.title,titleSource:"shennian_generated",titleRevision:e.titleRevision,titleLockedByUser:!1,titleOriginEventId:e.titleOriginEventId}),!0)}function me(t,e,n){A(t),g();const s=u().append(t,e,n);return N(t,e,s.bodyRevision),s.bodyRevision}function ye(t,e,n){A(t),g();const s=u().upsert(t,e,n);return N(t,e,s.bodyRevision),s.bodyRevision}function Ae(t,e){const n=u().getMessageState(t,e);return!n||n.tombstoned||!n.message||!n.deliveryState?{protocolVersion:I,dataEpoch:x,daemonInstallationId:g(),state:"not_found",sessionId:t,clientMessageId:e}:{protocolVersion:I,dataEpoch:x,daemonInstallationId:g(),state:n.deliveryState,sessionId:t,clientMessageId:e,messageId:n.message.id,deliveryState:n.deliveryState,bodyRevision:n.lastRevision,committedAt:new Date(n.message.ts).toISOString()}}function xe(t,e){A(t),g();const n=u().tombstone(t,e),s=d(),i=s[t];if(i){const o=e===i.lastMessagePreviewMessageId?V(t):{preview:i.lastMessagePreview??null,messageId:i.lastMessagePreviewMessageId??null,at:i.lastMessagePreviewAt??null};s[t]={...i,bodyRevision:n.bodyRevision,indexRevision:i.indexRevision+1,indexSyncState:"pending",indexSyncStateRevision:i.indexRevision+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:new Date().toISOString(),lastMessagePreview:o.preview,lastMessagePreviewMessageId:o.messageId,lastMessagePreviewAt:o.at,lastVisibleEventAt:B(t)},S(s)}return n.bodyRevision}function N(t,e,n){const s=d(),i=s[t];if(!i)return;const o=b(e),a=o?{lastMessagePreview:o,lastMessagePreviewMessageId:e.id,lastMessagePreviewAt:new Date(e.ts).toISOString()}:null,r=o||P(e.payload)?new Date(e.ts).toISOString():i.lastVisibleEventAt,l=u().getManifest(t),f=e.role==="user"&&o&&!i.title?{title:w(o),titleSource:"first_user_fallback",titleRevision:i.titleRevision+1,titleLockedByUser:!1,titleOriginEventId:e.id}:null,v=e.role==="user"&&!i.localReady?{localReady:!0,firstUserMessageId:e.id,firstUserBodyRevision:n}:null;s[t]={...i,...f??{},...v??{},bodyRevision:n,indexRevision:i.indexRevision+1,indexSyncState:"pending",indexSyncStateRevision:i.indexRevision+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:new Date().toISOString(),lastActivityAt:new Date(e.ts).toISOString(),lastVisibleEventAt:r,...a??{},firstAvailableSeq:l?.firstAvailableSeq??i.firstAvailableSeq,visibleMessageCount:l?.visibleMessageCount??i.visibleMessageCount,lastVisibleMessageId:l?.lastVisibleMessageId??i.lastVisibleMessageId,attentionCount:i.attentionCount??0,lastAttentionId:i.lastAttentionId??null,lastBodyCommittedAt:l?.lastBodyCommittedAt??i.lastBodyCommittedAt},S(s)}function V(t){let e;do{const n=u().readPage(t,{limit:500,beforeSequence:e});for(let s=n.entries.length-1;s>=0;s-=1){const i=n.entries[s],o=b(i.message);if(o)return{preview:o,messageId:i.message.id,at:new Date(i.message.ts).toISOString()}}if(!n.hasOlder||n.entries.length===0)break;e=n.entries[0].sequence}while(e!==void 0);return{preview:null,messageId:null,at:null}}function B(t){let e;do{const n=u().readPage(t,{limit:500,beforeSequence:e});for(let s=n.entries.length-1;s>=0;s-=1){const i=n.entries[s].message;if(!(!b(i)&&!P(i.payload)))return new Date(i.ts).toISOString()}if(!n.hasOlder||n.entries.length===0)break;e=n.entries[0].sequence}while(e!==void 0);return null}function z(){const t=d();let e=!1;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){if(Object.prototype.hasOwnProperty.call(i,"lastVisibleEventAt"))continue;const o=i.indexRevision+1;t[s]={...i,lastVisibleEventAt:B(s)??i.lastMessagePreviewAt??null,indexRevision:o,indexSyncState:"pending",indexSyncStateRevision:o,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:n},e=!0}e&&S(t)}function J(){const t=d();let e=!1;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){if(Object.prototype.hasOwnProperty.call(i,"lastMessagePreviewMessageId")&&Object.prototype.hasOwnProperty.call(i,"lastMessagePreviewAt"))continue;const o=V(s);t[s]={...i,lastMessagePreview:o.preview,lastMessagePreviewMessageId:o.messageId,lastMessagePreviewAt:o.at,indexRevision:i.indexRevision+1,indexSyncState:"pending",indexSyncStateRevision:i.indexRevision+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:n},e=!0}e&&S(t)}function H(t,e){const n={title:t?.title??"",titleSource:t?.titleSource??"first_user_fallback",titleRevision:t?.titleRevision??0,titleLockedByUser:t?.titleLockedByUser??!1,titleOriginEventId:t?.titleOriginEventId??null},s=w(e.title?.trim()??"");if(!s)return n;if(!e.titleSource)throw new Error("titleSource is required with title");if(n.title&&n.titleSource==="first_user_fallback"&&e.titleSource==="first_user_fallback")return n;const i=e.titleSource==="shennian_manual";if(e.titleLockedByUser!==void 0&&e.titleLockedByUser!==i)throw new Error("titleLockedByUser conflicts with titleSource");const o=s===n.title&&e.titleSource===n.titleSource,a=e.titleRevision??n.titleRevision+(o?0:1);if(!Number.isSafeInteger(a)||a<0)throw new Error("invalid titleRevision");const r=y[e.titleSource],l=y[n.titleSource];return r<l||a<n.titleRevision||o&&a===n.titleRevision||a===n.titleRevision&&!o?n:{title:s,titleSource:e.titleSource,titleRevision:a,titleLockedByUser:i,titleOriginEventId:e.titleOriginEventId??n.titleOriginEventId}}function Ie(t,e){const n=e?.limit&&e.limit>0?Math.min(e.limit,500):500;let i=u().readRecent(t,n).messages;return e?.before!==void 0&&(i=i.filter(o=>o.ts<e.before)),[...i].sort((o,a)=>a.ts-o.ts)}function pe(){return u().listSessionIds()}function we(){return u()}function X(t,e){const n=p.dirname(t);c.mkdirSync(n,{recursive:!0,mode:448});const s=`${t}.tmp-${process.pid}-${D.randomBytes(6).toString("hex")}`;let i;try{if(i=c.openSync(s,"wx",384),c.writeFileSync(i,`${JSON.stringify(e,null,2)}
|
|
2
|
-
`,"utf8"),
|
|
1
|
+
import{SESSION_SYNC_DATA_EPOCH as x,SESSION_SYNC_PROTOCOL_VERSION as I,SESSION_TITLE_SOURCE_PRIORITY as y,isInternalSession as O,isToolPayload as P,sessionPreviewFromPayload as h}from"@shennian/wire";import D from"node:crypto";import u from"node:fs";import{renameSyncWithRetry as G}from"../fs/atomic-rename.js";import p from"node:path";import{NativeSourceDeletionStore as L}from"../native-fusion/native-source-deletions.js";import{registerInternalNativeSource as q}from"../native-fusion/source-visibility.js";import{getDaemonInstallationId as g}from"../personal-sync/identity.js";import{PERSONAL_SYNC_V1_ROOT_NAME as j,resolvePersonalSyncV1Path as W}from"../personal-sync/paths.js";import{CanonicalSessionStore as F}from"./canonical-store.js";const _=120;function w(t){if(t.length<=_)return t;let e=t.slice(0,_);const n=e.charCodeAt(e.length-1);return n>=55296&&n<=56319&&(e=e.slice(0,-1)),e}let R=null,k=null;function M(){return W()}function c(){const t=p.join(M(),"canonical");return(!R||k!==t)&&(R=new F(t,g()),k=t),R}function T(){return p.join(M(),"session-index.json")}function d(){const t=T();if(!u.existsSync(t))return{};const e=JSON.parse(u.readFileSync(t,"utf8"));if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`invalid personal session index: ${t}`);const n=g();for(const s of Object.values(e))if(s.daemonInstallationId!==n)throw new Error(`personal session index belongs to another daemon installation: ${t}`);return e}function S(t){K(T(),t)}function b(t){return h(t.payload,120)}function A(t){if(new L({rootDir:M(),daemonInstallationId:g()}).hasSession(t))throw new Error(`session_deleted:${t}`)}function $(t){A(t.sessionId),g();const e=d(),n=e[t.sessionId],s=new Date().toISOString(),i=c().getManifest(t.sessionId)?.bodyRevision??n?.bodyRevision??0,o=c().getManifest(t.sessionId),a=X(n,t),r=t.attentionId?.trim()||null,l=Array.from(new Set([...n?.seenAttentionIds??[],...n?.lastAttentionId?[n.lastAttentionId]:[]])),f=!!(r&&!l.includes(r)),v=t.lastMessagePreview===null?{preview:null,messageId:null,at:null}:t.lastMessagePreview!==void 0&&t.lastMessagePreviewMessageId&&t.lastMessagePreviewAt?{preview:t.lastMessagePreview,messageId:t.lastMessagePreviewMessageId,at:t.lastMessagePreviewAt}:{preview:n?.lastMessagePreview??null,messageId:n?.lastMessagePreviewMessageId??null,at:n?.lastMessagePreviewAt??null},E=Date.parse(t.lastVisibleEventAt??""),C=Date.parse(n?.lastVisibleEventAt??""),U=Number.isFinite(E)&&(!Number.isFinite(C)||E>=C)?t.lastVisibleEventAt:n?.lastVisibleEventAt??null,m={daemonInstallationId:g(),sessionId:t.sessionId,agentType:t.agentType,sessionMode:t.sessionMode??n?.sessionMode,nativeSessionVisibility:O({...n,id:t.sessionId})||O({...n,...t,id:t.sessionId,sessionMode:t.sessionMode??n?.sessionMode})?"internal":"user",managerConfig:t.managerConfig??n?.managerConfig??null,workDir:t.workDir,agentSessionId:t.agentSessionId??n?.agentSessionId??null,modelId:t.modelId??n?.modelId??null,managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType??n?.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:t.managerDefaultWorkerModelId??n?.managerDefaultWorkerModelId??null,status:t.status??n?.status??"active",createdAt:n?.createdAt??s,updatedAt:s,lastActivityAt:t.lastActivityAt??n?.lastActivityAt??s,lastMessagePreview:v.preview,lastMessagePreviewMessageId:v.messageId,lastMessagePreviewAt:v.at,lastVisibleEventAt:U,localReady:n?.localReady===!0||t.localReady===!0,firstUserMessageId:n?.firstUserMessageId??t.firstUserMessageId??null,firstUserBodyRevision:n?.firstUserBodyRevision??t.firstUserBodyRevision??null,bodyRevision:i,indexRevision:(n?.indexRevision??0)+1,...a,firstAvailableSeq:o?.firstAvailableSeq??n?.firstAvailableSeq??null,visibleMessageCount:o?.visibleMessageCount??n?.visibleMessageCount??0,lastVisibleMessageId:o?.lastVisibleMessageId??n?.lastVisibleMessageId??null,attentionCount:(n?.attentionCount??0)+(f?1:0),lastAttentionId:f?r:n?.lastAttentionId??null,seenAttentionIds:f&&r?[...l,r]:l,lastBodyCommittedAt:o?.lastBodyCommittedAt??n?.lastBodyCommittedAt??null,deletionRevision:n?.deletionRevision??0,deletedAt:t.deletedAt??n?.deletedAt??null,syncedIndexRevision:n?.syncedIndexRevision??0,indexSyncState:"pending",indexSyncStateRevision:(n?.indexRevision??0)+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,indexQuarantineCode:null,titleGenerationAttemptedAt:n?.titleGenerationAttemptedAt&&n.titleGenerationNextAttemptAt!==void 0?n.titleGenerationAttemptedAt:null,titleGenerationNextAttemptAt:n?.titleGenerationNextAttemptAt??null,titleGenerationAttempts:n?.titleGenerationAttempts??0};return m.nativeSessionVisibility==="internal"&&m.agentSessionId&&q(m.sessionId,m.agentType,m.agentSessionId),e[t.sessionId]=m,S(e),m}function Q(){return Object.values(d())}function de(t){if(!t)throw new Error("sessionId is required");const e=d();e[t]&&(delete e[t],S(e))}function ce(t){c().purgeSession(t)}function Y(){const t=d();let e=!1;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){const o=w(i.title);if(o===i.title)continue;const a=i.indexRevision+1;t[s]={...i,title:o,indexRevision:a,indexSyncState:"pending",indexSyncStateRevision:a,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,indexQuarantineCode:null,updatedAt:n},e=!0}e&&S(t)}function ue(){const t=g();return H(),J(),Y(),Q().filter(e=>{const n=e.indexSyncStateRevision===e.indexRevision;return e.indexQuarantineCode||n&&(e.indexSyncState==="quarantined"||e.indexSyncState==="terminal")||n&&e.indexSyncNextAttemptAt&&Date.parse(e.indexSyncNextAttemptAt)>Date.now()?!1:e.indexRevision>e.syncedIndexRevision&&e.localReady&&!!e.firstUserMessageId&&e.firstUserBodyRevision!=null}).sort((e,n)=>e.indexRevision-n.indexRevision).map(e=>{const n=!!(e.lastMessagePreview&&e.lastMessagePreviewMessageId&&e.lastMessagePreviewAt);return{protocolVersion:I,dataEpoch:x,daemonInstallationId:t,session:{id:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,nativeSessionVisibility:e.nativeSessionVisibility,managerConfig:e.managerConfig,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null,managerDefaultWorkerAgentType:e.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:e.managerDefaultWorkerModelId??null,title:e.title,titleSource:e.titleSource,titleRevision:e.titleRevision,titleLockedByUser:e.titleLockedByUser,titleOriginEventId:e.titleOriginEventId,status:e.status??"active",workDir:e.workDir,lastMessagePreview:n?e.lastMessagePreview:null,lastMessagePreviewMessageId:n?e.lastMessagePreviewMessageId:null,lastMessagePreviewAt:n?e.lastMessagePreviewAt:null,lastVisibleEventAt:e.lastVisibleEventAt??e.lastMessagePreviewAt??null,bodyStorageMode:"machine_local",localReady:!0,firstUserBoundary:{role:"user",messageId:e.firstUserMessageId,bodyRevision:e.firstUserBodyRevision},bodyRevision:e.bodyRevision,indexRevision:e.indexRevision,firstAvailableSeq:e.firstAvailableSeq,visibleMessageCount:e.visibleMessageCount,lastVisibleMessageId:e.lastVisibleMessageId,attentionCount:e.attentionCount??0,lastAttentionId:e.lastAttentionId??null,lastBodyCommittedAt:e.lastBodyCommittedAt,deletionRevision:e.deletionRevision,lastActivityAt:e.lastActivityAt,createdAt:e.createdAt,updatedAt:e.updatedAt,deletedAt:e.deletedAt}}})}function ge(t,e){const n=d(),s=n[t];if(!(!s||e<=s.syncedIndexRevision)){if(e>s.indexRevision)throw new Error(`cannot acknowledge future index revision ${e} for ${t}`);n[t]={...s,syncedIndexRevision:e,indexSyncState:"applied",indexSyncStateRevision:e,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null},S(n)}}function Se(){const t=d();let e=0;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){if(i.deletedAt||i.indexQuarantineCode||!i.localReady)continue;const o=i.indexRevision+1;t[s]={...i,indexRevision:o,indexSyncState:"pending",indexSyncStateRevision:o,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:n},e+=1}return e>0&&S(t),e}function fe(t){const e=d(),n=e[t.sessionId];if(!n||n.indexRevision!==t.indexRevision)return"terminal";const i=(n.indexSyncStateRevision===t.indexRevision?n.indexSyncAttempts??0:0)+1;let o=t.disposition;o==="retry"&&i>=(t.maxAttempts??8)&&(o="terminal");const a=t.now??Date.now(),r=Math.min(5e3*2**Math.max(0,i-1),360*60*1e3),l=Math.round(r*.2*(Math.random()*2-1));return e[t.sessionId]={...n,indexSyncState:o==="retry"?"pending":o,indexSyncStateRevision:t.indexRevision,indexSyncAttempts:i,indexSyncNextAttemptAt:o==="retry"?new Date(a+r+l).toISOString():null,indexSyncErrorCode:t.code,indexQuarantineCode:o==="quarantined"?t.code:n.indexQuarantineCode??null},S(e),o}const z=2*6e4;function ve(t=Date.now(),e=z){const n=d(),s=[],i=new Date(t).toISOString();for(const o of Object.values(n)){if(o.titleSource!=="first_user_fallback"||o.titleLockedByUser||o.titleGenerationAttemptedAt||!o.title.trim()||o.syncedIndexRevision<o.indexRevision||o.titleGenerationNextAttemptAt&&Date.parse(o.titleGenerationNextAttemptAt)>t)continue;const a=o.status==="completed"||o.status==="failed",r=o.visibleMessageCount>=2;let l=null;if(o.agentType==="claude"&&r?l="agent_native_unavailable":a?l="terminal":r&&t-Date.parse(o.createdAt)>=e&&(l="grace_elapsed"),!l)continue;const f=h(o.title,240);if(!f)continue;const v=D.randomUUID();n[o.sessionId]={...o,titleGenerationAttemptedAt:i,titleGenerationNextAttemptAt:null,titleGenerationAttempts:(o.titleGenerationAttempts??0)+1},s.push({sessionId:o.sessionId,requestId:v,titleSeed:f,baseTitleRevision:o.titleRevision,eligibility:l})}return s.length>0&&S(n),s}function me(t,e=Date.now()){const n=d(),s=n[t];if(!s?.titleGenerationAttemptedAt||s.titleSource!=="first_user_fallback")return null;const i=Math.max(1,s.titleGenerationAttempts??1),o=Math.min(10*6e4,3e4*2**Math.min(i-1,5)),a=new Date(e+o).toISOString();return n[t]={...s,titleGenerationAttemptedAt:null,titleGenerationNextAttemptAt:a},S(n),a}function ye(t,e){const s=d()[t];return!s||s.titleLockedByUser||y[s.titleSource]>=y.shennian_generated||e.titleRevision<=s.titleRevision?!1:($({sessionId:t,agentType:s.agentType,sessionMode:s.sessionMode,managerConfig:s.managerConfig,workDir:s.workDir,agentSessionId:s.agentSessionId,modelId:s.modelId,status:s.status,title:e.title,titleSource:"shennian_generated",titleRevision:e.titleRevision,titleLockedByUser:!1,titleOriginEventId:e.titleOriginEventId}),!0)}function Ae(t,e,n){A(t),g();const s=c().append(t,e,n);return N(t,e,s.bodyRevision),s.bodyRevision}function xe(t,e,n){A(t),g();const s=c().upsert(t,e,n);return N(t,e,s.bodyRevision),s.bodyRevision}function Ie(t,e){const n=c().getMessageState(t,e);return!n||n.tombstoned||!n.message||!n.deliveryState?{protocolVersion:I,dataEpoch:x,daemonInstallationId:g(),state:"not_found",sessionId:t,clientMessageId:e}:{protocolVersion:I,dataEpoch:x,daemonInstallationId:g(),state:n.deliveryState,sessionId:t,clientMessageId:e,messageId:n.message.id,deliveryState:n.deliveryState,bodyRevision:n.lastRevision,committedAt:new Date(n.message.ts).toISOString()}}function pe(t,e){A(t),g();const n=c().tombstone(t,e),s=d(),i=s[t];if(i){const o=e===i.lastMessagePreviewMessageId?V(t):{preview:i.lastMessagePreview??null,messageId:i.lastMessagePreviewMessageId??null,at:i.lastMessagePreviewAt??null};s[t]={...i,bodyRevision:n.bodyRevision,indexRevision:i.indexRevision+1,indexSyncState:"pending",indexSyncStateRevision:i.indexRevision+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:new Date().toISOString(),lastMessagePreview:o.preview,lastMessagePreviewMessageId:o.messageId,lastMessagePreviewAt:o.at,lastVisibleEventAt:B(t)},S(s)}return n.bodyRevision}function N(t,e,n){const s=d(),i=s[t];if(!i)return;const o=b(e),a=o?{lastMessagePreview:o,lastMessagePreviewMessageId:e.id,lastMessagePreviewAt:new Date(e.ts).toISOString()}:null,r=o||P(e.payload)?new Date(e.ts).toISOString():i.lastVisibleEventAt,l=c().getManifest(t),f=e.role==="user"&&o&&!i.title?{title:w(o),titleSource:"first_user_fallback",titleRevision:i.titleRevision+1,titleLockedByUser:!1,titleOriginEventId:e.id}:null,v=e.role==="user"&&!i.localReady?{localReady:!0,firstUserMessageId:e.id,firstUserBodyRevision:n}:null;s[t]={...i,...f??{},...v??{},bodyRevision:n,indexRevision:i.indexRevision+1,indexSyncState:"pending",indexSyncStateRevision:i.indexRevision+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:new Date().toISOString(),lastActivityAt:new Date(e.ts).toISOString(),lastVisibleEventAt:r,...a??{},firstAvailableSeq:l?.firstAvailableSeq??i.firstAvailableSeq,visibleMessageCount:l?.visibleMessageCount??i.visibleMessageCount,lastVisibleMessageId:l?.lastVisibleMessageId??i.lastVisibleMessageId,attentionCount:i.attentionCount??0,lastAttentionId:i.lastAttentionId??null,lastBodyCommittedAt:l?.lastBodyCommittedAt??i.lastBodyCommittedAt},S(s)}function V(t){let e;do{const n=c().readPage(t,{limit:500,beforeSequence:e});for(let s=n.entries.length-1;s>=0;s-=1){const i=n.entries[s],o=b(i.message);if(o)return{preview:o,messageId:i.message.id,at:new Date(i.message.ts).toISOString()}}if(!n.hasOlder||n.entries.length===0)break;e=n.entries[0].sequence}while(e!==void 0);return{preview:null,messageId:null,at:null}}function B(t){let e;do{const n=c().readPage(t,{limit:500,beforeSequence:e});for(let s=n.entries.length-1;s>=0;s-=1){const i=n.entries[s].message;if(!(!b(i)&&!P(i.payload)))return new Date(i.ts).toISOString()}if(!n.hasOlder||n.entries.length===0)break;e=n.entries[0].sequence}while(e!==void 0);return null}function J(){const t=d();let e=!1;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){if(Object.prototype.hasOwnProperty.call(i,"lastVisibleEventAt"))continue;const o=i.indexRevision+1;t[s]={...i,lastVisibleEventAt:B(s)??i.lastMessagePreviewAt??null,indexRevision:o,indexSyncState:"pending",indexSyncStateRevision:o,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:n},e=!0}e&&S(t)}function H(){const t=d();let e=!1;const n=new Date().toISOString();for(const[s,i]of Object.entries(t)){if(Object.prototype.hasOwnProperty.call(i,"lastMessagePreviewMessageId")&&Object.prototype.hasOwnProperty.call(i,"lastMessagePreviewAt"))continue;const o=V(s);t[s]={...i,lastMessagePreview:o.preview,lastMessagePreviewMessageId:o.messageId,lastMessagePreviewAt:o.at,indexRevision:i.indexRevision+1,indexSyncState:"pending",indexSyncStateRevision:i.indexRevision+1,indexSyncAttempts:0,indexSyncNextAttemptAt:null,indexSyncErrorCode:null,updatedAt:n},e=!0}e&&S(t)}function X(t,e){const n={title:t?.title??"",titleSource:t?.titleSource??"first_user_fallback",titleRevision:t?.titleRevision??0,titleLockedByUser:t?.titleLockedByUser??!1,titleOriginEventId:t?.titleOriginEventId??null},s=w(e.title?.trim()??"");if(!s)return n;if(!e.titleSource)throw new Error("titleSource is required with title");if(n.title&&n.titleSource==="first_user_fallback"&&e.titleSource==="first_user_fallback")return n;const i=e.titleSource==="shennian_manual";if(e.titleLockedByUser!==void 0&&e.titleLockedByUser!==i)throw new Error("titleLockedByUser conflicts with titleSource");const o=s===n.title&&e.titleSource===n.titleSource,a=e.titleRevision??n.titleRevision+(o?0:1);if(!Number.isSafeInteger(a)||a<0)throw new Error("invalid titleRevision");const r=y[e.titleSource],l=y[n.titleSource];return r<l||a<n.titleRevision||o&&a===n.titleRevision||a===n.titleRevision&&!o?n:{title:s,titleSource:e.titleSource,titleRevision:a,titleLockedByUser:i,titleOriginEventId:e.titleOriginEventId??n.titleOriginEventId}}function we(t,e){const n=e?.limit&&e.limit>0?Math.min(e.limit,500):500;let i=c().readRecent(t,n).messages;return e?.before!==void 0&&(i=i.filter(o=>o.ts<e.before)),[...i].sort((o,a)=>a.ts-o.ts)}function Re(){return c().listSessionIds()}function Me(){return c()}function K(t,e){const n=p.dirname(t);u.mkdirSync(n,{recursive:!0,mode:448});const s=`${t}.tmp-${process.pid}-${D.randomBytes(6).toString("hex")}`;let i;try{if(i=u.openSync(s,"wx",384),u.writeFileSync(i,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf8"),u.fsyncSync(i),u.closeSync(i),i=void 0,G(s,t),process.platform!=="win32"){const o=u.openSync(n,"r");try{u.fsyncSync(o)}finally{u.closeSync(o)}}}finally{i!==void 0&&u.closeSync(i);try{u.unlinkSync(s)}catch{}}}export{j as PERSONAL_SYNC_V1_ROOT_NAME,ge as acknowledgeSessionIndexUpdate,Ae as appendMessage,ye as applyGeneratedSessionTitle,ve as claimSessionTitleGenerationCandidates,me as deferSessionTitleGeneration,Me as getCanonicalSessionStore,g as getDaemonInstallationId,Ie as getMessageDeliveryStatus,ue as listPendingSessionIndexUpdates,Q as listSessionRecords,Re as listSessions,Se as markAllSessionIndexesForRepublish,ce as purgeCanonicalSession,de as purgeSessionRecord,we as readMessages,$ as recordSession,fe as recordSessionIndexRejection,pe as tombstoneMessage,xe as upsertMessage};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import f from"node:crypto";import n from"node:fs";import s from"node:path";import{resolvePersonalSyncV1Path as
|
|
2
|
-
`,"utf8"),n.fsyncSync(e),n.closeSync(e),e=void 0,
|
|
1
|
+
import f from"node:crypto";import n from"node:fs";import{renameSyncWithRetry as m}from"../fs/atomic-rename.js";import s from"node:path";import{resolvePersonalSyncV1Path as y}from"../personal-sync/paths.js";const a=200,S=25*1024*1024;function j(t){const r=c(t.sessionId);n.mkdirSync(r,{recursive:!0,mode:448}),d(s.join(r,`${l(t.toolCallId)}.json`),{schemaVersion:1,...t}),p(r)}function w(t,r){const o=s.join(c(t),`${l(r)}.json`);if(!n.existsSync(o))return null;try{const e=JSON.parse(n.readFileSync(o,"utf8"));return e.schemaVersion===1&&e.sessionId===t&&e.toolCallId===r?e:null}catch{return null}}function D(t){if(!t)throw new Error("sessionId is required");n.rmSync(c(t),{recursive:!0,force:!0})}function c(t){return y("tool-details",l(t))}function l(t){return f.createHash("sha256").update(t).digest("hex")}function d(t,r){const o=`${t}.tmp-${process.pid}-${f.randomBytes(6).toString("hex")}`;let e;try{e=n.openSync(o,"wx",384),n.writeFileSync(e,`${JSON.stringify(r)}
|
|
2
|
+
`,"utf8"),n.fsyncSync(e),n.closeSync(e),e=void 0,m(o,t)}finally{e!==void 0&&n.closeSync(e);try{n.unlinkSync(o)}catch{}}}function p(t){const r=n.readdirSync(t).filter(e=>e.endsWith(".json")).map(e=>{const i=s.join(t,e),u=n.statSync(i);return{file:i,bytes:u.size,mtimeMs:u.mtimeMs}}).sort((e,i)=>e.mtimeMs-i.mtimeMs);let o=r.reduce((e,i)=>e+i.bytes,0);for(;r.length>a||o>S;){const e=r.shift();if(!e)return;n.unlinkSync(e.file),o-=e.bytes}}export{D as purgeToolDetails,w as readToolDetail,j as writeToolDetail};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
|