@xopcai/xopc 0.0.117 → 0.0.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -24
- package/README.zh-CN.md +46 -42
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BBLhJ2C6.js → agent-avatar-dicebear-CU8J6zou.js} +1 -1
- package/dist/gateway/static/root/assets/agents-B0hkpLhP.js +2 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-B9vfYoEr.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-ClOzIO24.js +1 -0
- package/dist/gateway/static/root/assets/{apps-page-DdDx0V4z.js → apps-page-DU0dz9Zo.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-DZsVqMhU.js → archive-plugin-BkVIgZzA.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CIol6JWX.js → attachment-load-CaCMWh1D.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-DhGDpKP3.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-CTedroVo.js +1 -0
- package/dist/gateway/static/root/assets/{binary-plugins-B3UauMfp.js → binary-plugins-B4TO_bsn.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-2HJoFchH.js → block-editor-DJRWwWNI.js} +6 -6
- package/dist/gateway/static/root/assets/browser-settings-page-FCDwOOBK.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-Befi89CL.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-_G8eb2vJ.js +1 -0
- package/dist/gateway/static/root/assets/channel-recipient-api-BNSuJb5f.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-C3d5JBJX.js +1 -0
- package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-yaUNvt5u.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
- package/dist/gateway/static/root/assets/dreaming-settings-DNrdg1Ve.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DX5WRE_t.js → extension-debug-page-DYh402XV.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Buah7Bw-.js → extension-page-Cr_TizrN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DuroLVnf.js → extension-settings-page-BU1KoKRj.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-B5zdl27C.js → fetch-Y7AEX4H3.js} +1 -1
- package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-gT4ZhE7h.js → gateway-config-api-RbMmAOpX.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-C79wkXef.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B3kL8KGY.js → gateway-startup-retry-DiD_Tx4N.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-9paXuHdo.js +1 -0
- package/dist/gateway/static/root/assets/{goals-config-api-AR-fVh0P.js → goals-config-api-DqxVi0p5.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-Cpb21ezg.js → goals-page-CS0R-Af2.js} +2 -2
- package/dist/gateway/static/root/assets/goals-settings-CSuzZ8Ae.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-DXPaYJm3.js +1 -0
- package/dist/gateway/static/root/assets/index-BoKafJIZ.js +191 -0
- package/dist/gateway/static/root/assets/index-CArhCcYn.css +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Dvg53qnd.js +1 -0
- package/dist/gateway/static/root/assets/{logs-page-DefCgF4o.js → logs-page-DLXPcksQ.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-ChbR9LGO.js → markdown-split-CpHxbtWJ.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-B82oP80n.js → media-plugins-SFPQRSxq.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CrDHEbss.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BDF2iyRk.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-CSb_hwig.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-CDknITM3.js → note-image-lightbox-BUYURRgn.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-BsIBSFyZ.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DV3xQsWB.js → preview-open-alternatives-BHz9iWYA.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwzSovcS.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BODCXnvY.js → save-bar-controls-CefkOlRg.js} +1 -1
- package/dist/gateway/static/root/assets/schedule-field-CmTRoOcE.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-qtfEI6QM.js → schema-form-FMKv1vGu.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-PHmX-NmA.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BRAeKJN4.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BHZKjVcS.js → settings-collapsible-section-BouO6JTi.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-5i35D-J1.js → settings-form-section-D-4lBl6X.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-KKrbFjy8.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-layout-BJ4Gsef5.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-CrUjHPQo.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-B0H63tDv.js → share-preview-page-BDy2btRN.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-B18OBmH5.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-C28-2uKQ.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Bm2ebkwl.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-CRngrlnZ.js +1 -0
- package/dist/gateway/static/root/assets/typed-models-lib-BltBc0b-.js +1 -0
- package/dist/gateway/static/root/assets/{use-channel-catalog-BCjP_VHb.js → use-channel-catalog-CjN-51e6.js} +1 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-DJ1dKwZy.js +1 -0
- package/dist/gateway/static/root/assets/utils-B5M5-YvK.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-CeEevm7z.js +1 -0
- package/dist/gateway/static/root/assets/{voice-player-store-BlF9V05n.js → voice-player-store-B7ykUlHM.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-C4PzUQjB.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-BL84_-Ky.js +18 -0
- package/dist/gateway/static/root/index.html +6 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +4 -5
- package/dist/src/agent/agent-manager.js +6 -9
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.js +0 -2
- package/dist/src/agent/agent-scope.js.map +1 -1
- package/dist/src/agent/background-review/prompts.d.ts +2 -2
- package/dist/src/agent/background-review/prompts.js +2 -2
- package/dist/src/agent/background-review/prompts.js.map +1 -1
- package/dist/src/agent/background-review/settings.d.ts +1 -1
- package/dist/src/agent/background-review/settings.js +7 -8
- package/dist/src/agent/background-review/settings.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +1 -0
- package/dist/src/agent/bootstrap/bootstrap-cache.js +4 -3
- package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-files.d.ts +4 -0
- package/dist/src/agent/bootstrap/bootstrap-files.js +4 -3
- package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +4 -2
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +2 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +17 -16
- package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/types.d.ts +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
- package/dist/src/agent/context/workspace.d.ts +4 -2
- package/dist/src/agent/context/workspace.js +5 -4
- package/dist/src/agent/context/workspace.js.map +1 -1
- package/dist/src/agent/embedded/run-for-session.js +106 -15
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/fallback/candidates.d.ts +0 -8
- package/dist/src/agent/fallback/candidates.js +10 -11
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/index.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
- package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/progress.d.ts +0 -1
- package/dist/src/agent/lifecycle/progress.js +1 -6
- package/dist/src/agent/lifecycle/progress.js.map +1 -1
- package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
- package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
- package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
- package/dist/src/agent/memory/builtin-memory-store.d.ts +4 -2
- package/dist/src/agent/memory/builtin-memory-store.js +11 -6
- package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
- package/dist/src/agent/memory/builtin-provider.js +36 -7
- package/dist/src/agent/memory/builtin-provider.js.map +1 -1
- package/dist/src/agent/memory/candidate-extractor.d.ts +6 -0
- package/dist/src/agent/memory/candidate-extractor.js +60 -0
- package/dist/src/agent/memory/candidate-extractor.js.map +1 -0
- package/dist/src/agent/memory/manager.d.ts +2 -1
- package/dist/src/agent/memory/manager.js +27 -3
- package/dist/src/agent/memory/manager.js.map +1 -1
- package/dist/src/agent/memory/memory-config.js +3 -0
- package/dist/src/agent/memory/memory-config.js.map +1 -1
- package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -1
- package/dist/src/agent/memory/types.d.ts +27 -4
- package/dist/src/agent/middleware/self-verify.d.ts +0 -1
- package/dist/src/agent/middleware/self-verify.js +0 -2
- package/dist/src/agent/middleware/self-verify.js.map +1 -1
- package/dist/src/agent/models/index.d.ts +1 -1
- package/dist/src/agent/models/manager.d.ts +4 -20
- package/dist/src/agent/models/manager.js +9 -126
- package/dist/src/agent/models/manager.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/prompt/memory/index.d.ts +4 -2
- package/dist/src/agent/prompt/memory/index.js +18 -12
- package/dist/src/agent/prompt/memory/index.js.map +1 -1
- package/dist/src/agent/prompt/sections/memory-skills.js +1 -1
- package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +2 -2
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +4 -31
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/subagent-context.js +1 -1
- package/dist/src/agent/prompt/subagent-context.js.map +1 -1
- package/dist/src/agent/prompt/types.d.ts +1 -1
- package/dist/src/agent/reply/post-compaction-context.js +1 -3
- package/dist/src/agent/reply/post-compaction-context.js.map +1 -1
- package/dist/src/agent/reply/startup-context.js +1 -5
- package/dist/src/agent/reply/startup-context.js.map +1 -1
- package/dist/src/agent/service.d.ts +4 -12
- package/dist/src/agent/service.js +10 -48
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +2 -2
- package/dist/src/agent/session/session-config-service.d.ts +11 -11
- package/dist/src/agent/session/session-config-service.js +14 -14
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +3 -2
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/starter-agents.js +12 -12
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +14 -0
- package/dist/src/agent/tools/automation-tool.js +102 -0
- package/dist/src/agent/tools/automation-tool.js.map +1 -0
- package/dist/src/agent/tools/curated-memory-tool.js +57 -2
- package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
- package/dist/src/agent/tools/delegate-tool.js +1 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +3 -3
- package/dist/src/agent/tools/factory.js +2 -2
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -1
- package/dist/src/agent/tools/index.js +2 -2
- package/dist/src/agent/tools/web-extract.js +6 -8
- package/dist/src/agent/tools/web-extract.js.map +1 -1
- package/dist/src/agent-manifest/index.js +2 -2
- package/dist/src/agent-manifest/resolver.d.ts +4 -2
- package/dist/src/agent-manifest/resolver.js +6 -3
- package/dist/src/agent-manifest/resolver.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +238 -0
- package/dist/src/agent-manifest/schema.js +16 -5
- package/dist/src/agent-manifest/schema.js.map +1 -1
- package/dist/src/agent-manifest/validator.d.ts +3 -2
- package/dist/src/agent-manifest/validator.js +2 -1
- package/dist/src/agent-manifest/validator.js.map +1 -1
- package/dist/src/ai-assist/text-assist.d.ts +1 -1
- package/dist/src/ai-assist/text-assist.js +56 -0
- package/dist/src/ai-assist/text-assist.js.map +1 -1
- package/dist/src/auth/profiles/store.js.map +1 -1
- package/dist/src/automations/api/routes.d.ts +3 -0
- package/dist/src/automations/api/routes.js +193 -0
- package/dist/src/automations/api/routes.js.map +1 -0
- package/dist/src/automations/domain/index.d.ts +3 -0
- package/dist/src/automations/domain/index.js +3 -0
- package/dist/src/automations/domain/schedule.d.ts +4 -0
- package/dist/src/automations/domain/schedule.js +37 -0
- package/dist/src/automations/domain/schedule.js.map +1 -0
- package/dist/src/automations/domain/types.d.ts +160 -0
- package/dist/src/automations/domain/validation.d.ts +370 -0
- package/dist/src/automations/domain/validation.js +149 -0
- package/dist/src/automations/domain/validation.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
- package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
- package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
- package/dist/src/automations/draft/automation-draft-service.js +135 -0
- package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
- package/dist/src/automations/draft/automation-draft-validator.js +105 -0
- package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
- package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
- package/dist/src/automations/draft/index.d.ts +3 -0
- package/dist/src/automations/draft/index.js +3 -0
- package/dist/src/automations/index.d.ts +3 -0
- package/dist/src/automations/index.js +8 -0
- package/dist/src/automations/product-events.d.ts +5 -0
- package/dist/src/automations/product-events.js +21 -0
- package/dist/src/automations/product-events.js.map +1 -0
- package/dist/src/automations/service/action-executor.d.ts +9 -0
- package/dist/src/automations/service/action-executor.js +157 -0
- package/dist/src/automations/service/action-executor.js.map +1 -0
- package/dist/src/automations/service/automation-service.d.ts +54 -0
- package/dist/src/automations/service/automation-service.js +404 -0
- package/dist/src/automations/service/automation-service.js.map +1 -0
- package/dist/src/automations/service/index.d.ts +2 -0
- package/dist/src/automations/service/index.js +3 -0
- package/dist/src/automations/storage/automation-repository.d.ts +6 -0
- package/dist/src/automations/storage/automation-repository.js +61 -0
- package/dist/src/automations/storage/automation-repository.js.map +1 -0
- package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
- package/dist/src/automations/storage/automation-run-repository.js +130 -0
- package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
- package/dist/src/automations/storage/index.d.ts +2 -0
- package/dist/src/automations/storage/index.js +3 -0
- package/dist/src/channels/pipeline.d.ts +1 -1
- package/dist/src/channels/pipeline.js.map +1 -1
- package/dist/src/channels/plugin-types.d.ts +3 -0
- package/dist/src/chat-commands/agent-edit.js +0 -1
- package/dist/src/chat-commands/agent-edit.js.map +1 -1
- package/dist/src/chat-commands/builtins/model.js +2 -2
- package/dist/src/chat-commands/builtins/model.js.map +1 -1
- package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
- package/dist/src/cli/command-catalog.js +0 -39
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +0 -1
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.d.ts +1 -1
- package/dist/src/cli/command-manifest.js +1 -5
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agents.js +7 -6
- package/dist/src/cli/commands/agents.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
- package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
- package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -0
- package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +0 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
- package/dist/src/cli/commands/doctor/flow.js +2 -2
- package/dist/src/cli/commands/doctor/flow.js.map +1 -1
- package/dist/src/cli/commands/gateway/call.js +2 -2
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/init.js +33 -14
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/models.js +13 -31
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/model.js +17 -10
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +2 -2
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/tui.js +26 -4
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +10 -5
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/registry.js +1 -1
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/cli/templates.d.ts +1 -1
- package/dist/src/cli/templates.js +1 -11
- package/dist/src/cli/templates.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -0
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/commands/agents.config.d.ts +9 -0
- package/dist/src/commands/agents.config.js +42 -12
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +5 -3
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.js +3 -5
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/config-surface.d.ts +3 -0
- package/dist/src/config/index.d.ts +0 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/paths.d.ts +8 -10
- package/dist/src/config/paths.js +16 -16
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +0 -1
- package/dist/src/config/profile.js.map +1 -1
- package/dist/src/config/rules.js +0 -5
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +45 -44
- package/dist/src/config/schema.js +68 -52
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +0 -12
- package/dist/src/config/web-patch.js +2 -29
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/extensions/api.d.ts +2 -0
- package/dist/src/extensions/api.js +10 -0
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
- package/dist/src/extensions/extension-registry-impl.js +8 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -1
- package/dist/src/extensions/loader.d.ts +3 -3
- package/dist/src/extensions/loader.js +3 -3
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/sdk/testing.d.ts +2 -0
- package/dist/src/extensions/sdk/testing.js +7 -0
- package/dist/src/extensions/sdk/testing.js.map +1 -1
- package/dist/src/extensions/types/core.d.ts +10 -1
- package/dist/src/extensions/types/index.d.ts +1 -1
- package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +8 -0
- package/dist/src/gateway/agents-admin.js +63 -34
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
- package/dist/src/gateway/capability-presets-admin.js +19 -10
- package/dist/src/gateway/capability-presets-admin.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +9 -2
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
- package/dist/src/gateway/global-defaults-admin.d.ts +36 -0
- package/dist/src/gateway/global-defaults-admin.js +146 -0
- package/dist/src/gateway/global-defaults-admin.js.map +1 -0
- package/dist/src/gateway/heartbeat/service.d.ts +0 -2
- package/dist/src/gateway/heartbeat/service.js +0 -7
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +33 -1
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +4 -5
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +12 -6
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +27 -37
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/global-defaults.d.ts +3 -0
- package/dist/src/gateway/hono/routes/global-defaults.js +61 -0
- package/dist/src/gateway/hono/routes/global-defaults.js.map +1 -0
- package/dist/src/gateway/hono/routes/home.d.ts +2 -2
- package/dist/src/gateway/hono/routes/home.js +34 -25
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +21 -9
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/memory.js +75 -4
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
- package/dist/src/gateway/hono/routes/migrations.js +35 -0
- package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +14 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/run-loop.js +2 -0
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/security/operator-scopes.js +5 -1
- package/dist/src/gateway/security/operator-scopes.js.map +1 -1
- package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
- package/dist/src/gateway/service/config-coordinator.js +14 -8
- package/dist/src/gateway/service/config-coordinator.js.map +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +4 -4
- package/dist/src/gateway/service/marketplace-service.js +11 -7
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +2 -1
- package/dist/src/gateway/service/sessions-api.js +6 -1
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +7 -3
- package/dist/src/gateway/service.js +61 -27
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-service.js +45 -4
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
- package/dist/src/migrations/config/default-capability-preset.js +135 -0
- package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
- package/dist/src/migrations/index.d.ts +4 -0
- package/dist/src/migrations/index.js +4 -0
- package/dist/src/migrations/registry.d.ts +8 -0
- package/dist/src/migrations/registry.js +18 -0
- package/dist/src/migrations/registry.js.map +1 -0
- package/dist/src/migrations/runner.d.ts +17 -0
- package/dist/src/migrations/runner.js +191 -0
- package/dist/src/migrations/runner.js.map +1 -0
- package/dist/src/migrations/types.d.ts +34 -0
- package/dist/src/notes/service.js +27 -2
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/providers/index.d.ts +4 -5
- package/dist/src/providers/index.js +16 -16
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/model-registry.d.ts +0 -1
- package/dist/src/providers/model-registry.js +0 -3
- package/dist/src/providers/model-registry.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
- package/dist/src/routing/resolve-tui-session-key.js +14 -3
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
- package/dist/src/session/session-workspace.js +2 -7
- package/dist/src/session/session-workspace.js.map +1 -1
- package/dist/src/session/store.js +0 -5
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/transcript-outline.d.ts +47 -0
- package/dist/src/session/transcript-outline.js +481 -0
- package/dist/src/session/transcript-outline.js.map +1 -0
- package/dist/src/storage/sqlite/index.d.ts +1 -3
- package/dist/src/storage/sqlite/index.js +2 -4
- package/dist/src/storage/sqlite/memory-index-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/memory-index-repository.js +15 -14
- package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +44 -1
- package/dist/src/storage/sqlite/memory-records-repository.js +164 -20
- package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/014_memory_record_governance.sql +10 -0
- package/dist/src/storage/sqlite/migrations/015_memory_trace_feedback.sql +4 -0
- package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
- package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
- package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +56 -46
- package/dist/src/tui/backends/embedded-backend.d.ts +9 -0
- package/dist/src/tui/backends/embedded-backend.js +55 -27
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -0
- package/dist/src/tui/backends/gateway-sse-backend.js +30 -3
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/components/tui-header.d.ts +0 -1
- package/dist/src/tui/components/tui-header.js +3 -8
- package/dist/src/tui/components/tui-header.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +4 -0
- package/dist/src/tui/tui-commands.d.ts +5 -0
- package/dist/src/tui/tui-commands.js +43 -0
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-startup-resources.js +2 -1
- package/dist/src/tui/tui-startup-resources.js.map +1 -1
- package/dist/src/tui/tui-startup-text.js +12 -12
- package/dist/src/tui/tui-startup-text.js.map +1 -1
- package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
- package/dist/src/tui/tui-transcript-tree.js +17 -257
- package/dist/src/tui/tui-transcript-tree.js.map +1 -1
- package/dist/src/tui/tui-types.d.ts +2 -0
- package/dist/src/tui/tui-types.js.map +1 -1
- package/dist/src/tui/tui.js +11 -3
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/workflows/domain/index.js +1 -1
- package/dist/src/workflows/domain/run.d.ts +7 -7
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/index.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
- package/dist/src/workflows/service/workflow-run-service.js +31 -9
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
- package/package.json +4 -2
- package/dist/gateway/static/root/assets/agents-C6xgagZd.js +0 -71
- package/dist/gateway/static/root/assets/app-management-settings-panel-CBpLONvG.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-CGcc54yj.js +0 -1
- package/dist/gateway/static/root/assets/browser-settings-page-CUOO-PQk.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-api-XQoMTI0A.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CfqF-kGr.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BYyRzsex.js +0 -1
- package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DIvEz4NX.js +0 -2
- package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-R41aQCX9.js +0 -1
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-D97nFqQD.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-Bceaw1PG.js +0 -1
- package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
- package/dist/gateway/static/root/assets/format-interval-label-Dn_QKIqb.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-iISWAZRm.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DCUROLMQ.js +0 -1
- package/dist/gateway/static/root/assets/goals-settings-CPAuFwoD.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-D7bKFEeO.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CC69vNx0.js +0 -1
- package/dist/gateway/static/root/assets/index-CwhK8qCh.js +0 -122
- package/dist/gateway/static/root/assets/index-CyfhARL-.css +0 -1
- package/dist/gateway/static/root/assets/interval-presets-0DtsnxE0.js +0 -1
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-BPREtN8B.js +0 -1
- package/dist/gateway/static/root/assets/messages-Cf1O9JB0.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-DmKiIihT.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-CxxfLRJZ.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-X2slSx7V.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BvmUWqgu.js +0 -1
- package/dist/gateway/static/root/assets/schedule-field-CgJSCD3B.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B0yESuuL.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-q2M8RKOo.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-CGozabLD.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-FoOSe6nU.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Cy5zWyYQ.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DaZNFro9.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-CnwtUzvw.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-DXs2VmBt.js +0 -1
- package/dist/gateway/static/root/assets/typed-models-lib-4gPuydz_.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DvKiOglO.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-CAVZcONQ.js +0 -18
- package/dist/src/agent/context/workspace-templates/USER.md +0 -24
- package/dist/src/agent/fallback/error.d.ts +0 -22
- package/dist/src/agent/fallback/error.js +0 -32
- package/dist/src/agent/fallback/error.js.map +0 -1
- package/dist/src/agent/fallback/index.d.ts +0 -5
- package/dist/src/agent/fallback/index.js +0 -9
- package/dist/src/agent/fallback/index.js.map +0 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
- package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
- package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
- package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
- package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
- package/dist/src/agent/tools/cronjob-tool.js +0 -274
- package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
- package/dist/src/cli/commands/cron-cli.d.ts +0 -2
- package/dist/src/cli/commands/cron-cli.js +0 -15
- package/dist/src/cli/commands/cron-cli.js.map +0 -1
- package/dist/src/cli/commands/cron.d.ts +0 -4
- package/dist/src/cli/commands/cron.js +0 -188
- package/dist/src/cli/commands/cron.js.map +0 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
- package/dist/src/cron/execution-types.d.ts +0 -42
- package/dist/src/cron/executor.d.ts +0 -67
- package/dist/src/cron/executor.js +0 -669
- package/dist/src/cron/executor.js.map +0 -1
- package/dist/src/cron/index.d.ts +0 -7
- package/dist/src/cron/index.js +0 -7
- package/dist/src/cron/job-content.d.ts +0 -5
- package/dist/src/cron/job-content.js +0 -15
- package/dist/src/cron/job-content.js.map +0 -1
- package/dist/src/cron/run-log-store.d.ts +0 -12
- package/dist/src/cron/run-log-store.js +0 -58
- package/dist/src/cron/run-log-store.js.map +0 -1
- package/dist/src/cron/schedule.d.ts +0 -10
- package/dist/src/cron/schedule.js +0 -85
- package/dist/src/cron/schedule.js.map +0 -1
- package/dist/src/cron/service.d.ts +0 -58
- package/dist/src/cron/service.js +0 -419
- package/dist/src/cron/service.js.map +0 -1
- package/dist/src/cron/types.d.ts +0 -183
- package/dist/src/cron/validation.d.ts +0 -500
- package/dist/src/cron/validation.js +0 -192
- package/dist/src/cron/validation.js.map +0 -1
- package/dist/src/cron/workflow-run-completion.d.ts +0 -23
- package/dist/src/cron/workflow-run-completion.js +0 -72
- package/dist/src/cron/workflow-run-completion.js.map +0 -1
- package/dist/src/extensions/types/phase4.js +0 -1
- package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
- package/dist/src/gateway/hono/routes/cron.js +0 -109
- package/dist/src/gateway/hono/routes/cron.js.map +0 -1
- package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
- package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
- package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
- package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
- package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
- package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
- /package/dist/src/{cron → automations/domain}/types.js +0 -0
- /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
- /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
- /package/dist/src/{cron/execution-types.js → migrations/types.js} +0 -0
|
@@ -5,12 +5,7 @@ import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
|
|
|
5
5
|
import { createSkillConfigManager } from "../../agent/skills/config.js";
|
|
6
6
|
import { removeSkillsLockEntry } from "../../agent/skills/hub-lock.js";
|
|
7
7
|
import { deleteManagedSkill, installSkillFromZip, listManagedSkillDirs } from "../../agent/skills/managed-store.js";
|
|
8
|
-
import { listRegisteredProviders } from "../../agent/skills/marketplace/registry.js";
|
|
9
8
|
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
10
|
-
import { installExtensionFromStoreZip, peekExtensionIdFromStoreZip } from "../../extensions/install.js";
|
|
11
|
-
import { downloadExtensionStoreZipBuffer, fetchMarketplacePackageDetail, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } from "../../agent/skills/marketplace/adapters/store/store-api-client.js";
|
|
12
|
-
import { getMarketplaceProviderDisplayName, resolveSkillsMarketplaceProvider } from "../../agent/skills/marketplace/resolve-adapter.js";
|
|
13
|
-
import { downloadFromMarketplace, getMarketplacePackageDetail, listMarketplaceCategories, listMarketplacePackages } from "../../agent/skills/skills-marketplace.js";
|
|
14
9
|
import { join } from "node:path";
|
|
15
10
|
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
16
11
|
//#region src/gateway/service/marketplace-service.ts
|
|
@@ -87,22 +82,27 @@ var GatewayMarketplaceService = class {
|
|
|
87
82
|
this.opts.getAgentService().refreshSkillsAfterSkillConfigChange();
|
|
88
83
|
}
|
|
89
84
|
async fetchSkillsCatalog(params, provider) {
|
|
85
|
+
const { listMarketplacePackages } = await import("../../agent/skills/skills-marketplace.js");
|
|
90
86
|
return listMarketplacePackages(this.opts.getConfig(), params, provider);
|
|
91
87
|
}
|
|
92
88
|
async fetchSkillsCategories(provider) {
|
|
89
|
+
const { listMarketplaceCategories } = await import("../../agent/skills/skills-marketplace.js");
|
|
93
90
|
return listMarketplaceCategories(this.opts.getConfig(), provider);
|
|
94
91
|
}
|
|
95
92
|
async fetchSkillsPackageDetail(packageName, provider) {
|
|
93
|
+
const { getMarketplacePackageDetail } = await import("../../agent/skills/skills-marketplace.js");
|
|
96
94
|
return getMarketplacePackageDetail(this.opts.getConfig(), packageName, provider);
|
|
97
95
|
}
|
|
98
96
|
async installSkill(opts) {
|
|
97
|
+
const { downloadFromMarketplace } = await import("../../agent/skills/skills-marketplace.js");
|
|
99
98
|
const { buffer, skillId } = await downloadFromMarketplace(this.opts.getConfig(), opts.name, opts.version, opts.provider);
|
|
100
99
|
return this.installSkillZip(buffer, {
|
|
101
100
|
skillId,
|
|
102
101
|
overwrite: opts.overwrite ?? false
|
|
103
102
|
});
|
|
104
103
|
}
|
|
105
|
-
getSkillsProvider() {
|
|
104
|
+
async getSkillsProvider() {
|
|
105
|
+
const { getMarketplaceProviderDisplayName, resolveSkillsMarketplaceProvider } = await import("../../agent/skills/skills-marketplace.js");
|
|
106
106
|
const provider = resolveSkillsMarketplaceProvider(this.opts.getConfig());
|
|
107
107
|
return {
|
|
108
108
|
provider,
|
|
@@ -110,7 +110,8 @@ var GatewayMarketplaceService = class {
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
/** All registered marketplace providers (built-in + extension-contributed). */
|
|
113
|
-
getSkillsProviders() {
|
|
113
|
+
async getSkillsProviders() {
|
|
114
|
+
const { listRegisteredProviders } = await import("../../agent/skills/skills-marketplace.js");
|
|
114
115
|
return listRegisteredProviders();
|
|
115
116
|
}
|
|
116
117
|
getDefaultAgentId() {
|
|
@@ -139,6 +140,7 @@ var GatewayMarketplaceService = class {
|
|
|
139
140
|
}
|
|
140
141
|
/** xopc-store extension package preview (type must be `extension`). */
|
|
141
142
|
async fetchExtensionPackageDetail(packageName) {
|
|
143
|
+
const { fetchMarketplacePackageDetail, resolveExtensionsStoreBaseUrl } = await import("../../agent/skills/marketplace/adapters/store/store-api-client.js");
|
|
142
144
|
const detail = await fetchMarketplacePackageDetail(resolveExtensionsStoreBaseUrl(this.opts.getConfig()), packageName.trim());
|
|
143
145
|
if (detail.type !== "extension") throw new Error(`Package "${packageName}" is not an extension (store type: ${detail.type}).`);
|
|
144
146
|
return detail;
|
|
@@ -153,6 +155,8 @@ var GatewayMarketplaceService = class {
|
|
|
153
155
|
const packageName = opts.name.trim();
|
|
154
156
|
if (!packageName) throw new Error("Package name is required");
|
|
155
157
|
const cfg = this.opts.getConfig();
|
|
158
|
+
const { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } = await import("../../agent/skills/marketplace/adapters/store/store-api-client.js");
|
|
159
|
+
const { installExtensionFromStoreZip, peekExtensionIdFromStoreZip } = await import("../../extensions/install.js");
|
|
156
160
|
const storeBase = resolveExtensionsStoreBaseUrl(cfg);
|
|
157
161
|
const targetDir = resolveExtensionsDir();
|
|
158
162
|
mkdirSync(targetDir, { recursive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace-service.js","names":[],"sources":["../../../../src/gateway/service/marketplace-service.ts"],"sourcesContent":["/**\n * GatewayMarketplaceService — install / browse / remove for the two marketplaces\n * the gateway exposes:\n *\n * • **Skills** (`~/.xopc/skills/managed/<id>`) — zip-bundled markdown skills\n * pulled from a provider catalog (`agent/skills/skills-marketplace.ts`).\n * • **Extensions** (`~/.xopc/extensions/<id>`) — full extension packages from\n * the xopc-store.\n *\n * Owns the install/uninstall composite operations:\n * - download zip → unpack → upsert lockfile → refresh loader → emit reload\n * - rm dir → remove from `extensions.enabled` → refresh loader → emit reload\n *\n * Local-only skill management (install-from-zip, delete, enable/disable, list)\n * lives here too so callers (commands-skills routes) depend on a single narrow\n * service instead of the full `GatewayService`.\n */\nimport { existsSync, mkdirSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport type { AgentService } from '../../agent/service.js';\nimport type { ChannelManager } from '../../channels/manager.js';\nimport type { ExtensionLoader } from '../../extensions/loader.js';\nimport type {\n AgentSkillAvailabilityEntry,\n AgentSkillAvailabilityPayload,\n SkillCatalogEntry,\n SkillCatalogRuntimeMeta,\n} from '../../agent/agent-manager.js';\nimport type {\n ManagedSkillListItem,\n} from '../../agent/skills/managed-store.js';\nimport type { SkillMarkdownPreviewPayload } from '../../agent/skills/types.js';\nimport type {\n MarketplaceCategoryOption,\n SkillsStoreListParams,\n UnifiedMarketplaceListResponse,\n UnifiedMarketplacePackageDetail,\n} from '../../agent/skills/skills-marketplace.js';\nimport type { MarketplacePackageDetail } from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport {\n deleteManagedSkill as deleteManagedSkillDir,\n installSkillFromZip,\n listManagedSkillDirs,\n} from '../../agent/skills/managed-store.js';\nimport {\n downloadFromMarketplace,\n getMarketplacePackageDetail,\n getMarketplaceProviderDisplayName,\n listMarketplaceCategories,\n listMarketplacePackages,\n listRegisteredProviders,\n resolveSkillsMarketplaceProvider,\n} from '../../agent/skills/skills-marketplace.js';\nimport {\n downloadExtensionStoreZipBuffer,\n fetchMarketplacePackageDetail,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n} from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport { installExtensionFromStoreZip, peekExtensionIdFromStoreZip } from '../../extensions/install.js';\nimport { createSkillConfigManager } from '../../agent/skills/config.js';\nimport { removeSkillsLockEntry } from '../../agent/skills/hub-lock.js';\nimport { getExtensionLockfileManager } from '../../extensions/lockfile.js';\nimport { resolveExtensionsDir, resolveStateDir } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst log = createLogger('Gateway:Marketplace');\n\nexport interface GatewayMarketplaceServiceOptions {\n getConfig: () => Config;\n getAgentService: () => AgentService;\n getExtensionLoader: () => ExtensionLoader | null;\n getChannelManager: () => ChannelManager;\n saveConfig: (config: Config) => Promise<{ saved: boolean; error?: string }>;\n emit: (type: string, payload: unknown) => void;\n}\n\nexport interface SkillInstallAvailability {\n skillId: string;\n skillName?: string;\n loaded: boolean;\n enabled?: boolean;\n defaultAgentId: string;\n availableForDefaultAgent?: boolean;\n unavailableReason?: AgentSkillAvailabilityEntry['unavailableReason'];\n diagnostics: SkillCatalogRuntimeMeta['diagnostics'];\n}\n\nexport interface SkillInstallResultPayload {\n skillId: string;\n path: string;\n availability: SkillInstallAvailability;\n}\n\nexport class GatewayMarketplaceService {\n private readonly opts: GatewayMarketplaceServiceOptions;\n\n constructor(opts: GatewayMarketplaceServiceOptions) {\n this.opts = opts;\n }\n\n // ── Local skills (managed dir) ────────────────────────────────────────\n\n getSkillsApi(): {\n catalog: SkillCatalogEntry[];\n managed: ManagedSkillListItem[];\n } & SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n catalog: snapshot.catalog,\n managed: listManagedSkillDirs(),\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getSkillsStatusApi(): SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getAgentSkillsApi(agentId: string): AgentSkillAvailabilityPayload {\n return this.opts.getAgentService().getAgentSkillAvailability(agentId);\n }\n\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n return this.opts.getAgentService().getSkillMarkdownSource(skillName);\n }\n\n deleteSkill(skillId: string): void {\n removeSkillsLockEntry(skillId);\n deleteManagedSkillDir(skillId);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n installSkillZip(\n buffer: Buffer,\n opts: { skillId?: string; overwrite?: boolean },\n ): SkillInstallResultPayload {\n const result = installSkillFromZip(buffer, opts);\n removeSkillsLockEntry(result.skillId);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n return {\n ...result,\n availability: this.getInstallAvailability(result.skillId),\n };\n }\n\n reloadSkills(): void {\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n patchSkillEnabled(skillName: string, enabled: boolean): void {\n createSkillConfigManager(resolveStateDir()).setSkillEnabled(skillName, enabled);\n this.opts.getAgentService().refreshSkillsAfterSkillConfigChange();\n }\n\n // ── Skills marketplace catalog ────────────────────────────────────────\n\n async fetchSkillsCatalog(\n params: SkillsStoreListParams,\n provider?: string,\n ): Promise<UnifiedMarketplaceListResponse> {\n return listMarketplacePackages(this.opts.getConfig(), params, provider);\n }\n\n async fetchSkillsCategories(\n provider?: string,\n ): Promise<{ items: MarketplaceCategoryOption[] }> {\n return listMarketplaceCategories(this.opts.getConfig(), provider);\n }\n\n async fetchSkillsPackageDetail(\n packageName: string,\n provider?: string,\n ): Promise<UnifiedMarketplacePackageDetail> {\n return getMarketplacePackageDetail(this.opts.getConfig(), packageName, provider);\n }\n\n async installSkill(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n provider?: string;\n }): Promise<SkillInstallResultPayload> {\n const { buffer, skillId } = await downloadFromMarketplace(\n this.opts.getConfig(),\n opts.name,\n opts.version,\n opts.provider,\n );\n return this.installSkillZip(buffer, { skillId, overwrite: opts.overwrite ?? false });\n }\n\n getSkillsProvider(): { provider: string; displayName: string } {\n const provider = resolveSkillsMarketplaceProvider(this.opts.getConfig());\n return {\n provider,\n displayName: getMarketplaceProviderDisplayName(provider),\n };\n }\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n getSkillsProviders(): Array<{ id: string; displayName: string }> {\n return listRegisteredProviders();\n }\n\n private getDefaultAgentId(): string {\n return this.opts.getConfig().agents?.default || 'main';\n }\n\n private getInstallAvailability(skillId: string): SkillInstallAvailability {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n const catalogEntry =\n snapshot.catalog.find((s) => s.directoryId === skillId) ??\n snapshot.catalog.find((s) => s.name === skillId);\n const defaultAgentId = this.getDefaultAgentId();\n const agentSkills = this.getAgentSkillsApi(defaultAgentId);\n const agentEntry = catalogEntry\n ? agentSkills.skills.find((s) => s.name === catalogEntry.name)\n : undefined;\n const relevantDiagnostics = snapshot.diagnostics.filter((diag) => {\n if (!catalogEntry) return diag.path?.includes(skillId) || diag.skillName === skillId;\n return diag.skillName === catalogEntry.name || diag.path?.startsWith(catalogEntry.path);\n });\n return {\n skillId,\n ...(catalogEntry ? { skillName: catalogEntry.name } : {}),\n loaded: Boolean(catalogEntry),\n ...(catalogEntry ? { enabled: catalogEntry.enabled } : {}),\n defaultAgentId,\n ...(agentEntry ? { availableForDefaultAgent: agentEntry.availableForCurrentAgent } : {}),\n ...(agentEntry?.unavailableReason ? { unavailableReason: agentEntry.unavailableReason } : {}),\n diagnostics: relevantDiagnostics,\n };\n }\n\n // ── Extension marketplace ─────────────────────────────────────────────\n\n /** xopc-store extension package preview (type must be `extension`). */\n async fetchExtensionPackageDetail(packageName: string): Promise<MarketplacePackageDetail> {\n const base = resolveExtensionsStoreBaseUrl(this.opts.getConfig());\n const detail = await fetchMarketplacePackageDetail(base, packageName.trim());\n if (detail.type !== 'extension') {\n throw new Error(\n `Package \"${packageName}\" is not an extension (store type: ${detail.type}).`,\n );\n }\n return detail;\n }\n\n /**\n * Install an extension from xopc-store into `~/.xopc/extensions`, append id\n * to `extensions.enabled`, refresh the loader, and emit `config.reload`.\n * Returns `requiresGatewayRestart=true` when a new channel plugin would have\n * to wire into the running gateway (channel registration cannot hot-patch).\n */\n async installExtension(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n }): Promise<{ extensionId: string; version: string; requiresGatewayRestart: boolean }> {\n const packageName = opts.name.trim();\n if (!packageName) {\n throw new Error('Package name is required');\n }\n const cfg = this.opts.getConfig();\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n const targetDir = resolveExtensionsDir();\n mkdirSync(targetDir, { recursive: true });\n\n const { downloadUrl, version } = await resolveExtensionZipDownloadUrl(\n storeBase,\n packageName,\n opts.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(storeBase, downloadUrl);\n\n if (opts.overwrite) {\n const peekId = peekExtensionIdFromStoreZip(buf);\n if (peekId && existsSync(join(targetDir, peekId))) {\n rmSync(join(targetDir, peekId), { recursive: true, force: true });\n }\n }\n\n const result = await installExtensionFromStoreZip(buf, targetDir);\n if (!result.ok || !result.extensionId) {\n throw new Error(result.error ?? 'Extension install failed');\n }\n\n const lock = getExtensionLockfileManager();\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version,\n resolved: packageName,\n source: 'store',\n });\n\n const nextConfig = this.mergeExtensionEnabledIntoConfig(cfg, result.extensionId);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension install');\n }\n\n const channelIdsBefore = new Set(this.opts.getChannelManager().getAllPlugins().map((p) => p.id));\n let requiresGatewayRestart = false;\n const loader = this.opts.getExtensionLoader();\n try {\n if (loader) {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n const reg = loader.getRegistry();\n for (const p of reg.channelPlugins) {\n if (!channelIdsBefore.has(p.id)) {\n requiresGatewayRestart = true;\n break;\n }\n }\n }\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after marketplace install failed: ${em}`);\n requiresGatewayRestart = true;\n }\n\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-install' });\n return { extensionId: result.extensionId, version, requiresGatewayRestart };\n }\n\n /** Remove a user-installed extension (global or per-agent dir) from disk and config. */\n async uninstallExtension(extensionId: string): Promise<{ requiresGatewayRestart: boolean }> {\n const id = extensionId.trim();\n if (!id) {\n throw new Error('extensionId is required');\n }\n const loader = this.opts.getExtensionLoader();\n if (!loader) {\n throw new Error('Extensions unavailable');\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === id);\n if (!ext) {\n throw new Error(`Extension not found: ${id}`);\n }\n if (ext.source === 'bundled') {\n throw new Error('Built-in extensions cannot be uninstalled from the marketplace UI');\n }\n if (existsSync(ext.path)) {\n rmSync(ext.path, { recursive: true, force: true });\n }\n await getExtensionLockfileManager().remove(id);\n\n const nextConfig = this.mergeExtensionRemovedFromEnabledConfig(this.opts.getConfig(), id);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension uninstall');\n }\n try {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after uninstall failed: ${em}`);\n }\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-uninstall' });\n return { requiresGatewayRestart: true };\n }\n\n // ── Internals ─────────────────────────────────────────────────────────\n\n private mergeExtensionEnabledIntoConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? [...enabledRaw.filter((x): x is string => typeof x === 'string')]\n : [];\n if (!enabled.includes(id)) enabled.push(id);\n\n const disabledRaw = baseExt.disabled;\n const nextExt: Record<string, unknown> = { ...baseExt, enabled };\n if (Array.isArray(disabledRaw)) {\n const next = disabledRaw.filter((x): x is string => typeof x === 'string' && x !== id);\n if (next.length > 0) nextExt.disabled = next;\n else delete nextExt.disabled;\n }\n\n return {\n ...currentConfig,\n extensions: nextExt,\n } as Config;\n }\n\n private mergeExtensionRemovedFromEnabledConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? enabledRaw.filter((x): x is string => typeof x === 'string' && x !== id)\n : [];\n return {\n ...currentConfig,\n extensions: { ...baseExt, enabled },\n } as Config;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"marketplace-service.js","names":[],"sources":["../../../../src/gateway/service/marketplace-service.ts"],"sourcesContent":["/**\n * GatewayMarketplaceService — install / browse / remove for the two marketplaces\n * the gateway exposes:\n *\n * • **Skills** (`~/.xopc/skills/managed/<id>`) — zip-bundled markdown skills\n * pulled from a provider catalog (`agent/skills/skills-marketplace.ts`).\n * • **Extensions** (`~/.xopc/extensions/<id>`) — full extension packages from\n * the xopc-store.\n *\n * Owns the install/uninstall composite operations:\n * - download zip → unpack → upsert lockfile → refresh loader → emit reload\n * - rm dir → remove from `extensions.enabled` → refresh loader → emit reload\n *\n * Local-only skill management (install-from-zip, delete, enable/disable, list)\n * lives here too so callers (commands-skills routes) depend on a single narrow\n * service instead of the full `GatewayService`.\n */\nimport { existsSync, mkdirSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport type { AgentService } from '../../agent/service.js';\nimport type { ChannelManager } from '../../channels/manager.js';\nimport type { ExtensionLoader } from '../../extensions/loader.js';\nimport type {\n AgentSkillAvailabilityEntry,\n AgentSkillAvailabilityPayload,\n SkillCatalogEntry,\n SkillCatalogRuntimeMeta,\n} from '../../agent/agent-manager.js';\nimport type {\n ManagedSkillListItem,\n} from '../../agent/skills/managed-store.js';\nimport type { SkillMarkdownPreviewPayload } from '../../agent/skills/types.js';\nimport type {\n MarketplaceCategoryOption,\n SkillsStoreListParams,\n UnifiedMarketplaceListResponse,\n UnifiedMarketplacePackageDetail,\n} from '../../agent/skills/skills-marketplace.js';\nimport type { MarketplacePackageDetail } from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport {\n deleteManagedSkill as deleteManagedSkillDir,\n installSkillFromZip,\n listManagedSkillDirs,\n} from '../../agent/skills/managed-store.js';\nimport { createSkillConfigManager } from '../../agent/skills/config.js';\nimport { removeSkillsLockEntry } from '../../agent/skills/hub-lock.js';\nimport { getExtensionLockfileManager } from '../../extensions/lockfile.js';\nimport { resolveExtensionsDir, resolveStateDir } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst log = createLogger('Gateway:Marketplace');\n\nexport interface GatewayMarketplaceServiceOptions {\n getConfig: () => Config;\n getAgentService: () => AgentService;\n getExtensionLoader: () => ExtensionLoader | null;\n getChannelManager: () => ChannelManager;\n saveConfig: (config: Config) => Promise<{ saved: boolean; error?: string }>;\n emit: (type: string, payload: unknown) => void;\n}\n\nexport interface SkillInstallAvailability {\n skillId: string;\n skillName?: string;\n loaded: boolean;\n enabled?: boolean;\n defaultAgentId: string;\n availableForDefaultAgent?: boolean;\n unavailableReason?: AgentSkillAvailabilityEntry['unavailableReason'];\n diagnostics: SkillCatalogRuntimeMeta['diagnostics'];\n}\n\nexport interface SkillInstallResultPayload {\n skillId: string;\n path: string;\n availability: SkillInstallAvailability;\n}\n\nexport class GatewayMarketplaceService {\n private readonly opts: GatewayMarketplaceServiceOptions;\n\n constructor(opts: GatewayMarketplaceServiceOptions) {\n this.opts = opts;\n }\n\n // ── Local skills (managed dir) ────────────────────────────────────────\n\n getSkillsApi(): {\n catalog: SkillCatalogEntry[];\n managed: ManagedSkillListItem[];\n } & SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n catalog: snapshot.catalog,\n managed: listManagedSkillDirs(),\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getSkillsStatusApi(): SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getAgentSkillsApi(agentId: string): AgentSkillAvailabilityPayload {\n return this.opts.getAgentService().getAgentSkillAvailability(agentId);\n }\n\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n return this.opts.getAgentService().getSkillMarkdownSource(skillName);\n }\n\n deleteSkill(skillId: string): void {\n removeSkillsLockEntry(skillId);\n deleteManagedSkillDir(skillId);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n installSkillZip(\n buffer: Buffer,\n opts: { skillId?: string; overwrite?: boolean },\n ): SkillInstallResultPayload {\n const result = installSkillFromZip(buffer, opts);\n removeSkillsLockEntry(result.skillId);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n return {\n ...result,\n availability: this.getInstallAvailability(result.skillId),\n };\n }\n\n reloadSkills(): void {\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n patchSkillEnabled(skillName: string, enabled: boolean): void {\n createSkillConfigManager(resolveStateDir()).setSkillEnabled(skillName, enabled);\n this.opts.getAgentService().refreshSkillsAfterSkillConfigChange();\n }\n\n // ── Skills marketplace catalog ────────────────────────────────────────\n\n async fetchSkillsCatalog(\n params: SkillsStoreListParams,\n provider?: string,\n ): Promise<UnifiedMarketplaceListResponse> {\n const { listMarketplacePackages } = await import('../../agent/skills/skills-marketplace.js');\n return listMarketplacePackages(this.opts.getConfig(), params, provider);\n }\n\n async fetchSkillsCategories(\n provider?: string,\n ): Promise<{ items: MarketplaceCategoryOption[] }> {\n const { listMarketplaceCategories } = await import('../../agent/skills/skills-marketplace.js');\n return listMarketplaceCategories(this.opts.getConfig(), provider);\n }\n\n async fetchSkillsPackageDetail(\n packageName: string,\n provider?: string,\n ): Promise<UnifiedMarketplacePackageDetail> {\n const { getMarketplacePackageDetail } = await import('../../agent/skills/skills-marketplace.js');\n return getMarketplacePackageDetail(this.opts.getConfig(), packageName, provider);\n }\n\n async installSkill(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n provider?: string;\n }): Promise<SkillInstallResultPayload> {\n const { downloadFromMarketplace } = await import('../../agent/skills/skills-marketplace.js');\n const { buffer, skillId } = await downloadFromMarketplace(\n this.opts.getConfig(),\n opts.name,\n opts.version,\n opts.provider,\n );\n return this.installSkillZip(buffer, { skillId, overwrite: opts.overwrite ?? false });\n }\n\n async getSkillsProvider(): Promise<{ provider: string; displayName: string }> {\n const {\n getMarketplaceProviderDisplayName,\n resolveSkillsMarketplaceProvider,\n } = await import('../../agent/skills/skills-marketplace.js');\n const provider = resolveSkillsMarketplaceProvider(this.opts.getConfig());\n return {\n provider,\n displayName: getMarketplaceProviderDisplayName(provider),\n };\n }\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n async getSkillsProviders(): Promise<Array<{ id: string; displayName: string }>> {\n const { listRegisteredProviders } = await import('../../agent/skills/skills-marketplace.js');\n return listRegisteredProviders();\n }\n\n private getDefaultAgentId(): string {\n return this.opts.getConfig().agents?.default || 'main';\n }\n\n private getInstallAvailability(skillId: string): SkillInstallAvailability {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n const catalogEntry =\n snapshot.catalog.find((s) => s.directoryId === skillId) ??\n snapshot.catalog.find((s) => s.name === skillId);\n const defaultAgentId = this.getDefaultAgentId();\n const agentSkills = this.getAgentSkillsApi(defaultAgentId);\n const agentEntry = catalogEntry\n ? agentSkills.skills.find((s) => s.name === catalogEntry.name)\n : undefined;\n const relevantDiagnostics = snapshot.diagnostics.filter((diag) => {\n if (!catalogEntry) return diag.path?.includes(skillId) || diag.skillName === skillId;\n return diag.skillName === catalogEntry.name || diag.path?.startsWith(catalogEntry.path);\n });\n return {\n skillId,\n ...(catalogEntry ? { skillName: catalogEntry.name } : {}),\n loaded: Boolean(catalogEntry),\n ...(catalogEntry ? { enabled: catalogEntry.enabled } : {}),\n defaultAgentId,\n ...(agentEntry ? { availableForDefaultAgent: agentEntry.availableForCurrentAgent } : {}),\n ...(agentEntry?.unavailableReason ? { unavailableReason: agentEntry.unavailableReason } : {}),\n diagnostics: relevantDiagnostics,\n };\n }\n\n // ── Extension marketplace ─────────────────────────────────────────────\n\n /** xopc-store extension package preview (type must be `extension`). */\n async fetchExtensionPackageDetail(packageName: string): Promise<MarketplacePackageDetail> {\n const {\n fetchMarketplacePackageDetail,\n resolveExtensionsStoreBaseUrl,\n } = await import('../../agent/skills/marketplace/adapters/store/store-api-client.js');\n const base = resolveExtensionsStoreBaseUrl(this.opts.getConfig());\n const detail = await fetchMarketplacePackageDetail(base, packageName.trim());\n if (detail.type !== 'extension') {\n throw new Error(\n `Package \"${packageName}\" is not an extension (store type: ${detail.type}).`,\n );\n }\n return detail;\n }\n\n /**\n * Install an extension from xopc-store into `~/.xopc/extensions`, append id\n * to `extensions.enabled`, refresh the loader, and emit `config.reload`.\n * Returns `requiresGatewayRestart=true` when a new channel plugin would have\n * to wire into the running gateway (channel registration cannot hot-patch).\n */\n async installExtension(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n }): Promise<{ extensionId: string; version: string; requiresGatewayRestart: boolean }> {\n const packageName = opts.name.trim();\n if (!packageName) {\n throw new Error('Package name is required');\n }\n const cfg = this.opts.getConfig();\n const {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n } = await import('../../agent/skills/marketplace/adapters/store/store-api-client.js');\n const {\n installExtensionFromStoreZip,\n peekExtensionIdFromStoreZip,\n } = await import('../../extensions/install.js');\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n const targetDir = resolveExtensionsDir();\n mkdirSync(targetDir, { recursive: true });\n\n const { downloadUrl, version } = await resolveExtensionZipDownloadUrl(\n storeBase,\n packageName,\n opts.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(storeBase, downloadUrl);\n\n if (opts.overwrite) {\n const peekId = peekExtensionIdFromStoreZip(buf);\n if (peekId && existsSync(join(targetDir, peekId))) {\n rmSync(join(targetDir, peekId), { recursive: true, force: true });\n }\n }\n\n const result = await installExtensionFromStoreZip(buf, targetDir);\n if (!result.ok || !result.extensionId) {\n throw new Error(result.error ?? 'Extension install failed');\n }\n\n const lock = getExtensionLockfileManager();\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version,\n resolved: packageName,\n source: 'store',\n });\n\n const nextConfig = this.mergeExtensionEnabledIntoConfig(cfg, result.extensionId);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension install');\n }\n\n const channelIdsBefore = new Set(this.opts.getChannelManager().getAllPlugins().map((p) => p.id));\n let requiresGatewayRestart = false;\n const loader = this.opts.getExtensionLoader();\n try {\n if (loader) {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n const reg = loader.getRegistry();\n for (const p of reg.channelPlugins) {\n if (!channelIdsBefore.has(p.id)) {\n requiresGatewayRestart = true;\n break;\n }\n }\n }\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after marketplace install failed: ${em}`);\n requiresGatewayRestart = true;\n }\n\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-install' });\n return { extensionId: result.extensionId, version, requiresGatewayRestart };\n }\n\n /** Remove a user-installed extension (global or per-agent dir) from disk and config. */\n async uninstallExtension(extensionId: string): Promise<{ requiresGatewayRestart: boolean }> {\n const id = extensionId.trim();\n if (!id) {\n throw new Error('extensionId is required');\n }\n const loader = this.opts.getExtensionLoader();\n if (!loader) {\n throw new Error('Extensions unavailable');\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === id);\n if (!ext) {\n throw new Error(`Extension not found: ${id}`);\n }\n if (ext.source === 'bundled') {\n throw new Error('Built-in extensions cannot be uninstalled from the marketplace UI');\n }\n if (existsSync(ext.path)) {\n rmSync(ext.path, { recursive: true, force: true });\n }\n await getExtensionLockfileManager().remove(id);\n\n const nextConfig = this.mergeExtensionRemovedFromEnabledConfig(this.opts.getConfig(), id);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension uninstall');\n }\n try {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after uninstall failed: ${em}`);\n }\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-uninstall' });\n return { requiresGatewayRestart: true };\n }\n\n // ── Internals ─────────────────────────────────────────────────────────\n\n private mergeExtensionEnabledIntoConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? [...enabledRaw.filter((x): x is string => typeof x === 'string')]\n : [];\n if (!enabled.includes(id)) enabled.push(id);\n\n const disabledRaw = baseExt.disabled;\n const nextExt: Record<string, unknown> = { ...baseExt, enabled };\n if (Array.isArray(disabledRaw)) {\n const next = disabledRaw.filter((x): x is string => typeof x === 'string' && x !== id);\n if (next.length > 0) nextExt.disabled = next;\n else delete nextExt.disabled;\n }\n\n return {\n ...currentConfig,\n extensions: nextExt,\n } as Config;\n }\n\n private mergeExtensionRemovedFromEnabledConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? enabledRaw.filter((x): x is string => typeof x === 'string' && x !== id)\n : [];\n return {\n ...currentConfig,\n extensions: { ...baseExt, enabled },\n } as Config;\n }\n}\n"],"mappings":"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"}
|
|
@@ -64,6 +64,7 @@ export declare class GatewaySessionsApi {
|
|
|
64
64
|
nextBeforeCursor?: string;
|
|
65
65
|
};
|
|
66
66
|
}>;
|
|
67
|
+
getTimeline(key: string): Promise<import("../../session/transcript-outline.js").SessionTimelineItem[]>;
|
|
67
68
|
patch(key: string, body: SessionPatchBody): Promise<{
|
|
68
69
|
ok: true;
|
|
69
70
|
} | {
|
|
@@ -142,7 +143,7 @@ export declare class GatewaySessionsApi {
|
|
|
142
143
|
}>;
|
|
143
144
|
stats(): Promise<import("../../session/types.js").GlobalSessionStats>;
|
|
144
145
|
/**
|
|
145
|
-
* Distinct chat-id pairs from sessions, grouped by channel. Used by
|
|
146
|
+
* Distinct chat-id pairs from sessions, grouped by channel. Used by automation
|
|
146
147
|
* configuration UI to seed the "send to existing chat" picker.
|
|
147
148
|
*/
|
|
148
149
|
chatIds(channel?: string): Promise<Array<{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { retireSessionMcpRuntimeForSessionKey } from "../../agent/mcp/bundle-mcp-runtime.js";
|
|
2
2
|
import "../../agent/mcp/bundle-mcp-tools.js";
|
|
3
|
+
import { buildSessionTimeline } from "../../session/transcript-outline.js";
|
|
3
4
|
import { collectMediaUrisFromMessages, deleteMediaUris } from "../../media/session-references.js";
|
|
4
5
|
import { getDistinctSessionChatIds } from "./session-chat-ids.js";
|
|
5
6
|
import { performSessionReset } from "../session-reset-service.js";
|
|
@@ -44,6 +45,10 @@ var GatewaySessionsApi = class {
|
|
|
44
45
|
getMessagePage(key, options) {
|
|
45
46
|
return this.opts.sessionIndex.getSessionMessagePage(key, options);
|
|
46
47
|
}
|
|
48
|
+
async getTimeline(key) {
|
|
49
|
+
if (!await this.opts.sessionIndex.getSessionMetadata(key)) return null;
|
|
50
|
+
return buildSessionTimeline(await this.opts.sessionIndex.getStore().loadTranscriptRows(key));
|
|
51
|
+
}
|
|
47
52
|
patch(key, body) {
|
|
48
53
|
return this.opts.sessionIndex.patchSession(key, body);
|
|
49
54
|
}
|
|
@@ -156,7 +161,7 @@ var GatewaySessionsApi = class {
|
|
|
156
161
|
return this.opts.sessionIndex.getStats();
|
|
157
162
|
}
|
|
158
163
|
/**
|
|
159
|
-
* Distinct chat-id pairs from sessions, grouped by channel. Used by
|
|
164
|
+
* Distinct chat-id pairs from sessions, grouped by channel. Used by automation
|
|
160
165
|
* configuration UI to seed the "send to existing chat" picker.
|
|
161
166
|
*/
|
|
162
167
|
chatIds(channel) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions-api.js","names":[],"sources":["../../../../src/gateway/service/sessions-api.ts"],"sourcesContent":["/**\n * GatewaySessionsApi — session CRUD, search, compaction, tag/pin/archive,\n * stats, and chat-id grouping for the gateway REST surface.\n *\n * Twenty-four methods, previously sitting on `GatewayService` as a mix of\n * one-line `sessionIndex.*` delegations and small composite operations (e.g.\n * `restoreCheckpoint` also evicts the in-memory agent, `runCompaction` also\n * appends a transcript context entry). Centralising them here lets routes\n * depend on the narrow `GatewaySessionsApi` surface instead of the full\n * `GatewayService`, and keeps the gateway composition root focused on\n * lifecycle + wiring.\n */\n\nimport type { AgentService } from '../../agent/service.js';\nimport type { CompactionResult } from '../../agent/memory/compaction.js';\nimport { retireSessionMcpRuntimeForSessionKey } from '../../agent/mcp/bundle-mcp-tools.js';\nimport { SessionIndex } from '../../session/index.js';\nimport type { ExportFormat, SessionListQuery } from '../../session/types.js';\nimport type { SessionPatchBody } from '../../session/patch-metadata.js';\nimport { collectMediaUrisFromMessages, deleteMediaUris } from '../../media/session-references.js';\nimport { getDistinctSessionChatIds } from './session-chat-ids.js';\nimport { performSessionReset, type SessionResetResult } from '../session-reset-service.js';\n\nexport interface GatewaySessionsApiOptions {\n sessionIndex: SessionIndex;\n /** Resolves the live agent service (created lazily; throws if gateway is starting). */\n getAgentService: () => AgentService;\n /** Read-only view of in-flight webchat runs (per session key → run id). */\n getActiveWebchatRunId: (sessionKey: string) => string | undefined;\n}\n\nexport class GatewaySessionsApi {\n private readonly opts: GatewaySessionsApiOptions;\n\n constructor(opts: GatewaySessionsApiOptions) {\n this.opts = opts;\n }\n\n // ── List / get ─────────────────────────────────────────────────────────\n\n listSessions(query?: SessionListQuery) {\n return this.opts.sessionIndex.listSessions(query);\n }\n\n /** Subagent sessions have keys starting with `subagent:`. */\n listSubagents(query?: SessionListQuery) {\n return this.opts.sessionIndex.listSubagents(query);\n }\n\n getSession(\n key: string,\n options?: { includeTranscriptSummary?: boolean; includeTranscriptRows?: boolean },\n ) {\n return this.opts.sessionIndex.getSession(key, options);\n }\n\n async resolveSession(input: {\n key?: string;\n sessionKey?: string;\n sessionId?: string;\n }): Promise<\n | {\n sessionKey: string;\n sessionId: string;\n session: Awaited<ReturnType<GatewaySessionsApi['getSession']>>;\n }\n | null\n > {\n const explicitKey = input.sessionKey?.trim() || input.key?.trim();\n const resolvedKey =\n explicitKey ||\n (input.sessionId?.trim()\n ? await this.opts.sessionIndex.resolveSessionKeyBySessionId(input.sessionId.trim())\n : null);\n if (!resolvedKey) {\n return null;\n }\n const session = await this.getSession(resolvedKey);\n if (!session?.sessionId) {\n return null;\n }\n return { sessionKey: resolvedKey, sessionId: session.sessionId, session };\n }\n\n /** Read-only: in-flight webchat agent run for this session key, if any. */\n getActiveRun(sessionKey: string): { active: boolean; runId?: string } {\n const key = sessionKey.trim();\n if (!key) return { active: false };\n const runId = this.opts.getActiveWebchatRunId(key)?.trim();\n if (!runId) return { active: false };\n return { active: true, runId };\n }\n\n getMessagePage(\n key: string,\n options?: {\n offset?: number;\n limit?: number;\n before?: string;\n includeTranscriptSummary?: boolean;\n includeTranscriptRows?: boolean;\n },\n ) {\n return this.opts.sessionIndex.getSessionMessagePage(key, options);\n }\n\n // ── Metadata patches ──────────────────────────────────────────────────\n\n patch(key: string, body: SessionPatchBody): Promise<{ ok: true } | { ok: false; error: string }> {\n return this.opts.sessionIndex.patchSession(key, body);\n }\n\n async getAgentConfig(sessionKey: string) {\n return this.opts.getAgentService().sessionInspector.agentConfig(sessionKey);\n }\n\n /** Resolved markdown workspace for a session (after hydration / mkdir). */\n getEffectiveWorkspacePath(sessionKey: string): Promise<string> {\n return this.opts.getAgentService().getEffectiveWorkspacePathForSession(sessionKey);\n }\n\n patchAgentConfig(\n sessionKey: string,\n body: {\n thinkingLevel?: string;\n model?: string | null;\n reasoningLevel?: string;\n verboseLevel?: string;\n workingDirectory?: string;\n },\n ) {\n return this.opts.getAgentService().sessionConfig.patch(sessionKey, body);\n }\n\n // ── Compaction checkpoints ────────────────────────────────────────────\n\n listCompactionCheckpoints(key: string) {\n return this.opts.sessionIndex.listCompactionCheckpoints(key);\n }\n\n getCompactionCheckpoint(key: string, checkpointId: string) {\n return this.opts.sessionIndex.getCompactionCheckpointDetail(key, checkpointId);\n }\n\n async restoreCompactionCheckpoint(key: string, checkpointId: string): Promise<void> {\n await this.opts.sessionIndex.restoreCompactionCheckpoint(key, checkpointId);\n this.opts.getAgentService().evictSessionAgent(key);\n }\n\n async runCompaction(\n key: string,\n options?: { instructions?: string; force?: boolean },\n ): Promise<CompactionResult> {\n const result = await this.opts.getAgentService().sessionInspector.compact(key, options);\n if (result.compacted) {\n void this.opts.sessionIndex\n .appendTranscriptContextEntry(key, {\n text: 'Session transcript compacted',\n data: {\n firstKeptIndex: result.firstKeptIndex,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n summaryPreview: result.summary.slice(0, 500),\n },\n })\n .catch(() => {});\n }\n return result;\n }\n\n // ── Lifecycle (delete / rename / tag / pin / archive) ─────────────────\n\n async delete(key: string): Promise<{ deleted: boolean }> {\n const messages = await this.opts.sessionIndex.loadMessages(key).catch(() => []);\n const result = await this.opts.sessionIndex.deleteSession(key);\n if (result) {\n await deleteMediaUris(collectMediaUrisFromMessages(messages));\n this.opts.getAgentService().evictSessionAgent(key);\n await retireSessionMcpRuntimeForSessionKey({ sessionKey: key, reason: 'session-delete' });\n }\n return { deleted: result };\n }\n\n /** Reset transcript in place (archive + new session id); preserves session key and overrides. */\n reset(key: string): Promise<SessionResetResult> {\n return performSessionReset(key, {\n sessionIndex: this.opts.sessionIndex,\n getAgentService: this.opts.getAgentService,\n });\n }\n\n deleteMany(keys: string[]): Promise<{ success: string[]; failed: string[] }> {\n return this.opts.sessionIndex.deleteSessions(keys);\n }\n\n async rename(key: string, name: string): Promise<{ renamed: boolean }> {\n await this.opts.sessionIndex.renameSession(key, name);\n return { renamed: true };\n }\n\n async tag(key: string, tags: string[]): Promise<{ tagged: boolean }> {\n await this.opts.sessionIndex.tagSession(key, tags);\n return { tagged: true };\n }\n\n async untag(key: string, tags: string[]): Promise<{ untagged: boolean }> {\n await this.opts.sessionIndex.untagSession(key, tags);\n return { untagged: true };\n }\n\n async archive(key: string): Promise<{ archived: boolean }> {\n await this.opts.sessionIndex.archiveSession(key);\n return { archived: true };\n }\n\n async unarchive(key: string): Promise<{ unarchived: boolean }> {\n await this.opts.sessionIndex.unarchiveSession(key);\n return { unarchived: true };\n }\n\n async pin(key: string): Promise<{ pinned: boolean }> {\n await this.opts.sessionIndex.pinSession(key);\n return { pinned: true };\n }\n\n async unpin(key: string): Promise<{ unpinned: boolean }> {\n await this.opts.sessionIndex.unpinSession(key);\n return { unpinned: true };\n }\n\n // ── Search + export + stats ───────────────────────────────────────────\n\n search(query: string) {\n return this.opts.sessionIndex.searchSessions(query);\n }\n\n searchIn(key: string, keyword: string) {\n return this.opts.sessionIndex.searchInSession(key, keyword);\n }\n\n async export(key: string, format: ExportFormat): Promise<{ content: string }> {\n const content = await this.opts.sessionIndex.exportSession(key, format);\n return { content };\n }\n\n importExport(\n targetKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n return this.opts.sessionIndex.importSessionExport(targetKey, jsonContent);\n }\n\n fork(\n key: string,\n targetKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n return this.opts.sessionIndex.forkSession(key, targetKey);\n }\n\n forkRows(\n key: string,\n targetKey: string,\n options: { throughRow?: number } = {},\n ): Promise<{ sessionKey: string; rowCount: number }> {\n return this.opts.sessionIndex.forkSessionRows(key, targetKey, options);\n }\n\n btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n return this.opts.getAgentService().sessionInspector.btwQuery(sessionKey, question);\n }\n\n stats() {\n return this.opts.sessionIndex.getStats();\n }\n\n /**\n * Distinct chat-id pairs from sessions, grouped by channel. Used by cron job\n * configuration UI to seed the \"send to existing chat\" picker.\n */\n chatIds(channel?: string): Promise<\n Array<{\n channel: string;\n chatId: string;\n lastActive: string;\n accountId?: string;\n peerKind?: string;\n peerId?: string;\n }>\n > {\n return getDistinctSessionChatIds(this.opts.sessionIndex, channel);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sessions-api.js","names":[],"sources":["../../../../src/gateway/service/sessions-api.ts"],"sourcesContent":["/**\n * GatewaySessionsApi — session CRUD, search, compaction, tag/pin/archive,\n * stats, and chat-id grouping for the gateway REST surface.\n *\n * Twenty-four methods, previously sitting on `GatewayService` as a mix of\n * one-line `sessionIndex.*` delegations and small composite operations (e.g.\n * `restoreCheckpoint` also evicts the in-memory agent, `runCompaction` also\n * appends a transcript context entry). Centralising them here lets routes\n * depend on the narrow `GatewaySessionsApi` surface instead of the full\n * `GatewayService`, and keeps the gateway composition root focused on\n * lifecycle + wiring.\n */\n\nimport type { AgentService } from '../../agent/service.js';\nimport type { CompactionResult } from '../../agent/memory/compaction.js';\nimport { retireSessionMcpRuntimeForSessionKey } from '../../agent/mcp/bundle-mcp-tools.js';\nimport { SessionIndex } from '../../session/index.js';\nimport type { ExportFormat, SessionListQuery } from '../../session/types.js';\nimport { buildSessionTimeline } from '../../session/transcript-outline.js';\nimport type { SessionPatchBody } from '../../session/patch-metadata.js';\nimport { collectMediaUrisFromMessages, deleteMediaUris } from '../../media/session-references.js';\nimport { getDistinctSessionChatIds } from './session-chat-ids.js';\nimport { performSessionReset, type SessionResetResult } from '../session-reset-service.js';\n\nexport interface GatewaySessionsApiOptions {\n sessionIndex: SessionIndex;\n /** Resolves the live agent service (created lazily; throws if gateway is starting). */\n getAgentService: () => AgentService;\n /** Read-only view of in-flight webchat runs (per session key → run id). */\n getActiveWebchatRunId: (sessionKey: string) => string | undefined;\n}\n\nexport class GatewaySessionsApi {\n private readonly opts: GatewaySessionsApiOptions;\n\n constructor(opts: GatewaySessionsApiOptions) {\n this.opts = opts;\n }\n\n // ── List / get ─────────────────────────────────────────────────────────\n\n listSessions(query?: SessionListQuery) {\n return this.opts.sessionIndex.listSessions(query);\n }\n\n /** Subagent sessions have keys starting with `subagent:`. */\n listSubagents(query?: SessionListQuery) {\n return this.opts.sessionIndex.listSubagents(query);\n }\n\n getSession(\n key: string,\n options?: { includeTranscriptSummary?: boolean; includeTranscriptRows?: boolean },\n ) {\n return this.opts.sessionIndex.getSession(key, options);\n }\n\n async resolveSession(input: {\n key?: string;\n sessionKey?: string;\n sessionId?: string;\n }): Promise<\n | {\n sessionKey: string;\n sessionId: string;\n session: Awaited<ReturnType<GatewaySessionsApi['getSession']>>;\n }\n | null\n > {\n const explicitKey = input.sessionKey?.trim() || input.key?.trim();\n const resolvedKey =\n explicitKey ||\n (input.sessionId?.trim()\n ? await this.opts.sessionIndex.resolveSessionKeyBySessionId(input.sessionId.trim())\n : null);\n if (!resolvedKey) {\n return null;\n }\n const session = await this.getSession(resolvedKey);\n if (!session?.sessionId) {\n return null;\n }\n return { sessionKey: resolvedKey, sessionId: session.sessionId, session };\n }\n\n /** Read-only: in-flight webchat agent run for this session key, if any. */\n getActiveRun(sessionKey: string): { active: boolean; runId?: string } {\n const key = sessionKey.trim();\n if (!key) return { active: false };\n const runId = this.opts.getActiveWebchatRunId(key)?.trim();\n if (!runId) return { active: false };\n return { active: true, runId };\n }\n\n getMessagePage(\n key: string,\n options?: {\n offset?: number;\n limit?: number;\n before?: string;\n includeTranscriptSummary?: boolean;\n includeTranscriptRows?: boolean;\n },\n ) {\n return this.opts.sessionIndex.getSessionMessagePage(key, options);\n }\n\n async getTimeline(key: string) {\n const metadata = await this.opts.sessionIndex.getSessionMetadata(key);\n if (!metadata) return null;\n const rows = await this.opts.sessionIndex.getStore().loadTranscriptRows(key);\n return buildSessionTimeline(rows);\n }\n\n // ── Metadata patches ──────────────────────────────────────────────────\n\n patch(key: string, body: SessionPatchBody): Promise<{ ok: true } | { ok: false; error: string }> {\n return this.opts.sessionIndex.patchSession(key, body);\n }\n\n async getAgentConfig(sessionKey: string) {\n return this.opts.getAgentService().sessionInspector.agentConfig(sessionKey);\n }\n\n /** Resolved markdown workspace for a session (after hydration / mkdir). */\n getEffectiveWorkspacePath(sessionKey: string): Promise<string> {\n return this.opts.getAgentService().getEffectiveWorkspacePathForSession(sessionKey);\n }\n\n patchAgentConfig(\n sessionKey: string,\n body: {\n thinkingLevel?: string;\n model?: string | null;\n reasoningLevel?: string;\n verboseLevel?: string;\n workingDirectory?: string;\n },\n ) {\n return this.opts.getAgentService().sessionConfig.patch(sessionKey, body);\n }\n\n // ── Compaction checkpoints ────────────────────────────────────────────\n\n listCompactionCheckpoints(key: string) {\n return this.opts.sessionIndex.listCompactionCheckpoints(key);\n }\n\n getCompactionCheckpoint(key: string, checkpointId: string) {\n return this.opts.sessionIndex.getCompactionCheckpointDetail(key, checkpointId);\n }\n\n async restoreCompactionCheckpoint(key: string, checkpointId: string): Promise<void> {\n await this.opts.sessionIndex.restoreCompactionCheckpoint(key, checkpointId);\n this.opts.getAgentService().evictSessionAgent(key);\n }\n\n async runCompaction(\n key: string,\n options?: { instructions?: string; force?: boolean },\n ): Promise<CompactionResult> {\n const result = await this.opts.getAgentService().sessionInspector.compact(key, options);\n if (result.compacted) {\n void this.opts.sessionIndex\n .appendTranscriptContextEntry(key, {\n text: 'Session transcript compacted',\n data: {\n firstKeptIndex: result.firstKeptIndex,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n summaryPreview: result.summary.slice(0, 500),\n },\n })\n .catch(() => {});\n }\n return result;\n }\n\n // ── Lifecycle (delete / rename / tag / pin / archive) ─────────────────\n\n async delete(key: string): Promise<{ deleted: boolean }> {\n const messages = await this.opts.sessionIndex.loadMessages(key).catch(() => []);\n const result = await this.opts.sessionIndex.deleteSession(key);\n if (result) {\n await deleteMediaUris(collectMediaUrisFromMessages(messages));\n this.opts.getAgentService().evictSessionAgent(key);\n await retireSessionMcpRuntimeForSessionKey({ sessionKey: key, reason: 'session-delete' });\n }\n return { deleted: result };\n }\n\n /** Reset transcript in place (archive + new session id); preserves session key and overrides. */\n reset(key: string): Promise<SessionResetResult> {\n return performSessionReset(key, {\n sessionIndex: this.opts.sessionIndex,\n getAgentService: this.opts.getAgentService,\n });\n }\n\n deleteMany(keys: string[]): Promise<{ success: string[]; failed: string[] }> {\n return this.opts.sessionIndex.deleteSessions(keys);\n }\n\n async rename(key: string, name: string): Promise<{ renamed: boolean }> {\n await this.opts.sessionIndex.renameSession(key, name);\n return { renamed: true };\n }\n\n async tag(key: string, tags: string[]): Promise<{ tagged: boolean }> {\n await this.opts.sessionIndex.tagSession(key, tags);\n return { tagged: true };\n }\n\n async untag(key: string, tags: string[]): Promise<{ untagged: boolean }> {\n await this.opts.sessionIndex.untagSession(key, tags);\n return { untagged: true };\n }\n\n async archive(key: string): Promise<{ archived: boolean }> {\n await this.opts.sessionIndex.archiveSession(key);\n return { archived: true };\n }\n\n async unarchive(key: string): Promise<{ unarchived: boolean }> {\n await this.opts.sessionIndex.unarchiveSession(key);\n return { unarchived: true };\n }\n\n async pin(key: string): Promise<{ pinned: boolean }> {\n await this.opts.sessionIndex.pinSession(key);\n return { pinned: true };\n }\n\n async unpin(key: string): Promise<{ unpinned: boolean }> {\n await this.opts.sessionIndex.unpinSession(key);\n return { unpinned: true };\n }\n\n // ── Search + export + stats ───────────────────────────────────────────\n\n search(query: string) {\n return this.opts.sessionIndex.searchSessions(query);\n }\n\n searchIn(key: string, keyword: string) {\n return this.opts.sessionIndex.searchInSession(key, keyword);\n }\n\n async export(key: string, format: ExportFormat): Promise<{ content: string }> {\n const content = await this.opts.sessionIndex.exportSession(key, format);\n return { content };\n }\n\n importExport(\n targetKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n return this.opts.sessionIndex.importSessionExport(targetKey, jsonContent);\n }\n\n fork(\n key: string,\n targetKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n return this.opts.sessionIndex.forkSession(key, targetKey);\n }\n\n forkRows(\n key: string,\n targetKey: string,\n options: { throughRow?: number } = {},\n ): Promise<{ sessionKey: string; rowCount: number }> {\n return this.opts.sessionIndex.forkSessionRows(key, targetKey, options);\n }\n\n btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n return this.opts.getAgentService().sessionInspector.btwQuery(sessionKey, question);\n }\n\n stats() {\n return this.opts.sessionIndex.getStats();\n }\n\n /**\n * Distinct chat-id pairs from sessions, grouped by channel. Used by automation\n * configuration UI to seed the \"send to existing chat\" picker.\n */\n chatIds(channel?: string): Promise<\n Array<{\n channel: string;\n chatId: string;\n lastActive: string;\n accountId?: string;\n peerKind?: string;\n peerId?: string;\n }>\n > {\n return getDistinctSessionChatIds(this.opts.sessionIndex, channel);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AgentService } from '../agent/service.js';
|
|
2
2
|
import { MessageBus } from '../infra/bus/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { AutomationService } from '../automations/index.js';
|
|
4
4
|
import { NotesService } from '../notes/index.js';
|
|
5
5
|
import { WorkflowRunService } from '../workflows/service/workflow-run-service.js';
|
|
6
6
|
import { ExtensionLoader } from '../extensions/index.js';
|
|
@@ -22,7 +22,7 @@ export declare class GatewayService {
|
|
|
22
22
|
private configPath;
|
|
23
23
|
private _agentService;
|
|
24
24
|
private channelManager;
|
|
25
|
-
private
|
|
25
|
+
private automationService;
|
|
26
26
|
private notesService;
|
|
27
27
|
private extensionLoader;
|
|
28
28
|
private extensionMetadataSnapshot;
|
|
@@ -53,6 +53,8 @@ export declare class GatewayService {
|
|
|
53
53
|
private goalRunner;
|
|
54
54
|
private goalNotifications;
|
|
55
55
|
private connectorSupervisor;
|
|
56
|
+
private stopAutomationProductEventBridge;
|
|
57
|
+
private stopSessionTranscriptAutomationEvents;
|
|
56
58
|
/**
|
|
57
59
|
* Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
|
|
58
60
|
* `submitClarifyResponse`, clarify-bridge dispatch). Owns the
|
|
@@ -233,7 +235,8 @@ export declare class GatewayService {
|
|
|
233
235
|
get messageBusInstance(): MessageBus;
|
|
234
236
|
/** Effective HTTP listen port (CLI `--port` override or config default). */
|
|
235
237
|
getEffectiveListenPort(): number;
|
|
236
|
-
get
|
|
238
|
+
get automationServiceInstance(): AutomationService;
|
|
239
|
+
private reconcileDreamingAutomations;
|
|
237
240
|
get notesServiceInstance(): NotesService;
|
|
238
241
|
get sessionIndexInstance(): SessionIndex;
|
|
239
242
|
/** Shared workflow run orchestrator + session bridge (one instance per gateway). */
|
|
@@ -244,6 +247,7 @@ export declare class GatewayService {
|
|
|
244
247
|
processDirect(content: string, sessionKey?: string): Promise<string>;
|
|
245
248
|
subscribe(sessionId: string, listener: (event: ServiceEvent) => Promise<void> | void): () => void;
|
|
246
249
|
emit(type: string, payload: unknown): void;
|
|
250
|
+
private startAutomationProductEventBridge;
|
|
247
251
|
/** Replay events since `lastEventId` for SSE reconnection. */
|
|
248
252
|
getEventsSince(sessionId: string, lastEventId: string): ServiceEvent[];
|
|
249
253
|
/**
|
|
@@ -16,6 +16,8 @@ import { loadConfig, saveConfig } from "../config/loader.js";
|
|
|
16
16
|
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
17
17
|
import { init_providers, providers_exports } from "../providers/index.js";
|
|
18
18
|
import { resolveEffectiveGatewayPort } from "./host.js";
|
|
19
|
+
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
20
|
+
import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
|
|
19
21
|
import { closeXopcDatabase, openXopcDatabase } from "../storage/sqlite/connection.js";
|
|
20
22
|
import { GoalRunner } from "../goals/goal-runner.js";
|
|
21
23
|
import { GoalNotificationService } from "../goals/goal-notifications.js";
|
|
@@ -31,15 +33,16 @@ import { MessageBus, MessageBusShutdownError } from "../infra/bus/queue.js";
|
|
|
31
33
|
import "../infra/bus/index.js";
|
|
32
34
|
import { AgentService } from "../agent/service.js";
|
|
33
35
|
import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
|
|
36
|
+
import { AutomationService } from "../automations/service/automation-service.js";
|
|
37
|
+
import "../automations/index.js";
|
|
34
38
|
import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
|
|
35
39
|
import { registerClarifyBridge } from "./clarify-runtime.js";
|
|
36
40
|
import { ChannelManager } from "../channels/manager.js";
|
|
37
41
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
38
42
|
import "../config/index.js";
|
|
39
43
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
40
|
-
import { CronService } from "../cron/service.js";
|
|
41
|
-
import "../cron/index.js";
|
|
42
44
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
45
|
+
import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
|
|
43
46
|
import { NotesStore } from "../notes/store.js";
|
|
44
47
|
import { buildNoteAgentContext } from "../notes/agent-context.js";
|
|
45
48
|
import { NotesService } from "../notes/service.js";
|
|
@@ -59,6 +62,7 @@ import { isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
|
|
|
59
62
|
import "./rate-limit/index.js";
|
|
60
63
|
import { assertGatewayRuntimeConfig } from "./runtime-config.js";
|
|
61
64
|
import { auditGatewayConfig } from "./security/audit.js";
|
|
65
|
+
import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
62
66
|
import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
|
|
63
67
|
import { resolveChannelConnectDeferSet } from "./resolve-channel-connect-defer.js";
|
|
64
68
|
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
|
|
@@ -87,7 +91,7 @@ var GatewayService = class {
|
|
|
87
91
|
configPath;
|
|
88
92
|
_agentService = null;
|
|
89
93
|
channelManager;
|
|
90
|
-
|
|
94
|
+
automationService;
|
|
91
95
|
notesService;
|
|
92
96
|
extensionLoader = null;
|
|
93
97
|
extensionMetadataSnapshot = null;
|
|
@@ -120,6 +124,8 @@ var GatewayService = class {
|
|
|
120
124
|
goalRunner = null;
|
|
121
125
|
goalNotifications = null;
|
|
122
126
|
connectorSupervisor = null;
|
|
127
|
+
stopAutomationProductEventBridge = null;
|
|
128
|
+
stopSessionTranscriptAutomationEvents = null;
|
|
123
129
|
/**
|
|
124
130
|
* Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
|
|
125
131
|
* `submitClarifyResponse`, clarify-bridge dispatch). Owns the
|
|
@@ -145,6 +151,7 @@ var GatewayService = class {
|
|
|
145
151
|
this.serviceConfig = serviceConfig;
|
|
146
152
|
this.bus = new MessageBus();
|
|
147
153
|
this.configPath = serviceConfig.configPath || resolveConfigPath();
|
|
154
|
+
runBootstrapMigrationsSync(this.configPath);
|
|
148
155
|
this.config = loadConfig(this.configPath);
|
|
149
156
|
const starterResult = ensureStarterAgentsInitialized(this.config);
|
|
150
157
|
if (starterResult.changed) {
|
|
@@ -204,7 +211,7 @@ var GatewayService = class {
|
|
|
204
211
|
this.workspacePath = getWorkspacePath(this.config) || "./workspace";
|
|
205
212
|
this.initializeExtensionLoader();
|
|
206
213
|
this.sessionIndex = new SessionIndex({ config: this.config });
|
|
207
|
-
this.
|
|
214
|
+
this.automationService = new AutomationService();
|
|
208
215
|
this.notesService = new NotesService(new NotesStore());
|
|
209
216
|
this.agentRunner = new GatewayAgentRunner({
|
|
210
217
|
bus: this.bus,
|
|
@@ -237,10 +244,10 @@ var GatewayService = class {
|
|
|
237
244
|
},
|
|
238
245
|
getAgentService: () => this.ensureAgentService(),
|
|
239
246
|
getChannelManager: () => this.channelManager,
|
|
240
|
-
getCronService: () => this.cronService,
|
|
241
247
|
getHeartbeatService: () => this.heartbeatService,
|
|
242
248
|
getExtensionLoader: () => this.extensionLoader,
|
|
243
249
|
reconcileBrowserExtensionServer: () => this.reconcileBrowserExtensionServer(),
|
|
250
|
+
reconcileDreamingAutomations: () => this.reconcileDreamingAutomations(),
|
|
244
251
|
getChannelsStatus: () => this.getChannelsStatus(),
|
|
245
252
|
emit: (type, payload) => this.emit(type, payload)
|
|
246
253
|
});
|
|
@@ -251,7 +258,6 @@ var GatewayService = class {
|
|
|
251
258
|
}
|
|
252
259
|
ensureAgentService() {
|
|
253
260
|
if (this._agentService) return this._agentService;
|
|
254
|
-
const cronRef = { service: this.cronService };
|
|
255
261
|
this._agentService = new AgentService(this.bus, {
|
|
256
262
|
workspace: this.workspacePath,
|
|
257
263
|
model: getAgentDefaultModelRef(this.config),
|
|
@@ -280,7 +286,7 @@ var GatewayService = class {
|
|
|
280
286
|
});
|
|
281
287
|
},
|
|
282
288
|
extensionRegistry: this.extensionLoader?.getRegistry(),
|
|
283
|
-
|
|
289
|
+
getAutomationService: () => this.automationService,
|
|
284
290
|
getWorkflowRunService: () => this.createWorkflowRunService(),
|
|
285
291
|
sourceContextResolver: async (binding) => {
|
|
286
292
|
if (binding.kind !== "note") return null;
|
|
@@ -305,16 +311,11 @@ var GatewayService = class {
|
|
|
305
311
|
getModelForSession: (sk) => this._agentService.getModelForSession(sk),
|
|
306
312
|
switchModelForSession: (sk, id) => this._agentService.switchModelForSession(sk, id)
|
|
307
313
|
});
|
|
308
|
-
this.
|
|
314
|
+
this.automationService.setDeps({
|
|
309
315
|
agentService: this._agentService,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
sessionStore: this.sessionIndex.getStore(),
|
|
313
|
-
getDefaultCronAgentId: () => getDefaultAgentId(this.config),
|
|
314
|
-
workflowRunService: this.createWorkflowRunService(),
|
|
315
|
-
goalRunner: this.createGoalRunner()
|
|
316
|
+
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
317
|
+
workflowRunService: this.createWorkflowRunService()
|
|
316
318
|
});
|
|
317
|
-
cronRef.service = this.cronService;
|
|
318
319
|
this._agentService.persistentGoals.setWebchatContinuationScheduler((sessionKey, message) => {
|
|
319
320
|
const scheduleWhenIdle = () => {
|
|
320
321
|
if (this._agentService.getInboundTurnDepth(sessionKey) > 0) {
|
|
@@ -336,7 +337,6 @@ var GatewayService = class {
|
|
|
336
337
|
this.heartbeatService = new HeartbeatService({
|
|
337
338
|
agentService: this.ensureAgentService(),
|
|
338
339
|
messageBus: this.bus,
|
|
339
|
-
cronService: this.cronService,
|
|
340
340
|
sessionStore: this.sessionIndex.getStore(),
|
|
341
341
|
getConfig: () => this.config
|
|
342
342
|
});
|
|
@@ -614,15 +614,12 @@ var GatewayService = class {
|
|
|
614
614
|
}, "Gateway channel startup phase-1 complete");
|
|
615
615
|
await trace.measure("sessions.initialize", () => this.sessionIndex.initialize());
|
|
616
616
|
log.debug("Session manager initialized");
|
|
617
|
-
this.
|
|
617
|
+
this.automationService.setDeps({
|
|
618
618
|
agentService: this.agentService,
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
sessionStore: this.sessionIndex.getStore(),
|
|
622
|
-
getDefaultCronAgentId: () => getDefaultAgentId(this.config),
|
|
623
|
-
workflowRunService: this.createWorkflowRunService(),
|
|
624
|
-
goalRunner: this.createGoalRunner()
|
|
619
|
+
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
620
|
+
workflowRunService: this.createWorkflowRunService()
|
|
625
621
|
});
|
|
622
|
+
this.startAutomationProductEventBridge();
|
|
626
623
|
await trace.measure("workflows.reconcile", () => this.reconcileInterruptedWorkflowRuns());
|
|
627
624
|
this.sessionIndex.on("sessionUpdated", (data) => {
|
|
628
625
|
this.emit("session.updated", {
|
|
@@ -631,7 +628,8 @@ var GatewayService = class {
|
|
|
631
628
|
tags: data.tags
|
|
632
629
|
});
|
|
633
630
|
});
|
|
634
|
-
|
|
631
|
+
await trace.measure("automations.initialize", () => this.automationService.initialize());
|
|
632
|
+
await trace.measure("dreaming.reconcile", () => this.reconcileDreamingAutomations());
|
|
635
633
|
await this.notesService.initialize();
|
|
636
634
|
this.ensureHeartbeatService().start(heartbeatRunnerConfigFromConfig(this.config));
|
|
637
635
|
this.connectorSupervisor = startConnectorSupervisor({
|
|
@@ -775,7 +773,11 @@ var GatewayService = class {
|
|
|
775
773
|
this.lastChannelConnectDeferMode = "auto";
|
|
776
774
|
this.lastChannelConnectDeferSource = "off";
|
|
777
775
|
await this.channelManager.stop();
|
|
778
|
-
await this.
|
|
776
|
+
await this.automationService.stop();
|
|
777
|
+
this.stopAutomationProductEventBridge?.();
|
|
778
|
+
this.stopAutomationProductEventBridge = null;
|
|
779
|
+
this.stopSessionTranscriptAutomationEvents?.();
|
|
780
|
+
this.stopSessionTranscriptAutomationEvents = null;
|
|
779
781
|
await this.notesService.flush();
|
|
780
782
|
buckets.destroyAll();
|
|
781
783
|
closeXopcDatabase();
|
|
@@ -1074,8 +1076,14 @@ var GatewayService = class {
|
|
|
1074
1076
|
getEffectiveListenPort() {
|
|
1075
1077
|
return resolveEffectiveGatewayPort(this.config, this.serviceConfig.listenPort);
|
|
1076
1078
|
}
|
|
1077
|
-
get
|
|
1078
|
-
return this.
|
|
1079
|
+
get automationServiceInstance() {
|
|
1080
|
+
return this.automationService;
|
|
1081
|
+
}
|
|
1082
|
+
async reconcileDreamingAutomations() {
|
|
1083
|
+
await reconcileDreamingAutomations({
|
|
1084
|
+
config: this.config,
|
|
1085
|
+
automationService: this.automationService
|
|
1086
|
+
});
|
|
1079
1087
|
}
|
|
1080
1088
|
get notesServiceInstance() {
|
|
1081
1089
|
return this.notesService;
|
|
@@ -1134,6 +1142,32 @@ var GatewayService = class {
|
|
|
1134
1142
|
this.sse.emit(type, payload);
|
|
1135
1143
|
this.createGoalNotificationService().handleGatewayEvent(type, payload);
|
|
1136
1144
|
}
|
|
1145
|
+
startAutomationProductEventBridge() {
|
|
1146
|
+
this.stopAutomationProductEventBridge?.();
|
|
1147
|
+
this.stopSessionTranscriptAutomationEvents?.();
|
|
1148
|
+
this.stopAutomationProductEventBridge = onAutomationProductEvent((event) => {
|
|
1149
|
+
this.automationService.triggerEvent(event).catch((err) => {
|
|
1150
|
+
const em = err instanceof Error ? err.message : String(err);
|
|
1151
|
+
log.warn({
|
|
1152
|
+
err,
|
|
1153
|
+
eventType: event.type,
|
|
1154
|
+
source: event.source
|
|
1155
|
+
}, `Automation product event failed: ${em}`);
|
|
1156
|
+
});
|
|
1157
|
+
});
|
|
1158
|
+
this.stopSessionTranscriptAutomationEvents = onSessionTranscriptUpdate((update) => {
|
|
1159
|
+
if (!update.sessionKey || update.sessionKey.includes(":automation:")) return;
|
|
1160
|
+
publishAutomationProductEvent({
|
|
1161
|
+
type: "session.transcript.updated",
|
|
1162
|
+
source: "sessions",
|
|
1163
|
+
payload: {
|
|
1164
|
+
sessionKey: update.sessionKey,
|
|
1165
|
+
messageId: update.messageId,
|
|
1166
|
+
hasMessage: update.message !== void 0
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1137
1171
|
/** Replay events since `lastEventId` for SSE reconnection. */
|
|
1138
1172
|
getEventsSince(sessionId, lastEventId) {
|
|
1139
1173
|
return this.sse.getEventsSince(sessionId, lastEventId);
|