@xopcai/xopc 0.0.95 → 0.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/{agents-CKe2LMnz.js → agents-B_YUvNi6.js} +2 -2
- package/dist/gateway/static/root/assets/{apps-page-Mi9mMIZ1.js → apps-page-BmwG5aur.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-BrdyC101.js → channels-settings-BiwkeKPb.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-D55Bu0nn.js → channels-status-swr-ChyN473C.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-CPpx2l-E.js → cron-api-CvSifIfJ.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-Bx2jB0YN.js → cron-page-BDqTDFy6.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-D_AiG_Kg.js → dist-DxsUrjpy.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-6ieHsxRE.js → extension-debug-page-DV_Av5Jq.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-B8nywHRO.js → extension-page-CwZwRhWw.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DrskdEIV.js → extension-settings-page-Bb7TR1Se.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-B0aeeY0q.js → fetch-BLLOP2CM.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives--9ooY8Xl.js → field-primitives-CyqVu1QR.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DUZ_W1w-.js → heartbeat-config-api-Cd4M1eHt.js} +1 -1
- package/dist/gateway/static/root/assets/{index-Dj9FuxCm.js → index-0tS9lV85.js} +74 -74
- package/dist/gateway/static/root/assets/index-BJDmBCSl.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-CaXqhpKf.js → logs-page-BsAOSowN.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-page-B91pLkEI.css → note-detail-page-D4ZIVQbk.css} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-page-DYzym2B0.js → note-detail-page-Dlxoy6Ap.js} +54 -53
- package/dist/gateway/static/root/assets/{note-time-B-vSi2dR.js → note-time-B-r8yTpQ.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-BkhWdGiT.js → notes-page-CHFcyqYW.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-53YFokoe.js → sessions-page-Ctu0kgt7.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-advanced-gate-BaZmaklx.js → settings-advanced-gate-Dh0TyOOg.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DIJPKpTR.js → settings-form-section-DXMCEW1d.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Dvb230FF.js → settings-page-CIkZ7233.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CRyjTAG6.js → share-preview-page-7RV65xhJ.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-C5ZJbfAe.js → skills-page-D_Az1SlU.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-Cg_SuBw0.js → theme-store-e2q2yjs4.js} +1 -1
- package/dist/gateway/static/root/assets/url-DpFBIyN9.js +3 -0
- package/dist/gateway/static/root/assets/{utils-lMYoWhqo.js → utils-OA_b1q0Q.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-Dda2pcUU.js → voice-api-key-field-SJml1hAt.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-page.utils-KIladUrU.js → workflow-page.utils-D90VVCzC.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-BTis4Z7Y.js → workflows-page-y7Btji0J.js} +1 -1
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +12 -8
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.d.ts +0 -1
- package/dist/src/agent/agent-scope.js +2 -5
- package/dist/src/agent/agent-scope.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +2 -0
- package/dist/src/agent/bootstrap/bootstrap-cache.js +10 -1
- package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-files.d.ts +2 -1
- package/dist/src/agent/bootstrap/bootstrap-files.js +34 -12
- package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +1 -2
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +6 -12
- package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/types.d.ts +5 -5
- package/dist/src/agent/context/workspace-seed.js +6 -6
- package/dist/src/agent/context/workspace-seed.js.map +1 -1
- package/dist/src/agent/context/workspace-state.d.ts +20 -0
- package/dist/src/agent/context/workspace-state.js +57 -0
- package/dist/src/agent/context/workspace-state.js.map +1 -0
- package/dist/src/agent/context/workspace-templates/AGENTS.md +0 -4
- package/dist/src/agent/embedded/index.d.ts +2 -2
- package/dist/src/agent/embedded/index.js +3 -3
- package/dist/src/agent/embedded/run-turn.js +0 -3
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-manager-init.d.ts +0 -17
- package/dist/src/agent/embedded/session-manager-init.js +1 -36
- package/dist/src/agent/embedded/session-manager-init.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.d.ts +3 -12
- package/dist/src/agent/embedded/session-runner.js +12 -26
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +2 -4
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/embedded/sqlite-hydrating-session-manager.d.ts +10 -0
- package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js +34 -0
- package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js.map +1 -0
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +8 -15
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/memory/index.d.ts +1 -0
- package/dist/src/agent/prompt/memory/index.js +34 -80
- package/dist/src/agent/prompt/memory/index.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/prompt/system-prompt.js +0 -1
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service/process-direct-one-shot.js +8 -17
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +14 -23
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.js +7 -11
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +3 -3
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/index.d.ts +0 -1
- package/dist/src/agent/tools/index.js +1 -2
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/session-search-tool.d.ts +0 -1
- package/dist/src/agent/tools/session-search-tool.js +11 -6
- package/dist/src/agent/tools/session-search-tool.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/tool-paths.js +1 -3
- package/dist/src/agent/tools/tool-paths.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/agent-edit.js +3 -4
- package/dist/src/chat-commands/agent-edit.js.map +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +32 -95
- package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +5 -7
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +0 -8
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/templates.d.ts +3 -10
- package/dist/src/cli/templates.js +4 -32
- package/dist/src/cli/templates.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/commands/agents.config.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +7 -8
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.d.ts +3 -0
- package/dist/src/config/paths-state.js +7 -3
- package/dist/src/config/paths-state.js.map +1 -1
- package/dist/src/config/paths.d.ts +5 -36
- package/dist/src/config/paths.js +7 -52
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +15 -0
- package/dist/src/config/schema.js +11 -0
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/execution-types.d.ts +42 -0
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.d.ts +4 -8
- package/dist/src/cron/run-log-store.js +26 -78
- package/dist/src/cron/run-log-store.js.map +1 -1
- package/dist/src/cron/service.d.ts +3 -3
- package/dist/src/cron/service.js +2 -2
- package/dist/src/cron/service.js.map +1 -1
- package/dist/src/cron/types.d.ts +1 -42
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.js +4 -4
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.d.ts +0 -1
- package/dist/src/gateway/file-path-classifier.js +2 -8
- package/dist/src/gateway/file-path-classifier.js.map +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +2 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service.js +5 -1
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/session-reset-service.d.ts +1 -1
- package/dist/src/gateway/session-reset-service.js +1 -1
- package/dist/src/gateway/session-reset-service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/node-sqlite.d.ts +1 -0
- package/dist/src/infra/node-sqlite.js +17 -0
- package/dist/src/infra/node-sqlite.js.map +1 -0
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/sqlite-errors.d.ts +1 -0
- package/dist/src/infra/sqlite-errors.js +77 -0
- package/dist/src/infra/sqlite-errors.js.map +1 -0
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/unhandled-rejections.d.ts +1 -0
- package/dist/src/infra/unhandled-rejections.js +25 -0
- package/dist/src/infra/unhandled-rejections.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/warning-filter.d.ts +7 -0
- package/dist/src/infra/warning-filter.js +59 -0
- package/dist/src/infra/warning-filter.js.map +1 -0
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/notes/store.d.ts +3 -9
- package/dist/src/notes/store.js +22 -196
- package/dist/src/notes/store.js.map +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.d.ts +6 -75
- package/dist/src/session/config-store.js +38 -144
- package/dist/src/session/config-store.js.map +1 -1
- package/dist/src/session/config-types.d.ts +15 -0
- package/dist/src/session/config-types.js +1 -0
- package/dist/src/session/index.d.ts +1 -3
- package/dist/src/session/index.js +3 -5
- package/dist/src/session/init-session-turn.d.ts +0 -6
- package/dist/src/session/init-session-turn.js +18 -18
- package/dist/src/session/init-session-turn.js.map +1 -1
- package/dist/src/session/lifecycle-timestamps.d.ts +5 -2
- package/dist/src/session/lifecycle-timestamps.js.map +1 -1
- package/dist/src/session/{parity/load-jsonl-entries.js → load-jsonl-entries.js} +1 -1
- package/dist/src/session/load-jsonl-entries.js.map +1 -0
- package/dist/src/session/manager.d.ts +5 -3
- package/dist/src/session/manager.js +1 -5
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/resolve-session.d.ts +3 -6
- package/dist/src/session/resolve-session.js +26 -31
- package/dist/src/session/resolve-session.js.map +1 -1
- package/dist/src/session/session-context-for-llm.js +5 -1
- package/dist/src/session/session-context-for-llm.js.map +1 -1
- package/dist/src/session/session-id.js +12 -0
- package/dist/src/session/session-id.js.map +1 -0
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/session-workspace.d.ts +1 -1
- package/dist/src/session/session-workspace.js.map +1 -1
- package/dist/src/session/store.d.ts +14 -63
- package/dist/src/session/store.js +172 -847
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/stored-rows-to-file-entries.d.ts +11 -0
- package/dist/src/session/stored-rows-to-file-entries.js +95 -0
- package/dist/src/session/stored-rows-to-file-entries.js.map +1 -0
- package/dist/src/session/transcript-events.d.ts +1 -2
- package/dist/src/session/transcript-events.js +5 -12
- package/dist/src/session/transcript-events.js.map +1 -1
- package/dist/src/session/transcript-format.d.ts +1 -1
- package/dist/src/session/transcript-format.js.map +1 -1
- package/dist/src/session/transcript-stats.d.ts +1 -0
- package/dist/src/session/transcript-stats.js +10 -0
- package/dist/src/session/transcript-stats.js.map +1 -0
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/storage/sqlite/config-repository.d.ts +6 -0
- package/dist/src/storage/sqlite/config-repository.js +56 -0
- package/dist/src/storage/sqlite/config-repository.js.map +1 -0
- package/dist/src/storage/sqlite/connection.d.ts +38 -0
- package/dist/src/storage/sqlite/connection.js +258 -0
- package/dist/src/storage/sqlite/connection.js.map +1 -0
- package/dist/src/storage/sqlite/cron-run-repository.d.ts +5 -0
- package/dist/src/storage/sqlite/cron-run-repository.js +97 -0
- package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -0
- package/dist/src/storage/sqlite/fts.d.ts +2 -0
- package/dist/src/storage/sqlite/fts.js +11 -0
- package/dist/src/storage/sqlite/fts.js.map +1 -0
- package/dist/src/storage/sqlite/index.d.ts +12 -0
- package/dist/src/storage/sqlite/index.js +13 -0
- package/dist/src/storage/sqlite/memory-index-repository.d.ts +18 -0
- package/dist/src/storage/sqlite/memory-index-repository.js +132 -0
- package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -0
- package/dist/src/storage/sqlite/notes-repository.d.ts +11 -0
- package/dist/src/storage/sqlite/notes-repository.js +191 -0
- package/dist/src/storage/sqlite/notes-repository.js.map +1 -0
- package/dist/src/storage/sqlite/paths.d.ts +1 -0
- package/dist/src/storage/sqlite/paths.js +7 -0
- package/dist/src/storage/sqlite/paths.js.map +1 -0
- package/dist/src/storage/sqlite/row-mappers.d.ts +82 -0
- package/dist/src/storage/sqlite/row-mappers.js +164 -0
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -0
- package/dist/src/storage/sqlite/schema.d.ts +5 -0
- package/dist/src/storage/sqlite/schema.js +43 -0
- package/dist/src/storage/sqlite/schema.js.map +1 -0
- package/dist/src/storage/sqlite/schema.sql +195 -0
- package/dist/src/storage/sqlite/session-metadata.d.ts +8 -0
- package/dist/src/storage/sqlite/session-metadata.js +83 -0
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -0
- package/dist/src/storage/sqlite/session-repository.d.ts +29 -0
- package/dist/src/storage/sqlite/session-repository.js +268 -0
- package/dist/src/storage/sqlite/session-repository.js.map +1 -0
- package/dist/src/storage/sqlite/transaction.d.ts +11 -0
- package/dist/src/storage/sqlite/transaction.js +115 -0
- package/dist/src/storage/sqlite/transaction.js.map +1 -0
- package/dist/src/storage/sqlite/transcript-repository.d.ts +34 -0
- package/dist/src/storage/sqlite/transcript-repository.js +241 -0
- package/dist/src/storage/sqlite/transcript-repository.js.map +1 -0
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/service/workflow-session-bridge.js +41 -64
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +0 -1
- package/dist/gateway/static/root/assets/url-BHHmdJYc.js +0 -3
- package/dist/src/agent/context/workspace-templates/BOOTSTRAP.md +0 -61
- package/dist/src/agent/embedded/session-manager-cache.d.ts +0 -19
- package/dist/src/agent/embedded/session-manager-cache.js +0 -48
- package/dist/src/agent/embedded/session-manager-cache.js.map +0 -1
- package/dist/src/session/parity/artifacts.d.ts +0 -16
- package/dist/src/session/parity/artifacts.js +0 -80
- package/dist/src/session/parity/artifacts.js.map +0 -1
- package/dist/src/session/parity/jsonl-transcript-io.d.ts +0 -54
- package/dist/src/session/parity/jsonl-transcript-io.js +0 -236
- package/dist/src/session/parity/jsonl-transcript-io.js.map +0 -1
- package/dist/src/session/parity/load-jsonl-entries.js.map +0 -1
- package/dist/src/session/parity/session-id.js +0 -18
- package/dist/src/session/parity/session-id.js.map +0 -1
- package/dist/src/session/parity/sessions-json-cache.d.ts +0 -14
- package/dist/src/session/parity/sessions-json-cache.js +0 -98
- package/dist/src/session/parity/sessions-json-cache.js.map +0 -1
- package/dist/src/session/parity/sessions-json-file-read.d.ts +0 -6
- package/dist/src/session/parity/sessions-json-file-read.js +0 -19
- package/dist/src/session/parity/sessions-json-file-read.js.map +0 -1
- package/dist/src/session/parity/sessions-json-file.d.ts +0 -11
- package/dist/src/session/parity/sessions-json-file.js +0 -52
- package/dist/src/session/parity/sessions-json-file.js.map +0 -1
- package/dist/src/session/parity/sessions-json-patch.d.ts +0 -14
- package/dist/src/session/parity/sessions-json-patch.js +0 -40
- package/dist/src/session/parity/sessions-json-patch.js.map +0 -1
- package/dist/src/session/parity/transcript-file-lock.d.ts +0 -22
- package/dist/src/session/parity/transcript-file-lock.js +0 -142
- package/dist/src/session/parity/transcript-file-lock.js.map +0 -1
- package/dist/src/session/parity/transcript-pagination.d.ts +0 -29
- package/dist/src/session/parity/transcript-pagination.js +0 -132
- package/dist/src/session/parity/transcript-pagination.js.map +0 -1
- package/dist/src/session/parity/transcript-paths.d.ts +0 -13
- package/dist/src/session/parity/transcript-paths.js +0 -64
- package/dist/src/session/parity/transcript-paths.js.map +0 -1
- package/dist/src/session/parity/xopc-session-disk-entry.d.ts +0 -22
- package/dist/src/session/search-index-cache.d.ts +0 -6
- package/dist/src/session/search-index-cache.js +0 -44
- package/dist/src/session/search-index-cache.js.map +0 -1
- package/dist/src/session/search-index.d.ts +0 -20
- package/dist/src/session/search-index.js +0 -124
- package/dist/src/session/search-index.js.map +0 -1
- /package/dist/src/{session/parity/xopc-session-disk-entry.js → cron/execution-types.js} +0 -0
- /package/dist/src/session/{parity/load-jsonl-entries.d.ts → load-jsonl-entries.d.ts} +0 -0
- /package/dist/src/session/{parity/session-id.d.ts → session-id.d.ts} +0 -0
|
@@ -1,180 +1,74 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import { mkdir, readFile } from "fs/promises";
|
|
3
|
+
import { requireXopcDatabase } from "../storage/sqlite/connection.js";
|
|
4
|
+
import { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
5
|
+
import "../storage/sqlite/index.js";
|
|
7
6
|
//#region src/session/config-store.ts
|
|
8
|
-
/**
|
|
9
|
-
* Session Config Store
|
|
10
|
-
*
|
|
11
|
-
* Manages session-level configuration persistence.
|
|
12
|
-
* Stores thinking level, reasoning visibility, verbose mode, and other
|
|
13
|
-
* session-specific settings that can be overridden via commands.
|
|
14
|
-
*/
|
|
15
|
-
init_write_file_atomic();
|
|
16
7
|
init_logger();
|
|
17
8
|
const log = createLogger("SessionConfigStore");
|
|
18
|
-
/**
|
|
19
|
-
* Session config store manager.
|
|
20
|
-
* Each session can have its own configuration that overrides agent defaults.
|
|
21
|
-
*/
|
|
22
9
|
var SessionConfigStore = class {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
this.configDir = join(agentHomeDir, "sessions", "config");
|
|
10
|
+
cwd;
|
|
11
|
+
constructor(_agentHomeDir, cwd = process.cwd()) {
|
|
12
|
+
this.cwd = cwd;
|
|
27
13
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*/
|
|
31
|
-
async initialize() {
|
|
32
|
-
await mkdir(this.configDir, { recursive: true });
|
|
33
|
-
log.debug("Session config store initialized");
|
|
14
|
+
requireDatabase() {
|
|
15
|
+
requireXopcDatabase();
|
|
34
16
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
getConfigPath(sessionKey) {
|
|
39
|
-
const safeKey = sessionKey.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
40
|
-
return join(this.configDir, `${safeKey}.json`);
|
|
17
|
+
async initialize() {
|
|
18
|
+
this.requireDatabase();
|
|
19
|
+
log.debug("Session config store initialized (SQLite)");
|
|
41
20
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Get config for a session
|
|
44
|
-
*/
|
|
45
21
|
async get(sessionKey) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const content = await readFile(configPath, "utf-8");
|
|
50
|
-
return JSON.parse(content);
|
|
51
|
-
} catch (error) {
|
|
52
|
-
const em = error instanceof Error ? error.message : String(error);
|
|
53
|
-
log.error({
|
|
54
|
-
err: error,
|
|
55
|
-
errorMessage: em,
|
|
56
|
-
sessionKey,
|
|
57
|
-
phase: "session.config"
|
|
58
|
-
}, `Failed to read session config: ${em}`);
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
22
|
+
this.requireDatabase();
|
|
23
|
+
return getSessionConfig(sessionKey);
|
|
61
24
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Set config for a session (full replacement)
|
|
64
|
-
*/
|
|
65
25
|
async set(sessionKey, config) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
updatedAt: Date.now()
|
|
70
|
-
};
|
|
71
|
-
try {
|
|
72
|
-
await writeTextAtomic(configPath, JSON.stringify(configWithTimestamp, null, 2));
|
|
73
|
-
log.debug({ sessionKey }, "Session config saved");
|
|
74
|
-
} catch (error) {
|
|
75
|
-
const em = error instanceof Error ? error.message : String(error);
|
|
76
|
-
log.error({
|
|
77
|
-
err: error,
|
|
78
|
-
errorMessage: em,
|
|
79
|
-
sessionKey,
|
|
80
|
-
phase: "session.config"
|
|
81
|
-
}, `Failed to save session config: ${em}`);
|
|
82
|
-
throw error;
|
|
83
|
-
}
|
|
26
|
+
this.requireDatabase();
|
|
27
|
+
setSessionConfig(sessionKey, config, this.cwd);
|
|
28
|
+
log.debug({ sessionKey }, "Session config saved");
|
|
84
29
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Update config for a session (partial update)
|
|
87
|
-
*/
|
|
88
30
|
async update(sessionKey, partial) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
updatedAt: Date.now()
|
|
93
|
-
};
|
|
94
|
-
await this.set(sessionKey, updated);
|
|
31
|
+
this.requireDatabase();
|
|
32
|
+
const updated = updateSessionConfig(sessionKey, partial, this.cwd);
|
|
33
|
+
log.debug({ sessionKey }, "Session config updated");
|
|
95
34
|
return updated;
|
|
96
35
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Delete config for a session
|
|
99
|
-
*/
|
|
100
36
|
async delete(sessionKey) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
await unlink(configPath);
|
|
105
|
-
log.debug({ sessionKey }, "Session config deleted");
|
|
106
|
-
} catch (error) {
|
|
107
|
-
log.error({
|
|
108
|
-
sessionKey,
|
|
109
|
-
error
|
|
110
|
-
}, "Failed to delete session config");
|
|
111
|
-
throw error;
|
|
112
|
-
}
|
|
37
|
+
this.requireDatabase();
|
|
38
|
+
deleteSessionConfig(sessionKey);
|
|
39
|
+
log.debug({ sessionKey }, "Session config deleted");
|
|
113
40
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Check if config exists for a session
|
|
116
|
-
*/
|
|
117
41
|
async has(sessionKey) {
|
|
118
|
-
|
|
42
|
+
this.requireDatabase();
|
|
43
|
+
return hasSessionConfig(sessionKey);
|
|
119
44
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Get all session configs
|
|
122
|
-
*/
|
|
123
45
|
async getAll() {
|
|
124
|
-
|
|
46
|
+
this.requireDatabase();
|
|
125
47
|
const configs = /* @__PURE__ */ new Map();
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const config = await this.get(sessionKey);
|
|
132
|
-
if (config) configs.set(sessionKey, config);
|
|
133
|
-
}
|
|
134
|
-
} catch (error) {
|
|
135
|
-
log.error({ error }, "Failed to list session configs");
|
|
48
|
+
const { listSessionMetadata } = await import("../storage/sqlite/index.js");
|
|
49
|
+
const { items } = listSessionMetadata({ limit: 1e5 });
|
|
50
|
+
for (const item of items) {
|
|
51
|
+
const config = getSessionConfig(item.key);
|
|
52
|
+
if (config) configs.set(item.key, config);
|
|
136
53
|
}
|
|
137
54
|
return configs;
|
|
138
55
|
}
|
|
139
|
-
/**
|
|
140
|
-
* Clear all session configs
|
|
141
|
-
*/
|
|
142
56
|
async clear() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
} catch (error) {
|
|
149
|
-
log.error({ error }, "Failed to clear session configs");
|
|
150
|
-
throw error;
|
|
151
|
-
}
|
|
57
|
+
this.requireDatabase();
|
|
58
|
+
const { listSessionMetadata } = await import("../storage/sqlite/index.js");
|
|
59
|
+
const { items } = listSessionMetadata({ limit: 1e5 });
|
|
60
|
+
for (const item of items) deleteSessionConfig(item.key);
|
|
61
|
+
log.debug("All session configs cleared");
|
|
152
62
|
}
|
|
153
63
|
};
|
|
154
|
-
/**
|
|
155
|
-
* Resolve thinking level for a session.
|
|
156
|
-
* Returns session config if set, otherwise falls back to agent defaults.
|
|
157
|
-
*/
|
|
158
64
|
async function resolveThinkingLevel(sessionConfigStore, sessionKey, agentDefault) {
|
|
159
|
-
|
|
160
|
-
if (config?.thinkingLevel) return config.thinkingLevel;
|
|
161
|
-
return agentDefault;
|
|
65
|
+
return (await sessionConfigStore.get(sessionKey))?.thinkingLevel ?? agentDefault;
|
|
162
66
|
}
|
|
163
|
-
/**
|
|
164
|
-
* Resolve reasoning level for a session.
|
|
165
|
-
*/
|
|
166
67
|
async function resolveReasoningLevel(sessionConfigStore, sessionKey, agentDefault) {
|
|
167
|
-
|
|
168
|
-
if (config?.reasoningLevel) return config.reasoningLevel;
|
|
169
|
-
return agentDefault;
|
|
68
|
+
return (await sessionConfigStore.get(sessionKey))?.reasoningLevel ?? agentDefault;
|
|
170
69
|
}
|
|
171
|
-
/**
|
|
172
|
-
* Resolve verbose level for a session.
|
|
173
|
-
*/
|
|
174
70
|
async function resolveVerboseLevel(sessionConfigStore, sessionKey, agentDefault) {
|
|
175
|
-
|
|
176
|
-
if (config?.verboseLevel) return config.verboseLevel;
|
|
177
|
-
return agentDefault;
|
|
71
|
+
return (await sessionConfigStore.get(sessionKey))?.verboseLevel ?? agentDefault;
|
|
178
72
|
}
|
|
179
73
|
//#endregion
|
|
180
74
|
export { SessionConfigStore, resolveReasoningLevel, resolveThinkingLevel, resolveVerboseLevel };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-store.js","names":[],"sources":["../../../src/session/config-store.ts"],"sourcesContent":["/**\n * Session Config Store\n * \n * Manages session-level configuration persistence.\n * Stores thinking level, reasoning visibility, verbose mode, and other\n * session-specific settings that can be overridden via commands.\n */\n\nimport { readFile, mkdir } from 'fs/promises';\nimport { writeTextAtomic } from '../infra/write-file-atomic.js';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport { createLogger } from '../utils/logger.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel, ElevatedMode } from '../agent/transcript/thinking-types.js';\n\nconst log = createLogger('SessionConfigStore');\n\n/**\n * Session-level agent configuration.\n * These settings override agent defaults for a specific session.\n */\nexport interface SessionAgentConfig {\n /** Thinking level for this session */\n thinkingLevel?: ThinkLevel;\n /** Reasoning visibility for this session */\n reasoningLevel?: ReasoningLevel;\n /** Verbose level for this session */\n verboseLevel?: VerboseLevel;\n /** Elevated mode for this session */\n elevatedMode?: ElevatedMode;\n /** Model override for this session */\n modelOverride?: string;\n /** Provider override for this session */\n providerOverride?: string;\n /** Absolute markdown workspace root for this session (set once; immutable after save). */\n workingDirectoryOverride?: string;\n /** Last updated timestamp */\n updatedAt?: number;\n}\n\n/**\n * Session config store manager.\n * Each session can have its own configuration that overrides agent defaults.\n */\nexport class SessionConfigStore {\n private configDir: string;\n\n /** @param agentHomeDir — `resolveAgentHomeDir(…)` (parent of `sessions/` transcript store) */\n constructor(agentHomeDir: string) {\n this.configDir = join(agentHomeDir, 'sessions', 'config');\n }\n\n /**\n * Initialize the config store\n */\n async initialize(): Promise<void> {\n await mkdir(this.configDir, { recursive: true });\n log.debug('Session config store initialized');\n }\n\n /**\n * Get the config file path for a session\n */\n private getConfigPath(sessionKey: string): string {\n // Sanitize session key to be a valid filename\n const safeKey = sessionKey.replace(/[^a-zA-Z0-9_-]/g, '_');\n return join(this.configDir, `${safeKey}.json`);\n }\n\n /**\n * Get config for a session\n */\n async get(sessionKey: string): Promise<SessionAgentConfig | null> {\n const configPath = this.getConfigPath(sessionKey);\n \n if (!existsSync(configPath)) {\n return null;\n }\n\n try {\n const content = await readFile(configPath, 'utf-8');\n const config = JSON.parse(content) as SessionAgentConfig;\n return config;\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.error({ err: error, errorMessage: em, sessionKey, phase: 'session.config' }, `Failed to read session config: ${em}`);\n return null;\n }\n }\n\n /**\n * Set config for a session (full replacement)\n */\n async set(sessionKey: string, config: SessionAgentConfig): Promise<void> {\n const configPath = this.getConfigPath(sessionKey);\n const configWithTimestamp = {\n ...config,\n updatedAt: Date.now(),\n };\n\n try {\n await writeTextAtomic(configPath, JSON.stringify(configWithTimestamp, null, 2));\n log.debug({ sessionKey }, 'Session config saved');\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.error({ err: error, errorMessage: em, sessionKey, phase: 'session.config' }, `Failed to save session config: ${em}`);\n throw error;\n }\n }\n\n /**\n * Update config for a session (partial update)\n */\n async update(sessionKey: string, partial: Partial<SessionAgentConfig>): Promise<SessionAgentConfig> {\n const existing = await this.get(sessionKey);\n const updated = {\n ...existing,\n ...partial,\n updatedAt: Date.now(),\n };\n \n await this.set(sessionKey, updated);\n return updated;\n }\n\n /**\n * Delete config for a session\n */\n async delete(sessionKey: string): Promise<void> {\n const configPath = this.getConfigPath(sessionKey);\n \n if (existsSync(configPath)) {\n try {\n const { unlink } = await import('fs/promises');\n await unlink(configPath);\n log.debug({ sessionKey }, 'Session config deleted');\n } catch (error) {\n log.error({ sessionKey, error }, 'Failed to delete session config');\n throw error;\n }\n }\n }\n\n /**\n * Check if config exists for a session\n */\n async has(sessionKey: string): Promise<boolean> {\n const configPath = this.getConfigPath(sessionKey);\n return existsSync(configPath);\n }\n\n /**\n * Get all session configs\n */\n async getAll(): Promise<Map<string, SessionAgentConfig>> {\n const { readdir } = await import('fs/promises');\n const configs = new Map<string, SessionAgentConfig>();\n\n try {\n const files = await readdir(this.configDir);\n \n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n \n const sessionKey = file.replace('.json', '').replace(/_/g, '-');\n const config = await this.get(sessionKey);\n \n if (config) {\n configs.set(sessionKey, config);\n }\n }\n } catch (error) {\n log.error({ error }, 'Failed to list session configs');\n }\n\n return configs;\n }\n\n /**\n * Clear all session configs\n */\n async clear(): Promise<void> {\n const { readdir, rm } = await import('fs/promises');\n \n try {\n const files = await readdir(this.configDir);\n \n for (const file of files) {\n if (file.endsWith('.json')) {\n await rm(join(this.configDir, file), { force: true });\n }\n }\n \n log.debug('All session configs cleared');\n } catch (error) {\n log.error({ error }, 'Failed to clear session configs');\n throw error;\n }\n }\n}\n\n// ========== Helper Functions ==========\n\n/**\n * Resolve thinking level for a session.\n * Returns session config if set, otherwise falls back to agent defaults.\n */\nexport async function resolveThinkingLevel(\n sessionConfigStore: SessionConfigStore,\n sessionKey: string,\n agentDefault?: ThinkLevel\n): Promise<ThinkLevel | undefined> {\n const config = await sessionConfigStore.get(sessionKey);\n \n if (config?.thinkingLevel) {\n return config.thinkingLevel;\n }\n \n return agentDefault;\n}\n\n/**\n * Resolve reasoning level for a session.\n */\nexport async function resolveReasoningLevel(\n sessionConfigStore: SessionConfigStore,\n sessionKey: string,\n agentDefault?: ReasoningLevel\n): Promise<ReasoningLevel | undefined> {\n const config = await sessionConfigStore.get(sessionKey);\n \n if (config?.reasoningLevel) {\n return config.reasoningLevel;\n }\n \n return agentDefault;\n}\n\n/**\n * Resolve verbose level for a session.\n */\nexport async function resolveVerboseLevel(\n sessionConfigStore: SessionConfigStore,\n sessionKey: string,\n agentDefault?: VerboseLevel\n): Promise<VerboseLevel | undefined> {\n const config = await sessionConfigStore.get(sessionKey);\n \n if (config?.verboseLevel) {\n return config.verboseLevel;\n }\n \n return agentDefault;\n}\n"],"mappings":";;;;;;;;;;;;;;wBASgE;aAGd;AAGlD,MAAM,MAAM,aAAa,qBAAqB;;;;;AA6B9C,IAAa,qBAAb,MAAgC;CAC9B;;CAGA,YAAY,cAAsB;AAChC,OAAK,YAAY,KAAK,cAAc,YAAY,SAAS;;;;;CAM3D,MAAM,aAA4B;AAChC,QAAM,MAAM,KAAK,WAAW,EAAE,WAAW,MAAM,CAAC;AAChD,MAAI,MAAM,mCAAmC;;;;;CAM/C,cAAsB,YAA4B;EAEhD,MAAM,UAAU,WAAW,QAAQ,mBAAmB,IAAI;AAC1D,SAAO,KAAK,KAAK,WAAW,GAAG,QAAQ,OAAO;;;;;CAMhD,MAAM,IAAI,YAAwD;EAChE,MAAM,aAAa,KAAK,cAAc,WAAW;AAEjD,MAAI,CAAC,WAAW,WAAW,CACzB,QAAO;AAGT,MAAI;GACF,MAAM,UAAU,MAAM,SAAS,YAAY,QAAQ;AAEnD,UADe,KAAK,MAAM,QACb;WACN,OAAO;GACd,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,OAAI,MAAM;IAAE,KAAK;IAAO,cAAc;IAAI;IAAY,OAAO;IAAkB,EAAE,kCAAkC,KAAK;AACxH,UAAO;;;;;;CAOX,MAAM,IAAI,YAAoB,QAA2C;EACvE,MAAM,aAAa,KAAK,cAAc,WAAW;EACjD,MAAM,sBAAsB;GAC1B,GAAG;GACH,WAAW,KAAK,KAAK;GACtB;AAED,MAAI;AACF,SAAM,gBAAgB,YAAY,KAAK,UAAU,qBAAqB,MAAM,EAAE,CAAC;AAC/E,OAAI,MAAM,EAAE,YAAY,EAAE,uBAAuB;WAC1C,OAAO;GACd,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,OAAI,MAAM;IAAE,KAAK;IAAO,cAAc;IAAI;IAAY,OAAO;IAAkB,EAAE,kCAAkC,KAAK;AACxH,SAAM;;;;;;CAOV,MAAM,OAAO,YAAoB,SAAmE;EAElG,MAAM,UAAU;GACd,GAAG,MAFkB,KAAK,IAAI,WAAW;GAGzC,GAAG;GACH,WAAW,KAAK,KAAK;GACtB;AAED,QAAM,KAAK,IAAI,YAAY,QAAQ;AACnC,SAAO;;;;;CAMT,MAAM,OAAO,YAAmC;EAC9C,MAAM,aAAa,KAAK,cAAc,WAAW;AAEjD,MAAI,WAAW,WAAW,CACxB,KAAI;GACF,MAAM,EAAE,WAAW,MAAM,OAAO;AAChC,SAAM,OAAO,WAAW;AACxB,OAAI,MAAM,EAAE,YAAY,EAAE,yBAAyB;WAC5C,OAAO;AACd,OAAI,MAAM;IAAE;IAAY;IAAO,EAAE,kCAAkC;AACnE,SAAM;;;;;;CAQZ,MAAM,IAAI,YAAsC;AAE9C,SAAO,WADY,KAAK,cAAc,WACV,CAAC;;;;;CAM/B,MAAM,SAAmD;EACvD,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,0BAAU,IAAI,KAAiC;AAErD,MAAI;GACF,MAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU;AAE3C,QAAK,MAAM,QAAQ,OAAO;AACxB,QAAI,CAAC,KAAK,SAAS,QAAQ,CAAE;IAE7B,MAAM,aAAa,KAAK,QAAQ,SAAS,GAAG,CAAC,QAAQ,MAAM,IAAI;IAC/D,MAAM,SAAS,MAAM,KAAK,IAAI,WAAW;AAEzC,QAAI,OACF,SAAQ,IAAI,YAAY,OAAO;;WAG5B,OAAO;AACd,OAAI,MAAM,EAAE,OAAO,EAAE,iCAAiC;;AAGxD,SAAO;;;;;CAMT,MAAM,QAAuB;EAC3B,MAAM,EAAE,SAAS,OAAO,MAAM,OAAO;AAErC,MAAI;GACF,MAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU;AAE3C,QAAK,MAAM,QAAQ,MACjB,KAAI,KAAK,SAAS,QAAQ,CACxB,OAAM,GAAG,KAAK,KAAK,WAAW,KAAK,EAAE,EAAE,OAAO,MAAM,CAAC;AAIzD,OAAI,MAAM,8BAA8B;WACjC,OAAO;AACd,OAAI,MAAM,EAAE,OAAO,EAAE,kCAAkC;AACvD,SAAM;;;;;;;;AAWZ,eAAsB,qBACpB,oBACA,YACA,cACiC;CACjC,MAAM,SAAS,MAAM,mBAAmB,IAAI,WAAW;AAEvD,KAAI,QAAQ,cACV,QAAO,OAAO;AAGhB,QAAO;;;;;AAMT,eAAsB,sBACpB,oBACA,YACA,cACqC;CACrC,MAAM,SAAS,MAAM,mBAAmB,IAAI,WAAW;AAEvD,KAAI,QAAQ,eACV,QAAO,OAAO;AAGhB,QAAO;;;;;AAMT,eAAsB,oBACpB,oBACA,YACA,cACmC;CACnC,MAAM,SAAS,MAAM,mBAAmB,IAAI,WAAW;AAEvD,KAAI,QAAQ,aACV,QAAO,OAAO;AAGhB,QAAO"}
|
|
1
|
+
{"version":3,"file":"config-store.js","names":["getSqliteSessionConfig","updateSqliteSessionConfig"],"sources":["../../../src/session/config-store.ts"],"sourcesContent":["import type { ReasoningLevel, ThinkLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport {\n deleteSessionConfig as deleteSqliteSessionConfig,\n getSessionConfig as getSqliteSessionConfig,\n hasSessionConfig,\n requireXopcDatabase,\n setSessionConfig as setSqliteSessionConfig,\n updateSessionConfig as updateSqliteSessionConfig,\n} from '../storage/sqlite/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport type { SessionAgentConfig } from './config-types.js';\n\nexport type { SessionAgentConfig } from './config-types.js';\n\nconst log = createLogger('SessionConfigStore');\n\nexport class SessionConfigStore {\n private cwd: string;\n\n constructor(_agentHomeDir: string, cwd = process.cwd()) {\n this.cwd = cwd;\n }\n\n private requireDatabase(): void {\n requireXopcDatabase();\n }\n\n async initialize(): Promise<void> {\n this.requireDatabase();\n log.debug('Session config store initialized (SQLite)');\n }\n\n async get(sessionKey: string): Promise<SessionAgentConfig | null> {\n this.requireDatabase();\n return getSqliteSessionConfig(sessionKey);\n }\n\n async set(sessionKey: string, config: SessionAgentConfig): Promise<void> {\n this.requireDatabase();\n setSqliteSessionConfig(sessionKey, config, this.cwd);\n log.debug({ sessionKey }, 'Session config saved');\n }\n\n async update(sessionKey: string, partial: Partial<SessionAgentConfig>): Promise<SessionAgentConfig> {\n this.requireDatabase();\n const updated = updateSqliteSessionConfig(sessionKey, partial, this.cwd);\n log.debug({ sessionKey }, 'Session config updated');\n return updated;\n }\n\n async delete(sessionKey: string): Promise<void> {\n this.requireDatabase();\n deleteSqliteSessionConfig(sessionKey);\n log.debug({ sessionKey }, 'Session config deleted');\n }\n\n async has(sessionKey: string): Promise<boolean> {\n this.requireDatabase();\n return hasSessionConfig(sessionKey);\n }\n\n async getAll(): Promise<Map<string, SessionAgentConfig>> {\n this.requireDatabase();\n const configs = new Map<string, SessionAgentConfig>();\n const { listSessionMetadata } = await import('../storage/sqlite/index.js');\n const { items } = listSessionMetadata({ limit: 100_000 });\n for (const item of items) {\n const config = getSqliteSessionConfig(item.key);\n if (config) {\n configs.set(item.key, config);\n }\n }\n return configs;\n }\n\n async clear(): Promise<void> {\n this.requireDatabase();\n const { listSessionMetadata } = await import('../storage/sqlite/index.js');\n const { items } = listSessionMetadata({ limit: 100_000 });\n for (const item of items) {\n deleteSqliteSessionConfig(item.key);\n }\n log.debug('All session configs cleared');\n }\n}\n\nexport async function resolveThinkingLevel(\n sessionConfigStore: SessionConfigStore,\n sessionKey: string,\n agentDefault?: ThinkLevel,\n): Promise<ThinkLevel | undefined> {\n const config = await sessionConfigStore.get(sessionKey);\n return config?.thinkingLevel ?? agentDefault;\n}\n\nexport async function resolveReasoningLevel(\n sessionConfigStore: SessionConfigStore,\n sessionKey: string,\n agentDefault?: ReasoningLevel,\n): Promise<ReasoningLevel | undefined> {\n const config = await sessionConfigStore.get(sessionKey);\n return config?.reasoningLevel ?? agentDefault;\n}\n\nexport async function resolveVerboseLevel(\n sessionConfigStore: SessionConfigStore,\n sessionKey: string,\n agentDefault?: VerboseLevel,\n): Promise<VerboseLevel | undefined> {\n const config = await sessionConfigStore.get(sessionKey);\n return config?.verboseLevel ?? agentDefault;\n}\n"],"mappings":";;;;;;aASkD;AAKlD,MAAM,MAAM,aAAa,qBAAqB;AAE9C,IAAa,qBAAb,MAAgC;CAC9B;CAEA,YAAY,eAAuB,MAAM,QAAQ,KAAK,EAAE;AACtD,OAAK,MAAM;;CAGb,kBAAgC;AAC9B,uBAAqB;;CAGvB,MAAM,aAA4B;AAChC,OAAK,iBAAiB;AACtB,MAAI,MAAM,4CAA4C;;CAGxD,MAAM,IAAI,YAAwD;AAChE,OAAK,iBAAiB;AACtB,SAAOA,iBAAuB,WAAW;;CAG3C,MAAM,IAAI,YAAoB,QAA2C;AACvE,OAAK,iBAAiB;AACtB,mBAAuB,YAAY,QAAQ,KAAK,IAAI;AACpD,MAAI,MAAM,EAAE,YAAY,EAAE,uBAAuB;;CAGnD,MAAM,OAAO,YAAoB,SAAmE;AAClG,OAAK,iBAAiB;EACtB,MAAM,UAAUC,oBAA0B,YAAY,SAAS,KAAK,IAAI;AACxE,MAAI,MAAM,EAAE,YAAY,EAAE,yBAAyB;AACnD,SAAO;;CAGT,MAAM,OAAO,YAAmC;AAC9C,OAAK,iBAAiB;AACtB,sBAA0B,WAAW;AACrC,MAAI,MAAM,EAAE,YAAY,EAAE,yBAAyB;;CAGrD,MAAM,IAAI,YAAsC;AAC9C,OAAK,iBAAiB;AACtB,SAAO,iBAAiB,WAAW;;CAGrC,MAAM,SAAmD;AACvD,OAAK,iBAAiB;EACtB,MAAM,0BAAU,IAAI,KAAiC;EACrD,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,EAAE,UAAU,oBAAoB,EAAE,OAAO,KAAS,CAAC;AACzD,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,SAASD,iBAAuB,KAAK,IAAI;AAC/C,OAAI,OACF,SAAQ,IAAI,KAAK,KAAK,OAAO;;AAGjC,SAAO;;CAGT,MAAM,QAAuB;AAC3B,OAAK,iBAAiB;EACtB,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,EAAE,UAAU,oBAAoB,EAAE,OAAO,KAAS,CAAC;AACzD,OAAK,MAAM,QAAQ,MACjB,qBAA0B,KAAK,IAAI;AAErC,MAAI,MAAM,8BAA8B;;;AAI5C,eAAsB,qBACpB,oBACA,YACA,cACiC;AAEjC,SAAO,MADc,mBAAmB,IAAI,WAAW,GACxC,iBAAiB;;AAGlC,eAAsB,sBACpB,oBACA,YACA,cACqC;AAErC,SAAO,MADc,mBAAmB,IAAI,WAAW,GACxC,kBAAkB;;AAGnC,eAAsB,oBACpB,oBACA,YACA,cACmC;AAEnC,SAAO,MADc,mBAAmB,IAAI,WAAW,GACxC,gBAAgB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ElevatedMode, ReasoningLevel, ThinkLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Session-level agent configuration persisted in SQLite.
|
|
4
|
+
* These settings override agent defaults for a specific session.
|
|
5
|
+
*/
|
|
6
|
+
export interface SessionAgentConfig {
|
|
7
|
+
thinkingLevel?: ThinkLevel;
|
|
8
|
+
reasoningLevel?: ReasoningLevel;
|
|
9
|
+
verboseLevel?: VerboseLevel;
|
|
10
|
+
elevatedMode?: ElevatedMode;
|
|
11
|
+
modelOverride?: string;
|
|
12
|
+
providerOverride?: string;
|
|
13
|
+
workingDirectoryOverride?: string;
|
|
14
|
+
updatedAt?: number;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,11 +2,9 @@ export { SessionIndex, type SessionIndexConfig } from './manager.js';
|
|
|
2
2
|
export { onSessionTranscriptUpdate, emitSessionTranscriptUpdate, type SessionTranscriptUpdate, } from './transcript-events.js';
|
|
3
3
|
export { SessionStore } from './store.js';
|
|
4
4
|
export type { SessionStoreOptions } from './store.js';
|
|
5
|
-
export { SessionSearchIndex } from './search-index.js';
|
|
6
|
-
export { getOrLoadSessionSearchIndex, invalidateSessionSearchIndexCache, } from './search-index-cache.js';
|
|
7
5
|
export { SessionConfigStore, resolveThinkingLevel, resolveReasoningLevel, resolveVerboseLevel } from './config-store.js';
|
|
8
6
|
export { resolveEffectiveThinkingLevel, resolveEffectiveReasoningLevel } from './thinking-resolve.js';
|
|
9
|
-
export type { SessionAgentConfig } from './config-
|
|
7
|
+
export type { SessionAgentConfig } from './config-types.js';
|
|
10
8
|
export { normalizeWorkingDirectoryInput, effectiveWorkspacePathForSession, } from './session-workspace.js';
|
|
11
9
|
export { SessionStatus, type SessionMetadata, type SessionDetail, type SessionListQuery, type PaginatedResult, type SessionStats, type ExportFormat, type SessionExport, type SessionTranscriptSummary, type CompactionCheckpointSummary, type CompactionCheckpointDetail, } from './types.js';
|
|
12
10
|
export { normalizeCompactionCheckpointId } from './compaction-checkpoints.js';
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SessionStatus } from "./types.js";
|
|
2
2
|
import { buildSessionContextForLlm, isTranscriptContextEntry, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray } from "./session-context-for-llm.js";
|
|
3
|
-
import {
|
|
4
|
-
import { getOrLoadSessionSearchIndex, invalidateSessionSearchIndexCache } from "./search-index-cache.js";
|
|
3
|
+
import { emitSessionTranscriptUpdate, onSessionTranscriptUpdate } from "./transcript-events.js";
|
|
5
4
|
import { fallbackTitleFromMessages, generateSessionTitleFromMessages, getSessionTitleSource, isWebchatSessionKey, maybeRefineSessionTitleWithLlm, maybeSetProvisionalSessionTitle, provisionalTitleFromUserText, sanitizeSessionTitle, shouldAutoTitleSessionKey, shouldRefineSessionTitleWithLlm } from "./session-title.js";
|
|
6
5
|
import { normalizeCompactionCheckpointId } from "./compaction-checkpoints.js";
|
|
7
|
-
import { SessionStatus } from "./types.js";
|
|
8
6
|
import { SessionStore } from "./store.js";
|
|
9
7
|
import { applySessionPatchToMetadata } from "./patch-metadata.js";
|
|
10
8
|
import { SessionIndex } from "./manager.js";
|
|
@@ -20,4 +18,4 @@ import { DEFAULT_RESET_TRIGGERS, RESET_OVERLAP_COMMANDS, bareResetAckMessage, ma
|
|
|
20
18
|
import { initSessionTurn } from "./init-session-turn.js";
|
|
21
19
|
import { flattenMessageContent, messagesToClientHistory } from "./client-history.js";
|
|
22
20
|
import { CURRENT_SESSION_TRANSCRIPT_VERSION, XOPC_SESSION_TRANSCRIPT_TYPE } from "./transcript-format.js";
|
|
23
|
-
export { CURRENT_SESSION_TRANSCRIPT_VERSION, DEFAULT_IDLE_MINUTES, DEFAULT_RESET_AT_HOUR, DEFAULT_RESET_MODE, DEFAULT_RESET_TRIGGERS, RESET_OVERLAP_COMMANDS, SessionConfigStore, SessionIndex,
|
|
21
|
+
export { CURRENT_SESSION_TRANSCRIPT_VERSION, DEFAULT_IDLE_MINUTES, DEFAULT_RESET_AT_HOUR, DEFAULT_RESET_MODE, DEFAULT_RESET_TRIGGERS, RESET_OVERLAP_COMMANDS, SessionConfigStore, SessionIndex, SessionStatus, SessionStore, XOPC_SESSION_TRANSCRIPT_TYPE, applySessionPatchToMetadata, bareResetAckMessage, buildSessionContextForLlm, effectiveWorkspacePathForSession, emitSessionTranscriptUpdate, evaluateSessionFreshness, fallbackTitleFromMessages, flattenMessageContent, generateSessionTitleFromMessages, getSessionTitleSource, initSessionTurn, isThreadSessionKey, isTranscriptContextEntry, isWebchatSessionKey, matchResetTriggers, maybeRefineSessionTitleWithLlm, maybeSetProvisionalSessionTitle, mergeLlmMessagesPreservingContextRows, messagesToClientHistory, normalizeCompactionCheckpointId, normalizeWorkingDirectoryInput, onSessionTranscriptUpdate, provisionalTitleFromUserText, resolveChannelResetConfig, resolveDailyResetAtMs, resolveEffectiveReasoningLevel, resolveEffectiveThinkingLevel, resolveReasoningLevel, resolveResetTriggers, resolveSession, resolveSessionKeyForRequest, resolveSessionLifecycleTimestamps, resolveSessionResetPolicy, resolveSessionResetType, resolveThinkingLevel, resolveVerboseLevel, sanitizeSessionTitle, shouldAutoTitleSessionKey, shouldRefineSessionTitleWithLlm, shouldSkipResetOverlapCommand, shouldSkipWebchatInboundByAbortCutoff, stripLeadingEnvelopeTimestamp, transcriptRowsFromJsonArray };
|
|
@@ -19,12 +19,6 @@ export type InitSessionTurnOptions = {
|
|
|
19
19
|
sessionKey: string;
|
|
20
20
|
body?: string;
|
|
21
21
|
resetSession: SessionResetFn;
|
|
22
|
-
/** When true, skip idle/daily implicit rollover (provider-owned CLI sessions). */
|
|
23
22
|
skipImplicitExpiry?: boolean;
|
|
24
23
|
};
|
|
25
|
-
/**
|
|
26
|
-
* Turn-start session init: match `resetTriggers`, evaluate freshness, archive +
|
|
27
|
-
* assign new `sessionId` when stale or explicitly reset. OpenClaw `initSessionState`
|
|
28
|
-
* equivalent for xopc direct + channel paths.
|
|
29
|
-
*/
|
|
30
24
|
export declare function initSessionTurn(opts: InitSessionTurnOptions): Promise<InitSessionTurnResult>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { SessionConfigSchema, init_schema } from "../config/schema.js";
|
|
2
|
-
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
3
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
4
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { SessionConfigSchema, init_schema } from "../config/schema.js";
|
|
4
|
+
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
5
|
+
import { requireXopcDatabase } from "../storage/sqlite/connection.js";
|
|
6
|
+
import "../storage/sqlite/index.js";
|
|
5
7
|
import { evaluateSessionFreshness, resolveSessionResetPolicy } from "./reset-policy.js";
|
|
6
8
|
import { resolveChannelResetConfig, resolveSessionResetType } from "./reset-type.js";
|
|
7
9
|
import { resolveSessionLifecycleTimestamps } from "./lifecycle-timestamps.js";
|
|
@@ -13,22 +15,17 @@ init_schema();
|
|
|
13
15
|
init_session_key();
|
|
14
16
|
init_logger();
|
|
15
17
|
const log = createLogger("InitSessionTurn");
|
|
16
|
-
/**
|
|
17
|
-
* Turn-start session init: match `resetTriggers`, evaluate freshness, archive +
|
|
18
|
-
* assign new `sessionId` when stale or explicitly reset. OpenClaw `initSessionState`
|
|
19
|
-
* equivalent for xopc direct + channel paths.
|
|
20
|
-
*/
|
|
21
18
|
async function initSessionTurn(opts) {
|
|
19
|
+
requireXopcDatabase();
|
|
22
20
|
const sessionCfg = opts.cfg.session ?? SessionConfigSchema.parse({});
|
|
23
21
|
const triggers = resolveResetTriggers(sessionCfg.resetTriggers);
|
|
24
22
|
const rawBody = opts.body ?? "";
|
|
25
23
|
const triggerMatch = matchResetTriggers(rawBody, triggers);
|
|
26
|
-
const { sessionKey,
|
|
24
|
+
const { sessionKey, sessionMetadata } = await resolveSessionKeyForRequest({
|
|
27
25
|
cfg: opts.cfg,
|
|
28
26
|
sessionKey: opts.sessionKey
|
|
29
27
|
});
|
|
30
28
|
const key = sessionKey?.trim() ?? opts.sessionKey.trim();
|
|
31
|
-
const sessionEntry = key ? sessionStore[key] : void 0;
|
|
32
29
|
const parsed = key ? parseSessionKey(key) : null;
|
|
33
30
|
const peerKind = parsed?.peerKind;
|
|
34
31
|
const resetType = resolveSessionResetType({
|
|
@@ -36,30 +33,33 @@ async function initSessionTurn(opts) {
|
|
|
36
33
|
isGroup: peerKind === "group" || peerKind === "channel",
|
|
37
34
|
isThread: Boolean(parsed?.threadId)
|
|
38
35
|
});
|
|
39
|
-
const meta = sessionEntry?.pluginExtensions?.xopc?.metadata;
|
|
40
36
|
const resetPolicy = resolveSessionResetPolicy({
|
|
41
37
|
sessionCfg,
|
|
42
38
|
resetType,
|
|
43
39
|
resetOverride: resolveChannelResetConfig({
|
|
44
40
|
sessionCfg,
|
|
45
|
-
channel: parsed?.source ??
|
|
41
|
+
channel: parsed?.source ?? sessionMetadata?.sourceChannel
|
|
46
42
|
})
|
|
47
43
|
});
|
|
48
|
-
const lifecycle = resolveSessionLifecycleTimestamps({ entry:
|
|
44
|
+
const lifecycle = resolveSessionLifecycleTimestamps({ entry: sessionMetadata ? {
|
|
45
|
+
updatedAt: Date.parse(sessionMetadata.updatedAt),
|
|
46
|
+
sessionStartedAt: sessionMetadata.sessionStartedAt ? Date.parse(sessionMetadata.sessionStartedAt) : void 0,
|
|
47
|
+
lastInteractionAt: sessionMetadata.lastInteractionAt ? Date.parse(sessionMetadata.lastInteractionAt) : void 0
|
|
48
|
+
} : void 0 });
|
|
49
49
|
const now = Date.now();
|
|
50
|
-
const freshness =
|
|
51
|
-
updatedAt:
|
|
50
|
+
const freshness = sessionMetadata ? evaluateSessionFreshness({
|
|
51
|
+
updatedAt: Date.parse(sessionMetadata.updatedAt),
|
|
52
52
|
...lifecycle,
|
|
53
53
|
now,
|
|
54
54
|
policy: resetPolicy
|
|
55
55
|
}) : { fresh: false };
|
|
56
56
|
const skipImplicit = opts.skipImplicitExpiry ?? false;
|
|
57
|
-
const staleRollover = Boolean(
|
|
57
|
+
const staleRollover = Boolean(sessionMetadata && !skipImplicit && !freshness.fresh);
|
|
58
58
|
const needsRollover = triggerMatch.resetTriggered || staleRollover;
|
|
59
|
-
let sessionId =
|
|
59
|
+
let sessionId = sessionMetadata?.transcriptId;
|
|
60
60
|
let previousSessionId;
|
|
61
61
|
let isNewSession = false;
|
|
62
|
-
if (needsRollover &&
|
|
62
|
+
if (needsRollover && sessionMetadata?.transcriptId) {
|
|
63
63
|
const outcome = await opts.resetSession(key);
|
|
64
64
|
if (outcome) {
|
|
65
65
|
previousSessionId = outcome.previousSessionId;
|
|
@@ -78,7 +78,7 @@ async function initSessionTurn(opts) {
|
|
|
78
78
|
sessionId = randomUUID();
|
|
79
79
|
isNewSession = true;
|
|
80
80
|
}
|
|
81
|
-
} else if (!
|
|
81
|
+
} else if (!sessionMetadata) {
|
|
82
82
|
isNewSession = true;
|
|
83
83
|
sessionId = randomUUID();
|
|
84
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-session-turn.js","names":[],"sources":["../../../src/session/init-session-turn.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { SessionConfigSchema, type Config } from '../config/schema.js';\nimport { parseSessionKey } from '../routing/session-key.js';\nimport { createLogger } from '../utils/logger.js';\
|
|
1
|
+
{"version":3,"file":"init-session-turn.js","names":[],"sources":["../../../src/session/init-session-turn.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { SessionConfigSchema, type Config } from '../config/schema.js';\nimport { parseSessionKey } from '../routing/session-key.js';\nimport { createLogger } from '../utils/logger.js';\nimport { requireXopcDatabase } from '../storage/sqlite/index.js';\nimport { resolveSessionLifecycleTimestamps } from './lifecycle-timestamps.js';\nimport {\n evaluateSessionFreshness,\n resolveSessionResetPolicy,\n} from './reset-policy.js';\nimport {\n bareResetAckMessage,\n matchResetTriggers,\n resolveResetTriggers,\n} from './reset-triggers.js';\nimport { resolveChannelResetConfig, resolveSessionResetType } from './reset-type.js';\nimport { resolveSessionKeyForRequest } from './resolve-session.js';\n\nconst log = createLogger('InitSessionTurn');\n\nexport type SessionResetFn = (\n sessionKey: string,\n) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n\nexport type InitSessionTurnResult = {\n sessionKey: string;\n sessionId?: string;\n previousSessionId?: string;\n isNewSession: boolean;\n resetTriggered: boolean;\n staleRollover: boolean;\n bodyStripped: string;\n bareReset: boolean;\n ackMessage?: string;\n};\n\nexport type InitSessionTurnOptions = {\n cfg: Config;\n sessionKey: string;\n body?: string;\n resetSession: SessionResetFn;\n skipImplicitExpiry?: boolean;\n};\n\nexport async function initSessionTurn(\n opts: InitSessionTurnOptions,\n): Promise<InitSessionTurnResult> {\n requireXopcDatabase();\n\n const sessionCfg = opts.cfg.session ?? SessionConfigSchema.parse({});\n const triggers = resolveResetTriggers(sessionCfg.resetTriggers);\n const rawBody = opts.body ?? '';\n const triggerMatch = matchResetTriggers(rawBody, triggers);\n\n const { sessionKey, sessionMetadata } = await resolveSessionKeyForRequest({\n cfg: opts.cfg,\n sessionKey: opts.sessionKey,\n });\n const key = sessionKey?.trim() ?? opts.sessionKey.trim();\n\n const parsed = key ? parseSessionKey(key) : null;\n const peerKind = parsed?.peerKind;\n const resetType = resolveSessionResetType({\n sessionKey: key,\n isGroup: peerKind === 'group' || peerKind === 'channel',\n isThread: Boolean(parsed?.threadId),\n });\n const channelReset = resolveChannelResetConfig({\n sessionCfg,\n channel: parsed?.source ?? sessionMetadata?.sourceChannel,\n });\n const resetPolicy = resolveSessionResetPolicy({\n sessionCfg,\n resetType,\n resetOverride: channelReset,\n });\n const lifecycle = resolveSessionLifecycleTimestamps({\n entry: sessionMetadata\n ? {\n updatedAt: Date.parse(sessionMetadata.updatedAt),\n sessionStartedAt: sessionMetadata.sessionStartedAt\n ? Date.parse(sessionMetadata.sessionStartedAt)\n : undefined,\n lastInteractionAt: sessionMetadata.lastInteractionAt\n ? Date.parse(sessionMetadata.lastInteractionAt)\n : undefined,\n }\n : undefined,\n });\n const now = Date.now();\n const freshness = sessionMetadata\n ? evaluateSessionFreshness({\n updatedAt: Date.parse(sessionMetadata.updatedAt),\n ...lifecycle,\n now,\n policy: resetPolicy,\n })\n : { fresh: false };\n\n const skipImplicit = opts.skipImplicitExpiry ?? false;\n const staleRollover = Boolean(sessionMetadata && !skipImplicit && !freshness.fresh);\n const needsRollover = triggerMatch.resetTriggered || staleRollover;\n\n let sessionId = sessionMetadata?.transcriptId;\n let previousSessionId: string | undefined;\n let isNewSession = false;\n\n if (needsRollover && sessionMetadata?.transcriptId) {\n const outcome = await opts.resetSession(key);\n if (outcome) {\n previousSessionId = outcome.previousSessionId;\n sessionId = outcome.sessionId;\n isNewSession = true;\n log.info(\n {\n sessionKey: key,\n sessionId: outcome.sessionId,\n previousSessionId: outcome.previousSessionId,\n resetTriggered: triggerMatch.resetTriggered,\n staleRollover,\n resetType,\n },\n triggerMatch.resetTriggered\n ? 'Session reset via reset trigger'\n : 'Session rolled over (stale freshness)',\n );\n } else {\n log.warn({ sessionKey: key }, 'Session rollover requested but resetSession returned null');\n sessionId = randomUUID();\n isNewSession = true;\n }\n } else if (!sessionMetadata) {\n isNewSession = true;\n sessionId = randomUUID();\n }\n\n const bareReset = triggerMatch.resetTriggered && triggerMatch.bareReset;\n const ackMessage = bareReset ? bareResetAckMessage(triggerMatch.matchedTrigger) : undefined;\n\n return {\n sessionKey: key,\n sessionId,\n previousSessionId,\n isNewSession,\n resetTriggered: triggerMatch.resetTriggered,\n staleRollover,\n bodyStripped: triggerMatch.resetTriggered ? triggerMatch.bodyStripped : rawBody,\n bareReset,\n ackMessage,\n };\n}\n"],"mappings":";;;;;;;;;;;;;aAEuE;kBACX;aACV;AAelD,MAAM,MAAM,aAAa,kBAAkB;AA0B3C,eAAsB,gBACpB,MACgC;AAChC,sBAAqB;CAErB,MAAM,aAAa,KAAK,IAAI,WAAW,oBAAoB,MAAM,EAAE,CAAC;CACpE,MAAM,WAAW,qBAAqB,WAAW,cAAc;CAC/D,MAAM,UAAU,KAAK,QAAQ;CAC7B,MAAM,eAAe,mBAAmB,SAAS,SAAS;CAE1D,MAAM,EAAE,YAAY,oBAAoB,MAAM,4BAA4B;EACxE,KAAK,KAAK;EACV,YAAY,KAAK;EAClB,CAAC;CACF,MAAM,MAAM,YAAY,MAAM,IAAI,KAAK,WAAW,MAAM;CAExD,MAAM,SAAS,MAAM,gBAAgB,IAAI,GAAG;CAC5C,MAAM,WAAW,QAAQ;CACzB,MAAM,YAAY,wBAAwB;EACxC,YAAY;EACZ,SAAS,aAAa,WAAW,aAAa;EAC9C,UAAU,QAAQ,QAAQ,SAAS;EACpC,CAAC;CAKF,MAAM,cAAc,0BAA0B;EAC5C;EACA;EACA,eAPmB,0BAA0B;GAC7C;GACA,SAAS,QAAQ,UAAU,iBAAiB;GAC7C,CAI4B;EAC5B,CAAC;CACF,MAAM,YAAY,kCAAkC,EAClD,OAAO,kBACH;EACE,WAAW,KAAK,MAAM,gBAAgB,UAAU;EAChD,kBAAkB,gBAAgB,mBAC9B,KAAK,MAAM,gBAAgB,iBAAiB,GAC5C,KAAA;EACJ,mBAAmB,gBAAgB,oBAC/B,KAAK,MAAM,gBAAgB,kBAAkB,GAC7C,KAAA;EACL,GACD,KAAA,GACL,CAAC;CACF,MAAM,MAAM,KAAK,KAAK;CACtB,MAAM,YAAY,kBACd,yBAAyB;EACvB,WAAW,KAAK,MAAM,gBAAgB,UAAU;EAChD,GAAG;EACH;EACA,QAAQ;EACT,CAAC,GACF,EAAE,OAAO,OAAO;CAEpB,MAAM,eAAe,KAAK,sBAAsB;CAChD,MAAM,gBAAgB,QAAQ,mBAAmB,CAAC,gBAAgB,CAAC,UAAU,MAAM;CACnF,MAAM,gBAAgB,aAAa,kBAAkB;CAErD,IAAI,YAAY,iBAAiB;CACjC,IAAI;CACJ,IAAI,eAAe;AAEnB,KAAI,iBAAiB,iBAAiB,cAAc;EAClD,MAAM,UAAU,MAAM,KAAK,aAAa,IAAI;AAC5C,MAAI,SAAS;AACX,uBAAoB,QAAQ;AAC5B,eAAY,QAAQ;AACpB,kBAAe;AACf,OAAI,KACF;IACE,YAAY;IACZ,WAAW,QAAQ;IACnB,mBAAmB,QAAQ;IAC3B,gBAAgB,aAAa;IAC7B;IACA;IACD,EACD,aAAa,iBACT,oCACA,wCACL;SACI;AACL,OAAI,KAAK,EAAE,YAAY,KAAK,EAAE,4DAA4D;AAC1F,eAAY,YAAY;AACxB,kBAAe;;YAER,CAAC,iBAAiB;AAC3B,iBAAe;AACf,cAAY,YAAY;;CAG1B,MAAM,YAAY,aAAa,kBAAkB,aAAa;CAC9D,MAAM,aAAa,YAAY,oBAAoB,aAAa,eAAe,GAAG,KAAA;AAElF,QAAO;EACL,YAAY;EACZ;EACA;EACA;EACA,gBAAgB,aAAa;EAC7B;EACA,cAAc,aAAa,iBAAiB,aAAa,eAAe;EACxE;EACA;EACD"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export type SessionLifecycleEntry = {
|
|
2
|
+
sessionStartedAt?: number;
|
|
3
|
+
lastInteractionAt?: number;
|
|
4
|
+
updatedAt?: number;
|
|
5
|
+
};
|
|
3
6
|
export declare function resolveSessionLifecycleTimestamps(params: {
|
|
4
7
|
entry: SessionLifecycleEntry | undefined;
|
|
5
8
|
}): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle-timestamps.js","names":[],"sources":["../../../src/session/lifecycle-timestamps.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"lifecycle-timestamps.js","names":[],"sources":["../../../src/session/lifecycle-timestamps.ts"],"sourcesContent":["export type SessionLifecycleEntry = {\n sessionStartedAt?: number;\n lastInteractionAt?: number;\n updatedAt?: number;\n};\n\nfunction resolveTimestamp(value: number | undefined): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\nexport function resolveSessionLifecycleTimestamps(params: {\n entry: SessionLifecycleEntry | undefined;\n}): { sessionStartedAt?: number; lastInteractionAt?: number } {\n const entry = params.entry;\n if (!entry) {\n return {};\n }\n return {\n sessionStartedAt: resolveTimestamp(entry.sessionStartedAt),\n lastInteractionAt: resolveTimestamp(entry.lastInteractionAt),\n };\n}\n"],"mappings":";AAMA,SAAS,iBAAiB,OAA+C;AACvE,QAAO,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,IAAI,SAAS,IAAI,QAAQ,KAAA;;AAGrF,SAAgB,kCAAkC,QAEY;CAC5D,MAAM,QAAQ,OAAO;AACrB,KAAI,CAAC,MACH,QAAO,EAAE;AAEX,QAAO;EACL,kBAAkB,iBAAiB,MAAM,iBAAiB;EAC1D,mBAAmB,iBAAiB,MAAM,kBAAkB;EAC7D"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
//#region src/session/
|
|
2
|
+
//#region src/session/load-jsonl-entries.ts
|
|
3
3
|
/** Same semantics as pi-coding-agent `loadEntriesFromFile` (package does not export it from the root). */
|
|
4
4
|
function loadEntriesFromFile(filePath) {
|
|
5
5
|
if (!existsSync(filePath)) return [];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-jsonl-entries.js","names":[],"sources":["../../../src/session/load-jsonl-entries.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\n\nimport type { FileEntry } from '@earendil-works/pi-coding-agent';\n\n/** Same semantics as pi-coding-agent `loadEntriesFromFile` (package does not export it from the root). */\nexport function loadEntriesFromFile(filePath: string): FileEntry[] {\n if (!existsSync(filePath)) {\n return [];\n }\n const content = readFileSync(filePath, 'utf8');\n const entries: FileEntry[] = [];\n for (const line of content.trim().split('\\n')) {\n if (!line.trim()) {\n continue;\n }\n try {\n entries.push(JSON.parse(line) as FileEntry);\n } catch {\n // Skip malformed lines (matches upstream)\n }\n }\n if (entries.length === 0) {\n return entries;\n }\n const header = entries[0];\n if (header.type !== 'session' || typeof (header as { id?: unknown }).id !== 'string') {\n return [];\n }\n return entries;\n}\n"],"mappings":";;;AAKA,SAAgB,oBAAoB,UAA+B;AACjE,KAAI,CAAC,WAAW,SAAS,CACvB,QAAO,EAAE;CAEX,MAAM,UAAU,aAAa,UAAU,OAAO;CAC9C,MAAM,UAAuB,EAAE;AAC/B,MAAK,MAAM,QAAQ,QAAQ,MAAM,CAAC,MAAM,KAAK,EAAE;AAC7C,MAAI,CAAC,KAAK,MAAM,CACd;AAEF,MAAI;AACF,WAAQ,KAAK,KAAK,MAAM,KAAK,CAAc;UACrC;;AAIV,KAAI,QAAQ,WAAW,EACrB,QAAO;CAET,MAAM,SAAS,QAAQ;AACvB,KAAI,OAAO,SAAS,aAAa,OAAQ,OAA4B,OAAO,SAC1E,QAAO,EAAE;AAEX,QAAO"}
|
|
@@ -10,8 +10,6 @@ import type { WindowConfig } from '../agent/memory/window.js';
|
|
|
10
10
|
import type { Config } from '../config/schema.js';
|
|
11
11
|
export interface SessionIndexConfig {
|
|
12
12
|
config: Config;
|
|
13
|
-
agentId?: string;
|
|
14
|
-
sessionsDir?: string;
|
|
15
13
|
windowConfig?: Partial<WindowConfig>;
|
|
16
14
|
compactionConfig?: Partial<CompactionConfig>;
|
|
17
15
|
}
|
|
@@ -140,7 +138,11 @@ export declare class SessionIndex extends EventEmitter {
|
|
|
140
138
|
prepareCompaction(key: string, messages: any[], contextWindow: number): {
|
|
141
139
|
needsCompaction: boolean;
|
|
142
140
|
messages: import("@earendil-works/pi-agent-core").AgentMessage[];
|
|
143
|
-
stats
|
|
141
|
+
stats: {
|
|
142
|
+
needed: boolean;
|
|
143
|
+
reason: string;
|
|
144
|
+
usagePercent?: number;
|
|
145
|
+
};
|
|
144
146
|
};
|
|
145
147
|
/** Compact session messages */
|
|
146
148
|
compact(key: string, messages: any[], contextWindow: number, instructions?: string, force?: boolean): Promise<CompactionResult>;
|
|
@@ -10,11 +10,7 @@ var SessionIndex = class extends EventEmitter$1 {
|
|
|
10
10
|
store;
|
|
11
11
|
constructor(config) {
|
|
12
12
|
super();
|
|
13
|
-
this.store = new SessionStore({
|
|
14
|
-
config: config.config,
|
|
15
|
-
agentId: config.agentId,
|
|
16
|
-
sessionsDir: config.sessionsDir
|
|
17
|
-
}, config.windowConfig, config.compactionConfig);
|
|
13
|
+
this.store = new SessionStore({ config: config.config }, config.windowConfig, config.compactionConfig);
|
|
18
14
|
}
|
|
19
15
|
async initialize() {
|
|
20
16
|
await this.store.initialize();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","names":["EventEmitter"],"sources":["../../../src/session/manager.ts"],"sourcesContent":["// Session manager - high-level session management service\n\nimport EventEmitter from 'events';\nimport { createLogger } from '../utils/logger.js';\nimport { SessionStore } from './store.js';\nimport type {\n SessionMetadata,\n SessionDetail,\n SessionListQuery,\n PaginatedResult,\n GlobalSessionStats,\n ExportFormat,\n SessionStatus,\n} from './types.js';\nimport type { Message } from './types.js';\nimport type { CompactionConfig, CompactionResult } from '../agent/memory/compaction.js';\nimport type { XopcSessionTranscriptV1 } from './transcript-format.js';\nimport type { XopcTranscriptContextEntry } from './session-context-for-llm.js';\nimport { applySessionPatchToMetadata, type SessionPatchBody } from './patch-metadata.js';\nimport type { WindowConfig } from '../agent/memory/window.js';\nimport type { Config } from '../config/schema.js';\n\nconst log = createLogger('SessionIndex');\n\nexport interface SessionIndexConfig {\n config: Config;\n agentId?: string;\n sessionsDir?: string;\n windowConfig?: Partial<WindowConfig>;\n compactionConfig?: Partial<CompactionConfig>;\n}\n\nexport class SessionIndex extends EventEmitter {\n private store: SessionStore;\n\n constructor(config: SessionIndexConfig) {\n super();\n this.store = new SessionStore(\n {\n config: config.config,\n agentId: config.agentId,\n sessionsDir: config.sessionsDir,\n },\n config.windowConfig,\n config.compactionConfig\n );\n }\n\n async initialize(): Promise<void> {\n await this.store.initialize();\n this.emit('ready');\n }\n\n /** Low-level store (e.g. cron resolving weixin delivery from session index). */\n getStore(): SessionStore {\n return this.store;\n }\n\n // ========== CRUD Operations ==========\n\n async listSessions(query?: SessionListQuery): Promise<PaginatedResult<SessionMetadata>> {\n return this.store.list(query);\n }\n\n /**\n * List all subagent sessions.\n * Subagent sessions have keys starting with 'subagent:'.\n */\n async listSubagents(query: SessionListQuery = {}): Promise<PaginatedResult<SessionMetadata>> {\n // Filter for subagent sessions only\n const subagentQuery: SessionListQuery = {\n ...query,\n search: query.search ? `subagent:${query.search}` : 'subagent:',\n };\n \n const result = await this.store.list(subagentQuery);\n \n // Additional filtering to ensure only subagent sessions\n const subagentSessions = result.items.filter((s) => s.key.startsWith('subagent:'));\n \n return {\n ...result,\n items: subagentSessions,\n total: subagentSessions.length,\n hasMore: false, // Simplified for now\n };\n }\n\n async getSession(\n key: string,\n options?: { includeTranscriptSummary?: boolean; includeTranscriptRows?: boolean },\n ): Promise<SessionDetail | null> {\n const session = await this.store.get(key, options);\n if (session) {\n this.emit('sessionAccessed', { key });\n }\n return session;\n }\n\n async getSessionMessagePage(\n key: string,\n options?: {\n offset?: number;\n limit?: number;\n before?: string;\n includeTranscriptSummary?: boolean;\n includeTranscriptRows?: boolean;\n },\n ): Promise<{\n session: SessionDetail;\n pagination: {\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n before?: string;\n nextBeforeCursor?: string;\n };\n } | null> {\n const result = await this.store.getMessagePage(key, options);\n if (result) {\n this.emit('sessionAccessed', { key });\n }\n return result;\n }\n\n /**\n * OpenClaw-style `sessions.patch`: partial metadata (name, tags, customData shallow merge).\n */\n async patchSession(\n key: string,\n patch: SessionPatchBody,\n ): Promise<{ ok: true } | { ok: false; error: string }> {\n const meta = await this.store.getMetadata(key);\n if (!meta) {\n return { ok: false, error: 'Session not found' };\n }\n const updates = applySessionPatchToMetadata(meta, patch);\n if (Object.keys(updates).length === 0) {\n return { ok: true };\n }\n await this.store.updateMetadata(key, updates);\n this.emit('sessionUpdated', { key });\n return { ok: true };\n }\n\n async getSessionMetadata(key: string): Promise<SessionMetadata | null> {\n return this.store.getMetadata(key);\n }\n\n async deleteSession(key: string): Promise<boolean> {\n const result = await this.store.delete(key);\n if (result) {\n this.emit('sessionDeleted', { key });\n }\n return result;\n }\n\n async deleteSessions(keys: string[]): Promise<{ success: string[]; failed: string[] }> {\n const result = await this.store.deleteMany(keys);\n for (const key of result.success) {\n this.emit('sessionDeleted', { key });\n }\n return result;\n }\n\n // ========== Metadata Updates ==========\n\n async renameSession(key: string, name: string): Promise<void> {\n const existing = await this.store.getMetadata(key);\n await this.store.updateMetadata(key, {\n name,\n customData: { ...(existing?.customData ?? {}), titleSource: 'user' },\n });\n this.emit('sessionUpdated', { key, name });\n }\n\n /** Partial metadata update (caller merges nested fields like `customData` when needed). */\n async updateSessionMetadata(key: string, updates: Partial<SessionMetadata>): Promise<void> {\n await this.store.updateMetadata(key, updates);\n this.emit('sessionUpdated', { key });\n }\n\n async tagSession(key: string, tags: string[]): Promise<void> {\n const existing = await this.store.getMetadata(key);\n if (!existing) {\n throw new Error(`Session not found: ${key}`);\n }\n\n // Merge tags, remove duplicates\n const mergedTags = [...new Set([...existing.tags, ...tags])];\n await this.store.updateMetadata(key, { tags: mergedTags });\n this.emit('sessionUpdated', { key, tags: mergedTags });\n }\n\n async untagSession(key: string, tags: string[]): Promise<void> {\n const existing = await this.store.getMetadata(key);\n if (!existing) {\n throw new Error(`Session not found: ${key}`);\n }\n\n const filteredTags = existing.tags.filter((t) => !tags.includes(t));\n await this.store.updateMetadata(key, { tags: filteredTags });\n this.emit('sessionUpdated', { key, tags: filteredTags });\n }\n\n async setSessionTags(key: string, tags: string[]): Promise<void> {\n await this.store.updateMetadata(key, { tags: [...new Set(tags)] });\n this.emit('sessionUpdated', { key, tags });\n }\n\n // ========== Status Management ==========\n\n async archiveSession(key: string): Promise<void> {\n await this.store.archive(key);\n this.emit('sessionArchived', { key });\n }\n\n async unarchiveSession(key: string): Promise<void> {\n await this.store.unarchive(key);\n this.emit('sessionRestored', { key });\n }\n\n async pinSession(key: string): Promise<void> {\n await this.store.pin(key);\n this.emit('sessionPinned', { key });\n }\n\n async unpinSession(key: string): Promise<void> {\n await this.store.unpin(key);\n this.emit('sessionUnpinned', { key });\n }\n\n async setSessionStatus(key: string, status: SessionStatus): Promise<void> {\n await this.store.setStatus(key, status);\n this.emit('sessionStatusChanged', { key, status });\n }\n\n // ========== Search ==========\n\n async searchSessions(query: string): Promise<SessionMetadata[]> {\n const result = await this.store.list({ search: query, limit: 100 });\n return result.items;\n }\n\n async searchInSession(key: string, keyword: string): Promise<Message[]> {\n return this.store.searchInSession(key, keyword);\n }\n\n // ========== Export/Import ==========\n\n async exportSession(key: string, format: ExportFormat): Promise<string> {\n return this.store.exportSession(key, format);\n }\n\n // ========== Statistics ==========\n\n async getStats(): Promise<GlobalSessionStats> {\n return this.store.getStats();\n }\n\n // ========== Maintenance ==========\n\n async archiveOldSessions(olderThanDays: number): Promise<number> {\n const count = await this.store.archiveOld(olderThanDays);\n log.info({ count, olderThanDays }, 'Archived old sessions');\n return count;\n }\n\n // ========== Event Helpers ==========\n\n onSessionCreated(callback: (metadata: SessionMetadata) => void): void {\n this.on('sessionCreated', callback);\n }\n\n onSessionUpdated(callback: (data: { key: string; name?: string; tags?: string[] }) => void): void {\n this.on('sessionUpdated', callback);\n }\n\n onSessionDeleted(callback: (data: { key: string }) => void): void {\n this.on('sessionDeleted', callback);\n }\n\n onSessionArchived(callback: (data: { key: string }) => void): void {\n this.on('sessionArchived', callback);\n }\n\n onSessionRestored(callback: (data: { key: string }) => void): void {\n this.on('sessionRestored', callback);\n }\n\n onSessionPinned(callback: (data: { key: string }) => void): void {\n this.on('sessionPinned', callback);\n }\n\n onSessionUnpinned(callback: (data: { key: string }) => void): void {\n this.on('sessionUnpinned', callback);\n }\n\n onSessionStatusChanged(callback: (data: { key: string; status: SessionStatus }) => void): void {\n this.on('sessionStatusChanged', callback);\n }\n\n onSessionAccessed(callback: (data: { key: string }) => void): void {\n this.on('sessionAccessed', callback);\n }\n\n // ========== Store delegation (messages, compaction) ==========\n\n /** Load messages for a session key */\n async loadMessages(key: string) {\n return this.store.loadMessages(key);\n }\n\n /** Wrapped transcript document (stable id, compaction history); null if missing or not a valid envelope. */\n async loadTranscriptDocument(key: string): Promise<XopcSessionTranscriptV1 | null> {\n return this.store.loadTranscriptDocument(key);\n }\n\n /**\n * Runtime turns must use PiTranscriptManager.appendMessage; this entry point\n * is reserved for compaction, tests, and admin tools.\n */\n async saveMessages(key: string, messages: any[]) {\n return this.store.saveMessages(key, messages);\n }\n\n /**\n * Append `kind: 'context'` transcript row (persisted, excluded from {@link loadMessages} / LLM).\n */\n async appendTranscriptContextEntry(\n key: string,\n entry: Omit<XopcTranscriptContextEntry, 'kind'> & Partial<Pick<XopcTranscriptContextEntry, 'kind'>>,\n ): Promise<void> {\n await this.store.appendTranscriptContextEntry(key, entry);\n this.emit('sessionUpdated', { key });\n }\n\n /** Delete session data */\n async delete(key: string): Promise<void> {\n await this.store.delete(key);\n }\n\n /** Archive transcript and start a new session id for the same key. */\n async resetSession(\n key: string,\n ): Promise<{ sessionId: string; previousSessionId: string } | null> {\n const result = await this.store.reset(key);\n if (result) {\n this.emit('sessionUpdated', { key });\n }\n return result;\n }\n\n /** Token/window stats for a message list */\n getWindowStats(messages: any[]) {\n return this.store.getWindowStats(messages);\n }\n\n /** Prepare compaction run */\n prepareCompaction(key: string, messages: any[], contextWindow: number) {\n return this.store.prepareCompaction(key, messages, contextWindow);\n }\n\n /** Compact session messages */\n compact(\n key: string,\n messages: any[],\n contextWindow: number,\n instructions?: string,\n force?: boolean,\n ): Promise<CompactionResult> {\n return this.store.compact(key, messages, contextWindow, instructions, force);\n }\n\n /** Compaction stats for a session */\n async getCompactionStats(key: string) {\n return this.store.getCompactionStats(key);\n }\n\n /** List pre-compaction transcript snapshots (newest first). */\n listCompactionCheckpoints(key: string) {\n return this.store.listCompactionCheckpoints(key);\n }\n\n getCompactionCheckpointDetail(key: string, checkpointId: string) {\n return this.store.getCompactionCheckpointDetail(key, checkpointId);\n }\n\n restoreCompactionCheckpoint(key: string, checkpointId: string) {\n return this.store.restoreCompactionCheckpoint(key, checkpointId);\n }\n\n /** Estimate token usage for messages */\n async estimateTokenUsage(key: string, messages: any[]): Promise<number> {\n return this.store.estimateTokens(messages);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","names":["EventEmitter"],"sources":["../../../src/session/manager.ts"],"sourcesContent":["// Session manager - high-level session management service\n\nimport EventEmitter from 'events';\nimport { createLogger } from '../utils/logger.js';\nimport { SessionStore } from './store.js';\nimport type {\n SessionMetadata,\n SessionDetail,\n SessionListQuery,\n PaginatedResult,\n GlobalSessionStats,\n ExportFormat,\n SessionStatus,\n} from './types.js';\nimport type { Message } from './types.js';\nimport type { CompactionConfig, CompactionResult } from '../agent/memory/compaction.js';\nimport type { XopcSessionTranscriptV1 } from './transcript-format.js';\nimport type { XopcTranscriptContextEntry } from './session-context-for-llm.js';\nimport { applySessionPatchToMetadata, type SessionPatchBody } from './patch-metadata.js';\nimport type { WindowConfig } from '../agent/memory/window.js';\nimport type { Config } from '../config/schema.js';\n\nconst log = createLogger('SessionIndex');\n\nexport interface SessionIndexConfig {\n config: Config;\n windowConfig?: Partial<WindowConfig>;\n compactionConfig?: Partial<CompactionConfig>;\n}\n\nexport class SessionIndex extends EventEmitter {\n private store: SessionStore;\n\n constructor(config: SessionIndexConfig) {\n super();\n this.store = new SessionStore(\n {\n config: config.config,\n },\n config.windowConfig,\n config.compactionConfig\n );\n }\n\n async initialize(): Promise<void> {\n await this.store.initialize();\n this.emit('ready');\n }\n\n /** Low-level store (e.g. cron resolving weixin delivery from session index). */\n getStore(): SessionStore {\n return this.store;\n }\n\n // ========== CRUD Operations ==========\n\n async listSessions(query?: SessionListQuery): Promise<PaginatedResult<SessionMetadata>> {\n return this.store.list(query);\n }\n\n /**\n * List all subagent sessions.\n * Subagent sessions have keys starting with 'subagent:'.\n */\n async listSubagents(query: SessionListQuery = {}): Promise<PaginatedResult<SessionMetadata>> {\n // Filter for subagent sessions only\n const subagentQuery: SessionListQuery = {\n ...query,\n search: query.search ? `subagent:${query.search}` : 'subagent:',\n };\n \n const result = await this.store.list(subagentQuery);\n \n // Additional filtering to ensure only subagent sessions\n const subagentSessions = result.items.filter((s) => s.key.startsWith('subagent:'));\n \n return {\n ...result,\n items: subagentSessions,\n total: subagentSessions.length,\n hasMore: false, // Simplified for now\n };\n }\n\n async getSession(\n key: string,\n options?: { includeTranscriptSummary?: boolean; includeTranscriptRows?: boolean },\n ): Promise<SessionDetail | null> {\n const session = await this.store.get(key, options);\n if (session) {\n this.emit('sessionAccessed', { key });\n }\n return session;\n }\n\n async getSessionMessagePage(\n key: string,\n options?: {\n offset?: number;\n limit?: number;\n before?: string;\n includeTranscriptSummary?: boolean;\n includeTranscriptRows?: boolean;\n },\n ): Promise<{\n session: SessionDetail;\n pagination: {\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n before?: string;\n nextBeforeCursor?: string;\n };\n } | null> {\n const result = await this.store.getMessagePage(key, options);\n if (result) {\n this.emit('sessionAccessed', { key });\n }\n return result;\n }\n\n /**\n * OpenClaw-style `sessions.patch`: partial metadata (name, tags, customData shallow merge).\n */\n async patchSession(\n key: string,\n patch: SessionPatchBody,\n ): Promise<{ ok: true } | { ok: false; error: string }> {\n const meta = await this.store.getMetadata(key);\n if (!meta) {\n return { ok: false, error: 'Session not found' };\n }\n const updates = applySessionPatchToMetadata(meta, patch);\n if (Object.keys(updates).length === 0) {\n return { ok: true };\n }\n await this.store.updateMetadata(key, updates);\n this.emit('sessionUpdated', { key });\n return { ok: true };\n }\n\n async getSessionMetadata(key: string): Promise<SessionMetadata | null> {\n return this.store.getMetadata(key);\n }\n\n async deleteSession(key: string): Promise<boolean> {\n const result = await this.store.delete(key);\n if (result) {\n this.emit('sessionDeleted', { key });\n }\n return result;\n }\n\n async deleteSessions(keys: string[]): Promise<{ success: string[]; failed: string[] }> {\n const result = await this.store.deleteMany(keys);\n for (const key of result.success) {\n this.emit('sessionDeleted', { key });\n }\n return result;\n }\n\n // ========== Metadata Updates ==========\n\n async renameSession(key: string, name: string): Promise<void> {\n const existing = await this.store.getMetadata(key);\n await this.store.updateMetadata(key, {\n name,\n customData: { ...(existing?.customData ?? {}), titleSource: 'user' },\n });\n this.emit('sessionUpdated', { key, name });\n }\n\n /** Partial metadata update (caller merges nested fields like `customData` when needed). */\n async updateSessionMetadata(key: string, updates: Partial<SessionMetadata>): Promise<void> {\n await this.store.updateMetadata(key, updates);\n this.emit('sessionUpdated', { key });\n }\n\n async tagSession(key: string, tags: string[]): Promise<void> {\n const existing = await this.store.getMetadata(key);\n if (!existing) {\n throw new Error(`Session not found: ${key}`);\n }\n\n // Merge tags, remove duplicates\n const mergedTags = [...new Set([...existing.tags, ...tags])];\n await this.store.updateMetadata(key, { tags: mergedTags });\n this.emit('sessionUpdated', { key, tags: mergedTags });\n }\n\n async untagSession(key: string, tags: string[]): Promise<void> {\n const existing = await this.store.getMetadata(key);\n if (!existing) {\n throw new Error(`Session not found: ${key}`);\n }\n\n const filteredTags = existing.tags.filter((t) => !tags.includes(t));\n await this.store.updateMetadata(key, { tags: filteredTags });\n this.emit('sessionUpdated', { key, tags: filteredTags });\n }\n\n async setSessionTags(key: string, tags: string[]): Promise<void> {\n await this.store.updateMetadata(key, { tags: [...new Set(tags)] });\n this.emit('sessionUpdated', { key, tags });\n }\n\n // ========== Status Management ==========\n\n async archiveSession(key: string): Promise<void> {\n await this.store.archive(key);\n this.emit('sessionArchived', { key });\n }\n\n async unarchiveSession(key: string): Promise<void> {\n await this.store.unarchive(key);\n this.emit('sessionRestored', { key });\n }\n\n async pinSession(key: string): Promise<void> {\n await this.store.pin(key);\n this.emit('sessionPinned', { key });\n }\n\n async unpinSession(key: string): Promise<void> {\n await this.store.unpin(key);\n this.emit('sessionUnpinned', { key });\n }\n\n async setSessionStatus(key: string, status: SessionStatus): Promise<void> {\n await this.store.setStatus(key, status);\n this.emit('sessionStatusChanged', { key, status });\n }\n\n // ========== Search ==========\n\n async searchSessions(query: string): Promise<SessionMetadata[]> {\n const result = await this.store.list({ search: query, limit: 100 });\n return result.items;\n }\n\n async searchInSession(key: string, keyword: string): Promise<Message[]> {\n return this.store.searchInSession(key, keyword);\n }\n\n // ========== Export/Import ==========\n\n async exportSession(key: string, format: ExportFormat): Promise<string> {\n return this.store.exportSession(key, format);\n }\n\n // ========== Statistics ==========\n\n async getStats(): Promise<GlobalSessionStats> {\n return this.store.getStats();\n }\n\n // ========== Maintenance ==========\n\n async archiveOldSessions(olderThanDays: number): Promise<number> {\n const count = await this.store.archiveOld(olderThanDays);\n log.info({ count, olderThanDays }, 'Archived old sessions');\n return count;\n }\n\n // ========== Event Helpers ==========\n\n onSessionCreated(callback: (metadata: SessionMetadata) => void): void {\n this.on('sessionCreated', callback);\n }\n\n onSessionUpdated(callback: (data: { key: string; name?: string; tags?: string[] }) => void): void {\n this.on('sessionUpdated', callback);\n }\n\n onSessionDeleted(callback: (data: { key: string }) => void): void {\n this.on('sessionDeleted', callback);\n }\n\n onSessionArchived(callback: (data: { key: string }) => void): void {\n this.on('sessionArchived', callback);\n }\n\n onSessionRestored(callback: (data: { key: string }) => void): void {\n this.on('sessionRestored', callback);\n }\n\n onSessionPinned(callback: (data: { key: string }) => void): void {\n this.on('sessionPinned', callback);\n }\n\n onSessionUnpinned(callback: (data: { key: string }) => void): void {\n this.on('sessionUnpinned', callback);\n }\n\n onSessionStatusChanged(callback: (data: { key: string; status: SessionStatus }) => void): void {\n this.on('sessionStatusChanged', callback);\n }\n\n onSessionAccessed(callback: (data: { key: string }) => void): void {\n this.on('sessionAccessed', callback);\n }\n\n // ========== Store delegation (messages, compaction) ==========\n\n /** Load messages for a session key */\n async loadMessages(key: string) {\n return this.store.loadMessages(key);\n }\n\n /** Wrapped transcript document (stable id, compaction history); null if missing or not a valid envelope. */\n async loadTranscriptDocument(key: string): Promise<XopcSessionTranscriptV1 | null> {\n return this.store.loadTranscriptDocument(key);\n }\n\n /**\n * Runtime turns must use PiTranscriptManager.appendMessage; this entry point\n * is reserved for compaction, tests, and admin tools.\n */\n async saveMessages(key: string, messages: any[]) {\n return this.store.saveMessages(key, messages);\n }\n\n /**\n * Append `kind: 'context'` transcript row (persisted, excluded from {@link loadMessages} / LLM).\n */\n async appendTranscriptContextEntry(\n key: string,\n entry: Omit<XopcTranscriptContextEntry, 'kind'> & Partial<Pick<XopcTranscriptContextEntry, 'kind'>>,\n ): Promise<void> {\n await this.store.appendTranscriptContextEntry(key, entry);\n this.emit('sessionUpdated', { key });\n }\n\n /** Delete session data */\n async delete(key: string): Promise<void> {\n await this.store.delete(key);\n }\n\n /** Archive transcript and start a new session id for the same key. */\n async resetSession(\n key: string,\n ): Promise<{ sessionId: string; previousSessionId: string } | null> {\n const result = await this.store.reset(key);\n if (result) {\n this.emit('sessionUpdated', { key });\n }\n return result;\n }\n\n /** Token/window stats for a message list */\n getWindowStats(messages: any[]) {\n return this.store.getWindowStats(messages);\n }\n\n /** Prepare compaction run */\n prepareCompaction(key: string, messages: any[], contextWindow: number) {\n return this.store.prepareCompaction(key, messages, contextWindow);\n }\n\n /** Compact session messages */\n compact(\n key: string,\n messages: any[],\n contextWindow: number,\n instructions?: string,\n force?: boolean,\n ): Promise<CompactionResult> {\n return this.store.compact(key, messages, contextWindow, instructions, force);\n }\n\n /** Compaction stats for a session */\n async getCompactionStats(key: string) {\n return this.store.getCompactionStats(key);\n }\n\n /** List pre-compaction transcript snapshots (newest first). */\n listCompactionCheckpoints(key: string) {\n return this.store.listCompactionCheckpoints(key);\n }\n\n getCompactionCheckpointDetail(key: string, checkpointId: string) {\n return this.store.getCompactionCheckpointDetail(key, checkpointId);\n }\n\n restoreCompactionCheckpoint(key: string, checkpointId: string) {\n return this.store.restoreCompactionCheckpoint(key, checkpointId);\n }\n\n /** Estimate token usage for messages */\n async estimateTokenUsage(key: string, messages: any[]): Promise<number> {\n return this.store.estimateTokens(messages);\n }\n}\n"],"mappings":"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"}
|