@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
|
@@ -13,9 +13,10 @@ import type { TypedEventBus } from './events.js';
|
|
|
13
13
|
import type { ExtensionHookEvent, ExtensionHookHandler, HookOptions, HookHandlerMap } from './hooks.js';
|
|
14
14
|
import type { ChannelPlugin } from '../../channels/plugin-types.js';
|
|
15
15
|
import type { SessionMetadata } from '../../session/types.js';
|
|
16
|
-
import type { FlagConfig, FlagValue, ShortcutConfig } from './
|
|
16
|
+
import type { FlagConfig, FlagValue, ShortcutConfig } from './registration.js';
|
|
17
17
|
import type { ProviderPlugin } from './providers.js';
|
|
18
18
|
import type { TuiExtensionRegistrar } from './tui.js';
|
|
19
|
+
import type { Migration } from '../../migrations/types.js';
|
|
19
20
|
export interface ExtensionDefinition {
|
|
20
21
|
/** Unique extension identifier */
|
|
21
22
|
id: string;
|
|
@@ -120,6 +121,8 @@ export interface ExtensionApi {
|
|
|
120
121
|
* Register a reload handler when config paths matching this extension change during hot reload.
|
|
121
122
|
*/
|
|
122
123
|
registerReload(handler: ExtensionReloadHandler): void;
|
|
124
|
+
/** Register a migration contributed by this extension. */
|
|
125
|
+
registerMigration(migration: Migration): void;
|
|
123
126
|
registerService(service: ExtensionService): void;
|
|
124
127
|
registerGatewayMethod(method: string, handler: GatewayMethodHandler): void;
|
|
125
128
|
/**
|
|
@@ -199,6 +202,10 @@ export interface ExtensionReloadRegistration {
|
|
|
199
202
|
/** Config path prefixes this handler cares about. Empty = any extension-related change passed to matcher. */
|
|
200
203
|
configPrefixes: string[];
|
|
201
204
|
}
|
|
205
|
+
export interface ExtensionMigrationRegistration {
|
|
206
|
+
extensionId: string;
|
|
207
|
+
migration: Migration;
|
|
208
|
+
}
|
|
202
209
|
/**
|
|
203
210
|
* Chat command registered by an extension (bridged into CommandRegistry with category `extension`).
|
|
204
211
|
*/
|
|
@@ -237,4 +244,6 @@ export interface ExtensionRegistry {
|
|
|
237
244
|
getCommand(name: string): ExtensionCommand | undefined;
|
|
238
245
|
addCliRegistration(reg: ExtensionCliRegistration): void;
|
|
239
246
|
getCliRegistrations(): readonly ExtensionCliRegistration[];
|
|
247
|
+
addMigrationRegistration?(reg: ExtensionMigrationRegistration): void;
|
|
248
|
+
getMigrationRegistrations?(): readonly ExtensionMigrationRegistration[];
|
|
240
249
|
}
|
|
@@ -9,6 +9,6 @@ export * from './tools.js';
|
|
|
9
9
|
export * from './hooks.js';
|
|
10
10
|
export * from './events.js';
|
|
11
11
|
export * from './loader.js';
|
|
12
|
-
export type { ProviderConfig, ProviderApiType, ModelConfig, OAuthConfig, OAuthCallbacks, OAuthCredentials, FlagConfig, FlagValue, ShortcutConfig, ShortcutHandler } from './
|
|
12
|
+
export type { ProviderConfig, ProviderApiType, ModelConfig, OAuthConfig, OAuthCallbacks, OAuthCredentials, FlagConfig, FlagValue, ShortcutConfig, ShortcutHandler } from './registration.js';
|
|
13
13
|
export * from './providers.js';
|
|
14
14
|
export * from './tui.js';
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Built-in agent tool `name` values for gateway admin UI (disable toggles).
|
|
3
3
|
* Extension tools are not listed; users can still add arbitrary strings in config.
|
|
4
4
|
*/
|
|
5
|
-
export declare const GATEWAY_BUILTIN_TOOL_IDS: readonly ["read_file", "write_file", "edit_file", "list_dir", "grep", "find", "shell", "session_status", "dreaming", "tool_manual", "clarify", "todo", "skills_list", "skill_view", "skill_manage", "web_search", "web_fetch", "web_extract", "send_message", "send_media", "read_media", "create_share", "text_to_speech", "memory_search", "memory_get", "curated_memory", "session_search", "
|
|
5
|
+
export declare const GATEWAY_BUILTIN_TOOL_IDS: readonly ["read_file", "write_file", "edit_file", "list_dir", "grep", "find", "shell", "session_status", "dreaming", "tool_manual", "clarify", "todo", "skills_list", "skill_view", "skill_manage", "web_search", "web_fetch", "web_extract", "send_message", "send_media", "read_media", "create_share", "text_to_speech", "memory_search", "memory_get", "curated_memory", "session_search", "automation", "workflow", "delegate_task", "execute_code", "image", "image_generate", "browser_use", "extensions", "bundle-mcp"];
|
|
6
6
|
export type GatewayBuiltinToolId = (typeof GATEWAY_BUILTIN_TOOL_IDS)[number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-builtin-tools.js","names":[],"sources":["../../../src/gateway/agent-builtin-tools.ts"],"sourcesContent":["/**\n * Built-in agent tool `name` values for gateway admin UI (disable toggles).\n * Extension tools are not listed; users can still add arbitrary strings in config.\n */\nexport const GATEWAY_BUILTIN_TOOL_IDS = [\n 'read_file',\n 'write_file',\n 'edit_file',\n 'list_dir',\n 'grep',\n 'find',\n 'shell',\n 'session_status',\n 'dreaming',\n 'tool_manual',\n 'clarify',\n 'todo',\n 'skills_list',\n 'skill_view',\n 'skill_manage',\n 'web_search',\n 'web_fetch',\n 'web_extract',\n 'send_message',\n 'send_media',\n 'read_media',\n 'create_share',\n 'text_to_speech',\n 'memory_search',\n 'memory_get',\n 'curated_memory',\n 'session_search',\n '
|
|
1
|
+
{"version":3,"file":"agent-builtin-tools.js","names":[],"sources":["../../../src/gateway/agent-builtin-tools.ts"],"sourcesContent":["/**\n * Built-in agent tool `name` values for gateway admin UI (disable toggles).\n * Extension tools are not listed; users can still add arbitrary strings in config.\n */\nexport const GATEWAY_BUILTIN_TOOL_IDS = [\n 'read_file',\n 'write_file',\n 'edit_file',\n 'list_dir',\n 'grep',\n 'find',\n 'shell',\n 'session_status',\n 'dreaming',\n 'tool_manual',\n 'clarify',\n 'todo',\n 'skills_list',\n 'skill_view',\n 'skill_manage',\n 'web_search',\n 'web_fetch',\n 'web_extract',\n 'send_message',\n 'send_media',\n 'read_media',\n 'create_share',\n 'text_to_speech',\n 'memory_search',\n 'memory_get',\n 'curated_memory',\n 'session_search',\n 'automation',\n 'workflow',\n 'delegate_task',\n 'execute_code',\n 'image',\n 'image_generate',\n 'browser_use',\n 'extensions',\n 'bundle-mcp',\n] as const;\n\nexport type GatewayBuiltinToolId = (typeof GATEWAY_BUILTIN_TOOL_IDS)[number];\n"],"mappings":";;;;;AAIA,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
@@ -95,6 +95,7 @@ export type UpdateAgentBody = {
|
|
|
95
95
|
defaultRole?: string | null;
|
|
96
96
|
roles?: Record<string, {
|
|
97
97
|
model: string;
|
|
98
|
+
fallbacks?: string[];
|
|
98
99
|
description?: string;
|
|
99
100
|
}>;
|
|
100
101
|
} | null;
|
|
@@ -134,6 +135,13 @@ export declare function writeAgentProfileFile(cfg: Config, agentId: string, name
|
|
|
134
135
|
agentId: string;
|
|
135
136
|
path: string;
|
|
136
137
|
}>>;
|
|
138
|
+
export declare function readUserProfileFile(): Promise<AgentAdminResult<{
|
|
139
|
+
content: string;
|
|
140
|
+
path: string;
|
|
141
|
+
}>>;
|
|
142
|
+
export declare function writeUserProfileFile(content: string): Promise<AgentAdminResult<{
|
|
143
|
+
path: string;
|
|
144
|
+
}>>;
|
|
137
145
|
export declare function readAgentAvatarFile(cfg: Config, agentId: string): Promise<AgentAdminResult<{
|
|
138
146
|
agentId: string;
|
|
139
147
|
buffer: Buffer;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
2
|
-
import {
|
|
2
|
+
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
3
3
|
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
4
|
-
import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
|
|
5
|
-
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES } from "../agent/context/workspace.js";
|
|
4
|
+
import { WORKSPACE_FILES, init_paths, resolveUserProfilePath } from "../config/paths.js";
|
|
5
|
+
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
|
|
6
6
|
import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
|
|
7
|
-
import { applyAgentConfig, findAgentEntryIndex, pruneAgentConfig, removeAgentDirsFromDisk } from "../commands/agents.config.js";
|
|
7
|
+
import { applyAgentConfig, findAgentEntryIndex, getAgentDeleteBlocker, pruneAgentConfig, removeAgentDirsFromDisk } from "../commands/agents.config.js";
|
|
8
8
|
import { resolveEffectiveTypedModels } from "../config/agent-typed-models.js";
|
|
9
9
|
import { GATEWAY_BUILTIN_TOOL_IDS } from "./agent-builtin-tools.js";
|
|
10
10
|
import { seedAgentProfileMarkdownFiles } from "../agent/context/workspace-seed.js";
|
|
11
|
-
import { join, resolve } from "node:path";
|
|
11
|
+
import { dirname, join, resolve } from "node:path";
|
|
12
12
|
import { cp, mkdir, readFile, readdir, realpath, stat, unlink, writeFile } from "node:fs/promises";
|
|
13
13
|
//#region src/gateway/agents-admin.ts
|
|
14
14
|
/**
|
|
@@ -121,7 +121,8 @@ function getGatewayAgentEffectiveManifest(cfg, agentIdRaw) {
|
|
|
121
121
|
ok: true,
|
|
122
122
|
data: resolveEffectiveAgentManifest({
|
|
123
123
|
agent: entry,
|
|
124
|
-
presets: cfg.agents.capabilityPresets
|
|
124
|
+
presets: cfg.agents.capabilityPresets,
|
|
125
|
+
defaultPresetId: cfg.agents.defaultPreset
|
|
125
126
|
})
|
|
126
127
|
};
|
|
127
128
|
} catch (err) {
|
|
@@ -132,14 +133,6 @@ function getGatewayAgentEffectiveManifest(cfg, agentIdRaw) {
|
|
|
132
133
|
};
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
|
-
function requireNonMain(id) {
|
|
136
|
-
if (normalizeAgentId(id) === "main") return {
|
|
137
|
-
ok: false,
|
|
138
|
-
error: `"${DEFAULT_AGENT_ID}" is reserved`,
|
|
139
|
-
status: 400
|
|
140
|
-
};
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
136
|
function prepareCreateAgent(cfg, body) {
|
|
144
137
|
const workspace = body.workspace?.trim() ?? "";
|
|
145
138
|
if (!workspace) return {
|
|
@@ -269,10 +262,6 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
269
262
|
},
|
|
270
263
|
responsibilities: { primary: ["Help the user complete tasks"] },
|
|
271
264
|
workspace: { root: `~/.xopc/workspace/${agentId}` },
|
|
272
|
-
models: {
|
|
273
|
-
defaultRole: "deep",
|
|
274
|
-
roles: { deep: { model: "openai/gpt-4.1" } }
|
|
275
|
-
},
|
|
276
265
|
tools: { builtin: {} },
|
|
277
266
|
skills: { mode: "all" },
|
|
278
267
|
memory: {
|
|
@@ -309,11 +298,7 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
309
298
|
if (nextExtends.length > 0) entry.extends = nextExtends;
|
|
310
299
|
else delete entry.extends;
|
|
311
300
|
}
|
|
312
|
-
if (body.models !== void 0) if (body.models === null)
|
|
313
|
-
ok: false,
|
|
314
|
-
error: "models cannot be null; every agent manifest needs model roles",
|
|
315
|
-
status: 400
|
|
316
|
-
};
|
|
301
|
+
if (body.models !== void 0) if (body.models === null) delete entry.models;
|
|
317
302
|
else {
|
|
318
303
|
if (body.models.defaultRole !== void 0) {
|
|
319
304
|
if (body.models.defaultRole === null || !body.models.defaultRole.trim()) return {
|
|
@@ -322,8 +307,9 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
322
307
|
status: 400
|
|
323
308
|
};
|
|
324
309
|
entry.models = {
|
|
325
|
-
|
|
326
|
-
|
|
310
|
+
defaultRole: body.models.defaultRole.trim(),
|
|
311
|
+
roles: entry.models?.roles ?? {},
|
|
312
|
+
...entry.models?.policy ? { policy: entry.models.policy } : {}
|
|
327
313
|
};
|
|
328
314
|
}
|
|
329
315
|
if (Object.hasOwn(body.models, "roles")) {
|
|
@@ -331,22 +317,31 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
331
317
|
const roles = Object.fromEntries(Object.entries(body.models.roles).map(([id, row]) => ({
|
|
332
318
|
id: id.trim(),
|
|
333
319
|
model: row.model.trim(),
|
|
320
|
+
fallbacks: (row.fallbacks ?? []).map((ref) => ref.trim()).filter(Boolean),
|
|
334
321
|
description: row.description?.trim()
|
|
335
|
-
})).filter((row) => row.id && row.model).map((row) => [row.id,
|
|
322
|
+
})).filter((row) => row.id && row.model).map((row) => [row.id, {
|
|
336
323
|
model: row.model,
|
|
337
|
-
|
|
338
|
-
|
|
324
|
+
...row.fallbacks.length > 0 ? { fallbacks: row.fallbacks } : {},
|
|
325
|
+
...row.description ? { description: row.description } : {}
|
|
326
|
+
}]));
|
|
339
327
|
entry.models = {
|
|
340
|
-
|
|
341
|
-
roles
|
|
328
|
+
defaultRole: entry.models?.defaultRole ?? Object.keys(roles)[0] ?? "deep",
|
|
329
|
+
roles,
|
|
330
|
+
...entry.models?.policy ? { policy: entry.models.policy } : {}
|
|
342
331
|
};
|
|
343
332
|
}
|
|
344
333
|
}
|
|
345
|
-
|
|
334
|
+
const roles = entry.models?.roles ?? {};
|
|
335
|
+
const defaultRole = entry.models?.defaultRole ?? Object.keys(roles)[0];
|
|
336
|
+
if (!defaultRole || !roles[defaultRole]) return {
|
|
346
337
|
ok: false,
|
|
347
338
|
error: "models.defaultRole must reference models.roles",
|
|
348
339
|
status: 400
|
|
349
340
|
};
|
|
341
|
+
entry.models = {
|
|
342
|
+
...entry.models,
|
|
343
|
+
defaultRole
|
|
344
|
+
};
|
|
350
345
|
}
|
|
351
346
|
if (body.skills !== void 0) if (body.skills === null) entry.skills = { mode: "all" };
|
|
352
347
|
else {
|
|
@@ -385,8 +380,12 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
385
380
|
}
|
|
386
381
|
function prepareDeleteAgent(cfg, agentIdRaw) {
|
|
387
382
|
const agentId = normalizeAgentId(agentIdRaw);
|
|
388
|
-
const
|
|
389
|
-
if (
|
|
383
|
+
const blocker = getAgentDeleteBlocker(cfg, agentId);
|
|
384
|
+
if (blocker) return {
|
|
385
|
+
ok: false,
|
|
386
|
+
error: blocker,
|
|
387
|
+
status: 400
|
|
388
|
+
};
|
|
390
389
|
if (findAgentEntryIndex(listAgentEntries(cfg), agentId) < 0) return {
|
|
391
390
|
ok: false,
|
|
392
391
|
error: `agent "${agentId}" not found`,
|
|
@@ -444,6 +443,7 @@ async function listAgentProfileFiles(cfg, agentId) {
|
|
|
444
443
|
updatedAtMs: st.mtimeMs
|
|
445
444
|
});
|
|
446
445
|
} catch {
|
|
446
|
+
if (!REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET.has(name)) continue;
|
|
447
447
|
files.push({
|
|
448
448
|
name,
|
|
449
449
|
missing: true
|
|
@@ -521,6 +521,35 @@ async function writeAgentProfileFile(cfg, agentId, name, content) {
|
|
|
521
521
|
}
|
|
522
522
|
};
|
|
523
523
|
}
|
|
524
|
+
async function readUserProfileFile() {
|
|
525
|
+
const path = resolveUserProfilePath();
|
|
526
|
+
try {
|
|
527
|
+
return {
|
|
528
|
+
ok: true,
|
|
529
|
+
data: {
|
|
530
|
+
content: await readFile(path, "utf-8"),
|
|
531
|
+
path
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
} catch {
|
|
535
|
+
return {
|
|
536
|
+
ok: true,
|
|
537
|
+
data: {
|
|
538
|
+
content: "",
|
|
539
|
+
path
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
async function writeUserProfileFile(content) {
|
|
545
|
+
const path = resolveUserProfilePath();
|
|
546
|
+
await mkdir(dirname(path), { recursive: true });
|
|
547
|
+
await writeFile(path, content, "utf-8");
|
|
548
|
+
return {
|
|
549
|
+
ok: true,
|
|
550
|
+
data: { path }
|
|
551
|
+
};
|
|
552
|
+
}
|
|
524
553
|
const AGENT_AVATAR_MAX_BYTES = 512 * 1024;
|
|
525
554
|
const AGENT_AVATAR_BASENAME = "agent-avatar";
|
|
526
555
|
const AGENT_AVATAR_EXTENSIONS = [
|
|
@@ -668,6 +697,6 @@ async function deleteAgentAvatarFile(cfg, agentId) {
|
|
|
668
697
|
};
|
|
669
698
|
}
|
|
670
699
|
//#endregion
|
|
671
|
-
export { deleteAgentAvatarFile, extractAvatarFromIdentityMarkdown, finalizeCreateAgentDirs, getGatewayAgentEffectiveManifest, listAgentProfileFiles, listGatewayAgents, parseIdentityMarkdown, prepareCreateAgent, prepareDeleteAgent, prepareUpdateAgent, readAgentAvatarFile, readAgentProfileFile, runAfterDeletePurge, writeAgentAvatarFromBase64, writeAgentProfileFile };
|
|
700
|
+
export { deleteAgentAvatarFile, extractAvatarFromIdentityMarkdown, finalizeCreateAgentDirs, getGatewayAgentEffectiveManifest, listAgentProfileFiles, listGatewayAgents, parseIdentityMarkdown, prepareCreateAgent, prepareDeleteAgent, prepareUpdateAgent, readAgentAvatarFile, readAgentProfileFile, readUserProfileFile, runAfterDeletePurge, writeAgentAvatarFromBase64, writeAgentProfileFile, writeUserProfileFile };
|
|
672
701
|
|
|
673
702
|
//# sourceMappingURL=agents-admin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents-admin.js","names":["pathResolve"],"sources":["../../../src/gateway/agents-admin.ts"],"sourcesContent":["/**\n * Gateway REST helpers for multi-agent management.\n */\n\nimport { cp, mkdir, readdir, readFile, realpath, stat, unlink, writeFile } from 'node:fs/promises';\nimport { join, resolve as pathResolve } from 'node:path';\n\nimport {\n DEFAULT_AGENT_ID,\n listAgentEntries,\n normalizeAgentId,\n resolveAgentDir,\n resolveAgentProfileDir,\n resolveAgentWorkspaceDir,\n resolveDefaultAgentId,\n resolveUserPath,\n validateAgentIdForNewAgent,\n} from '../agent/agent-scope.js';\nimport { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES } from '../agent/context/workspace.js';\nimport { seedAgentProfileMarkdownFiles } from '../agent/context/workspace-seed.js';\nimport {\n resolveEffectiveAgentManifest,\n type ResolveManifestResult,\n} from '../agent-manifest/resolver.js';\nimport {\n applyAgentConfig,\n findAgentEntryIndex,\n pruneAgentConfig,\n removeAgentDirsFromDisk,\n} from '../commands/agents.config.js';\nimport type { AgentModelsConfig, Config } from '../config/schema.js';\nimport { WORKSPACE_FILES } from '../config/paths.js';\nimport { resolveEffectiveAgentProfile } from '../config/agent-profile.js';\nimport type { AgentTypedModel } from '../config/schema.js';\nimport { resolveEffectiveTypedModels } from '../config/agent-typed-models.js';\nimport { GATEWAY_BUILTIN_TOOL_IDS } from './agent-builtin-tools.js';\nimport { isPathUnderWorkspace, resolveWorkspaceSafePath } from './workspace-editor-path.js';\n\nconst EDITABLE_PROFILE_MARKDOWN_NAMES = new Set<string>([...AGENT_PROFILE_MARKDOWN_SYSTEM_FILES]);\n\nexport type GatewayAgentTypedModelsInfo = {\n defaultRole: string;\n preset: AgentTypedModel[];\n entry?: AgentTypedModel[];\n effective: AgentTypedModel[];\n};\n\nexport type GatewayAgentRow = {\n id: string;\n name?: string;\n description?: string;\n language?: string;\n /** Value from `IDENTITY.md` **Avatar:** line when present (may be URL, `xopc:…`, etc.). */\n avatar?: string;\n workspace: string;\n /** Absolute directory for profile Markdown (`SOUL.md`, …) and gateway avatars: `agents/<id>/profile/`. */\n profileDir: string;\n model?: { primary?: string; fallbacks?: string[] };\n typedModels: GatewayAgentTypedModelsInfo;\n extends: string[];\n isDefault: boolean;\n skills: {\n preset: string[];\n entry?: string[];\n effectiveAllowlist?: string[];\n };\n tools: {\n presetDenied: string[];\n entryDisable: string[];\n effectiveDisable: string[];\n };\n};\n\nexport type GatewayAgentsListResponse = {\n defaultId: string;\n agents: GatewayAgentRow[];\n builtinToolIds: string[];\n};\n\nexport type GatewayAgentEffectiveManifestResponse = ResolveManifestResult;\n\nfunction collectAgentIdsForList(cfg: Config): string[] {\n const entries = listAgentEntries(cfg).filter((e) => e.enabled !== false);\n const defaultId = resolveDefaultAgentId(cfg);\n if (entries.length === 0) {\n return [defaultId];\n }\n const ids = new Set<string>();\n for (const e of entries) {\n ids.add(normalizeAgentId(e.id));\n }\n ids.add(defaultId);\n return [...ids];\n}\n\nfunction rolesToTypedModels(\n roles: Record<string, { model: string; description?: string }> | undefined,\n): AgentTypedModel[] {\n return Object.entries(roles ?? {})\n .map(([id, role]) => ({ id, ...role }))\n .sort((a, b) => a.id.localeCompare(b.id));\n}\n\n/** Extract `**Avatar:**` value from profile IDENTITY.md (same line shape as the gateway console parser). */\nexport function extractAvatarFromIdentityMarkdown(content: string): string | undefined {\n return parseIdentityMarkdown(content).avatar || undefined;\n}\n\nexport function parseIdentityMarkdown(content: string): {\n name?: string;\n description?: string;\n language?: string;\n avatar?: string;\n} {\n const out: { name?: string; description?: string; language?: string; avatar?: string } = {};\n for (const line of content.split('\\n')) {\n const match = line.match(/^[-*]\\s+\\*\\*(Name|Description|Language|Avatar):\\*\\*\\s*(.*)/i);\n if (match) {\n const key = match[1]?.toLowerCase();\n const v = match[2]?.trim() ?? '';\n if (!v || /^_\\(.*\\)_$/.test(v)) continue;\n if (key === 'name') out.name = v;\n if (key === 'description') out.description = v;\n if (key === 'language') out.language = v;\n if (key === 'avatar') out.avatar = v;\n }\n }\n return out;\n}\n\nexport async function listGatewayAgents(\n cfg: Config,\n _options: { locale?: string } = {},\n): Promise<GatewayAgentsListResponse> {\n const defaultId = resolveDefaultAgentId(cfg);\n const agents: GatewayAgentRow[] = [];\n const presetSkills: string[] | undefined = undefined;\n const presetDenied: string[] = [];\n const presetTypedModels: ReturnType<typeof rolesToTypedModels> = [];\n for (const id of collectAgentIdsForList(cfg)) {\n const profile = resolveEffectiveAgentProfile(cfg, id);\n const entry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === id);\n const model =\n profile.primaryModelRef || profile.fallbacks.length > 0\n ? {\n ...(profile.primaryModelRef ? { primary: profile.primaryModelRef } : {}),\n ...(profile.fallbacks.length > 0 ? { fallbacks: profile.fallbacks } : {}),\n }\n : undefined;\n const entrySkills = entry?.skills.mode === 'allowlist' ? entry.skills.allow ?? [] : undefined;\n const entryDisable = Object.entries(entry?.tools.builtin ?? {})\n .filter(([, policy]) => policy.mode === 'deny')\n .map(([name]) => name);\n const entryTypedModels = rolesToTypedModels(entry?.models?.roles);\n const effectiveTypedModels = [...resolveEffectiveTypedModels(cfg, id).values()].sort((a, b) =>\n a.id.localeCompare(b.id),\n );\n let identity: ReturnType<typeof parseIdentityMarkdown> = {};\n try {\n const identityPath = join(resolveAgentProfileDir(cfg, id), WORKSPACE_FILES.IDENTITY);\n const content = await readFile(identityPath, 'utf-8');\n identity = parseIdentityMarkdown(content);\n } catch {\n /* missing IDENTITY.md or unreadable */\n }\n agents.push({\n id,\n ...(identity.name ? { name: identity.name } : {}),\n ...(identity.description ? { description: identity.description } : {}),\n ...(identity.language ? { language: identity.language } : {}),\n ...(identity.avatar ? { avatar: identity.avatar } : {}),\n workspace: profile.resolvedWorkspacePath,\n profileDir: resolveAgentProfileDir(cfg, id),\n ...(model ? { model } : {}),\n typedModels: {\n defaultRole: profile.manifest.models.defaultRole,\n preset: [...presetTypedModels],\n ...(entryTypedModels.length > 0 ? { entry: entryTypedModels } : {}),\n effective: effectiveTypedModels,\n },\n extends: [...(entry?.extends ?? [])],\n isDefault: id === defaultId,\n skills: {\n preset: presetSkills ? [...presetSkills] : [],\n ...(entrySkills !== undefined ? { entry: [...entrySkills] } : {}),\n ...(profile.skillsAllowlist !== undefined\n ? { effectiveAllowlist: [...profile.skillsAllowlist] }\n : {}),\n },\n tools: {\n presetDenied: [...presetDenied],\n entryDisable: [...entryDisable],\n effectiveDisable: [...profile.tools.denied].sort((a, b) => a.localeCompare(b)),\n },\n });\n }\n agents.sort((a, b) => a.id.localeCompare(b.id));\n return { defaultId, agents, builtinToolIds: [...GATEWAY_BUILTIN_TOOL_IDS] };\n}\n\nexport function getGatewayAgentEffectiveManifest(\n cfg: Config,\n agentIdRaw: string,\n): AgentAdminResult<GatewayAgentEffectiveManifestResponse> {\n const agentId = normalizeAgentId(agentIdRaw);\n const entry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === agentId);\n if (!entry) {\n return { ok: false, error: `agent \"${agentId}\" not found`, status: 404 };\n }\n try {\n return {\n ok: true,\n data: resolveEffectiveAgentManifest({\n agent: entry,\n presets: cfg.agents.capabilityPresets,\n }),\n };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n status: 400,\n };\n }\n}\n\nexport type CreateAgentBody = {\n /** Optional id seed; normalized agent id defaults from `profileFiles[\"IDENTITY.md\"]` name when omitted. */\n id?: string;\n workspace: string;\n models?: AgentModelsConfig;\n /** Initial `agents.list[].skills` for the new entry. */\n skills?: string[];\n /** Initial `agents.list[].tools` for the new entry. */\n tools?: NonNullable<Config['agents']['list']>[number]['tools'];\n /** Profile markdown files to write after seeding (e.g. `IDENTITY.md`, `SOUL.md`). */\n profileFiles?: Record<string, string>;\n /** Clone from an existing agent id — copies config entry fields and profile directory. */\n cloneFrom?: string;\n};\n\nexport type AgentAdminHttpStatus = 400 | 404 | 409;\n\nexport type AgentAdminResult<T> =\n | { ok: true; data: T }\n | { ok: false; error: string; status?: AgentAdminHttpStatus };\n\nfunction requireNonMain(id: string): AgentAdminResult<never> | null {\n if (normalizeAgentId(id) === DEFAULT_AGENT_ID) {\n return { ok: false, error: `\"${DEFAULT_AGENT_ID}\" is reserved`, status: 400 };\n }\n return null;\n}\n\nexport function prepareCreateAgent(\n cfg: Config,\n body: CreateAgentBody,\n): AgentAdminResult<{ nextConfig: Config; agentId: string; workspace: string }> {\n const workspace = body.workspace?.trim() ?? '';\n if (!workspace) {\n return { ok: false, error: 'workspace is required', status: 400 };\n }\n if (body.profileFiles !== undefined) {\n if (typeof body.profileFiles !== 'object' || body.profileFiles === null || Array.isArray(body.profileFiles)) {\n return { ok: false, error: 'profileFiles must be an object', status: 400 };\n }\n for (const [name, content] of Object.entries(body.profileFiles)) {\n const bad = assertAllowedFile(name);\n if (bad) {\n return bad;\n }\n if (typeof content !== 'string') {\n return { ok: false, error: `profileFiles[\"${name}\"] must be a string`, status: 400 };\n }\n }\n }\n if (!body.cloneFrom && typeof body.profileFiles?.[WORKSPACE_FILES.IDENTITY] !== 'string') {\n return { ok: false, error: `profileFiles[\"${WORKSPACE_FILES.IDENTITY}\"] is required`, status: 400 };\n }\n\n const identity = body.profileFiles?.[WORKSPACE_FILES.IDENTITY]\n ? parseIdentityMarkdown(body.profileFiles[WORKSPACE_FILES.IDENTITY])\n : {};\n const nameSeed = identity.name ?? body.id ?? '';\n const idRes = validateAgentIdForNewAgent(body.id, nameSeed);\n if (idRes.ok === false) {\n return { ok: false, error: idRes.error, status: 400 };\n }\n const agentId = idRes.agentId;\n if (findAgentEntryIndex(listAgentEntries(cfg), agentId) >= 0) {\n return { ok: false, error: `agent \"${agentId}\" already exists`, status: 409 };\n }\n\n // Resolve fields from cloneFrom source when present\n let cloneSourceEntry: ReturnType<typeof listAgentEntries>[number] | undefined;\n if (body.cloneFrom) {\n const srcId = normalizeAgentId(body.cloneFrom);\n cloneSourceEntry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === srcId);\n if (!cloneSourceEntry && srcId !== resolveDefaultAgentId(cfg)) {\n return { ok: false, error: `source agent \"${srcId}\" not found`, status: 404 };\n }\n }\n\n const wsAbs = resolveUserPath(workspace);\n\n const rawModels = body.models ?? cloneSourceEntry?.models;\n const effectiveModels =\n rawModels?.roles\n ? {\n defaultRole: rawModels.defaultRole ?? Object.keys(rawModels.roles)[0] ?? 'deep',\n roles: rawModels.roles,\n }\n : undefined;\n if (effectiveModels && !effectiveModels.roles[effectiveModels.defaultRole]) {\n return { ok: false, error: 'models.defaultRole must reference models.roles', status: 400 };\n }\n\n let next = applyAgentConfig(cfg, {\n agentId,\n workspace: wsAbs,\n ...(effectiveModels ? { models: effectiveModels } : {}),\n ...(body.skills !== undefined\n ? { skills: body.skills.map((s) => String(s).trim()).filter(Boolean) }\n : cloneSourceEntry?.skills.mode === 'allowlist' && body.cloneFrom\n ? { skills: [...(cloneSourceEntry.skills.allow ?? [])] }\n : {}),\n ...(body.tools !== undefined ? { tools: body.tools } : cloneSourceEntry?.tools && body.cloneFrom ? { tools: cloneSourceEntry.tools } : {}),\n });\n\n return { ok: true, data: { nextConfig: next, agentId, workspace: wsAbs } };\n}\n\nexport async function finalizeCreateAgentDirs(\n cfg: Config,\n agentId: string,\n opts?: { profileFiles?: Record<string, string>; cloneFrom?: string },\n): Promise<AgentAdminResult<void>> {\n const wsPath = resolveAgentWorkspaceDir(cfg, agentId);\n const profilePath = resolveAgentProfileDir(cfg, agentId);\n const adPath = resolveAgentDir(cfg, agentId);\n await mkdir(wsPath, { recursive: true });\n await mkdir(profilePath, { recursive: true });\n await mkdir(adPath, { recursive: true });\n const id = normalizeAgentId(agentId);\n const displayName = opts?.profileFiles?.[WORKSPACE_FILES.IDENTITY]\n ? (parseIdentityMarkdown(opts.profileFiles[WORKSPACE_FILES.IDENTITY]).name ?? id)\n : id;\n\n // When cloning, copy the entire source profile directory instead of seeding\n if (opts?.cloneFrom) {\n const srcProfilePath = resolveAgentProfileDir(cfg, normalizeAgentId(opts.cloneFrom));\n try {\n const srcStat = await stat(srcProfilePath);\n if (srcStat.isDirectory()) {\n const srcFiles = await readdir(srcProfilePath);\n for (const fileName of srcFiles) {\n const srcFile = join(srcProfilePath, fileName);\n const dstFile = join(profilePath, fileName);\n try {\n const fileStat = await stat(srcFile);\n if (fileStat.isFile()) {\n await cp(srcFile, dstFile);\n }\n } catch {\n /* skip unreadable files */\n }\n }\n }\n } catch {\n // Source profile dir doesn't exist — fall through to normal seed\n seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName });\n }\n } else {\n seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName });\n }\n\n const profileFiles = opts?.profileFiles;\n if (profileFiles && Object.keys(profileFiles).length > 0) {\n for (const [name, content] of Object.entries(profileFiles)) {\n const written = await writeAgentProfileFile(cfg, agentId, name, content);\n if (written.ok === false) {\n return written;\n }\n }\n }\n\n return { ok: true, data: undefined };\n}\n\nexport type UpdateAgentBody = {\n workspace?: string;\n extends?: string[];\n models?: {\n defaultRole?: string | null;\n roles?: Record<string, { model: string; description?: string }>;\n } | null;\n setDefault?: boolean;\n /** Replace `agents.list[].skills`; `null` resets to all skills. */\n skills?: string[] | null;\n /** Replace `agents.list[].tools`; `null` resets to no explicit policies. */\n tools?: NonNullable<Config['agents']['list']>[number]['tools'] | null;\n /** Replace `agents.list[].memory`; every agent manifest owns its memory policy. */\n memory?: NonNullable<Config['agents']['list']>[number]['memory'];\n};\n\nexport function prepareUpdateAgent(\n cfg: Config,\n agentIdRaw: string,\n body: UpdateAgentBody,\n): AgentAdminResult<{ nextConfig: Config }> {\n const agentId = normalizeAgentId(agentIdRaw);\n let list = [...listAgentEntries(cfg)];\n let idx = findAgentEntryIndex(list, agentId);\n if (idx < 0 && agentId === resolveDefaultAgentId(cfg)) {\n list = [...list, {\n id: agentId,\n enabled: true as const,\n identity: { name: agentId, role: 'Agent', language: 'en', tone: 'direct' },\n responsibilities: { primary: ['Help the user complete tasks'] },\n workspace: { root: `~/.xopc/workspace/${agentId}` },\n models: { defaultRole: 'deep', roles: { deep: { model: 'openai/gpt-4.1' } } },\n tools: { builtin: {} },\n skills: { mode: 'all' },\n memory: { mode: 'confirmWrite', sources: ['session', 'curated'], writePolicy: { curated: 'confirm' } },\n workflows: {},\n boundaries: { requiresConfirmation: [], forbidden: [], escalation: [] },\n }];\n idx = list.length - 1;\n }\n if (idx < 0) {\n return { ok: false, error: `agent \"${agentId}\" not found`, status: 404 };\n }\n\n type Entry = (typeof list)[number];\n const entry: Entry = { ...list[idx] };\n\n if (body.workspace !== undefined) {\n const w = body.workspace.trim();\n if (w) {\n entry.workspace = { root: resolveUserPath(w) };\n }\n }\n if (body.extends !== undefined) {\n const nextExtends = Array.from(new Set(body.extends.map((id) => normalizeAgentId(id)).filter(Boolean)));\n for (const presetId of nextExtends) {\n if (!cfg.agents.capabilityPresets[presetId]) {\n return { ok: false, error: `capability preset \"${presetId}\" not found`, status: 400 };\n }\n }\n if (nextExtends.length > 0) {\n entry.extends = nextExtends;\n } else {\n delete entry.extends;\n }\n }\n if (body.models !== undefined) {\n if (body.models === null) {\n return { ok: false, error: 'models cannot be null; every agent manifest needs model roles', status: 400 };\n } else {\n if (body.models.defaultRole !== undefined) {\n if (body.models.defaultRole === null || !body.models.defaultRole.trim()) {\n return { ok: false, error: 'models.defaultRole must be a non-empty string', status: 400 };\n }\n entry.models = { ...entry.models, defaultRole: body.models.defaultRole.trim() };\n }\n if (Object.hasOwn(body.models, 'roles')) {\n if (body.models.roles !== undefined) {\n const roles = Object.fromEntries(\n Object.entries(body.models.roles)\n .map(([id, row]) => ({\n id: id.trim(),\n model: row.model.trim(),\n description: row.description?.trim(),\n }))\n .filter((row) => row.id && row.model)\n .map((row) => [\n row.id,\n row.description ? { model: row.model, description: row.description } : { model: row.model },\n ]),\n );\n entry.models = { ...entry.models, roles };\n }\n }\n if (!entry.models.roles[entry.models.defaultRole]) {\n return { ok: false, error: 'models.defaultRole must reference models.roles', status: 400 };\n }\n }\n }\n\n if (body.skills !== undefined) {\n if (body.skills === null) {\n entry.skills = { mode: 'all' };\n } else {\n const next = body.skills.map((s) => String(s).trim()).filter(Boolean);\n if (next.length === 0) {\n entry.skills = { mode: 'allowlist', allow: [] };\n } else {\n entry.skills = { mode: 'allowlist', allow: next };\n }\n }\n }\n\n if (body.tools !== undefined) {\n if (body.tools === null) {\n entry.tools = { builtin: {} };\n } else {\n entry.tools = body.tools;\n }\n }\n\n if (body.memory !== undefined) {\n entry.memory = body.memory;\n }\n\n list[idx] = entry;\n let next: Config = {\n ...cfg,\n agents: {\n ...cfg.agents,\n list,\n },\n };\n\n if (body.setDefault === true) {\n next = {\n ...next,\n agents: {\n ...next.agents,\n default: agentId,\n },\n };\n }\n return { ok: true, data: { nextConfig: next } };\n}\n\nexport function prepareDeleteAgent(\n cfg: Config,\n agentIdRaw: string,\n): AgentAdminResult<{ nextConfig: Config; agentId: string }> {\n const agentId = normalizeAgentId(agentIdRaw);\n const reserved = requireNonMain(agentId);\n if (reserved) {\n return reserved;\n }\n if (findAgentEntryIndex(listAgentEntries(cfg), agentId) < 0) {\n return { ok: false, error: `agent \"${agentId}\" not found`, status: 404 };\n }\n const { config: pruned } = pruneAgentConfig(cfg, agentId);\n return { ok: true, data: { nextConfig: pruned, agentId } };\n}\n\nexport async function runAfterDeletePurge(cfg: Config, agentId: string): Promise<void> {\n await removeAgentDirsFromDisk(cfg, agentId);\n}\n\nexport type AgentFileEntry = {\n name: string;\n missing: boolean;\n size?: number;\n updatedAtMs?: number;\n};\n\nasync function profileMarkdownRootReal(cfg: Config, agentId: string): Promise<string> {\n const dir = resolveAgentProfileDir(cfg, agentId);\n await mkdir(dir, { recursive: true });\n try {\n return await realpath(dir);\n } catch {\n return pathResolve(dir);\n }\n}\n\nfunction assertAllowedFile(name: string): AgentAdminResult<never> | null {\n if (!name || name.includes('/') || name.includes('\\\\') || !EDITABLE_PROFILE_MARKDOWN_NAMES.has(name)) {\n return { ok: false, error: `unsupported file \"${name}\"`, status: 400 };\n }\n return null;\n}\n\nexport async function listAgentProfileFiles(\n cfg: Config,\n agentId: string,\n): Promise<AgentAdminResult<{ agentId: string; profileDir: string; files: AgentFileEntry[] }>> {\n const id = normalizeAgentId(agentId);\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n const root = await profileMarkdownRootReal(cfg, id);\n const names = [...EDITABLE_PROFILE_MARKDOWN_NAMES];\n const files: AgentFileEntry[] = [];\n for (const name of names.sort((a, b) => a.localeCompare(b))) {\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n continue;\n }\n try {\n const st = await stat(abs);\n if (!st.isFile()) {\n continue;\n }\n files.push({\n name,\n missing: false,\n size: st.size,\n updatedAtMs: st.mtimeMs,\n });\n } catch {\n files.push({ name, missing: true });\n }\n }\n files.sort((a, b) => a.name.localeCompare(b.name));\n return { ok: true, data: { agentId: id, profileDir: root, files } };\n}\n\nexport async function readAgentProfileFile(\n cfg: Config,\n agentId: string,\n name: string,\n): Promise<AgentAdminResult<{ agentId: string; content: string; path: string }>> {\n const bad = assertAllowedFile(name);\n if (bad) {\n return bad;\n }\n const id = normalizeAgentId(agentId);\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n const root = await profileMarkdownRootReal(cfg, id);\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n return { ok: false, error: 'invalid path', status: 400 };\n }\n try {\n const content = await readFile(abs, 'utf-8');\n return { ok: true, data: { agentId: id, content, path: abs } };\n } catch {\n return { ok: false, error: 'file not found', status: 404 };\n }\n}\n\nexport async function writeAgentProfileFile(\n cfg: Config,\n agentId: string,\n name: string,\n content: string,\n): Promise<AgentAdminResult<{ agentId: string; path: string }>> {\n const bad = assertAllowedFile(name);\n if (bad) {\n return bad;\n }\n const id = normalizeAgentId(agentId);\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n const root = await profileMarkdownRootReal(cfg, id);\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n return { ok: false, error: 'invalid path', status: 400 };\n }\n const rootReal = await profileMarkdownRootReal(cfg, id);\n if (!isPathUnderWorkspace(rootReal, abs)) {\n return { ok: false, error: 'path escapes profile markdown root', status: 400 };\n }\n await writeFile(abs, content, 'utf-8');\n return { ok: true, data: { agentId: id, path: abs } };\n}\n\n// ---------------------------------------------------------------------------\n// Binary agent avatar (profile markdown root dir, not a SOUL/IDENTITY markdown file)\n// ---------------------------------------------------------------------------\n\nconst AGENT_AVATAR_MAX_BYTES = 512 * 1024;\nconst AGENT_AVATAR_BASENAME = 'agent-avatar';\n\nconst AGENT_AVATAR_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.webp'] as const;\n\nfunction agentAvatarFilenames(): string[] {\n return AGENT_AVATAR_EXTENSIONS.map((ext) => `${AGENT_AVATAR_BASENAME}${ext}`);\n}\n\nfunction mimeToExt(mime: string): '.png' | '.jpg' | '.jpeg' | '.webp' | null {\n const m = mime.toLowerCase().trim();\n if (m === 'image/png') return '.png';\n if (m === 'image/jpeg' || m === 'image/jpg') return '.jpg';\n if (m === 'image/webp') return '.webp';\n return null;\n}\n\nfunction detectImageMimeFromBytes(buf: Uint8Array): 'image/png' | 'image/jpeg' | 'image/webp' | null {\n if (buf.length >= 8 && buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {\n return 'image/png';\n }\n if (buf.length >= 3 && buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff) {\n return 'image/jpeg';\n }\n if (\n buf.length >= 12 &&\n buf[0] === 0x52 &&\n buf[1] === 0x49 &&\n buf[2] === 0x46 &&\n buf[3] === 0x46 &&\n buf[8] === 0x57 &&\n buf[9] === 0x45 &&\n buf[10] === 0x42 &&\n buf[11] === 0x50\n ) {\n return 'image/webp';\n }\n return null;\n}\n\nfunction assertAgentExistsForAvatar(cfg: Config, id: string): AgentAdminResult<never> | null {\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n return null;\n}\n\nexport async function readAgentAvatarFile(\n cfg: Config,\n agentId: string,\n): Promise<AgentAdminResult<{ agentId: string; buffer: Buffer; contentType: string; path: string }>> {\n const missingAgent = assertAgentExistsForAvatar(cfg, agentId);\n if (missingAgent) {\n return missingAgent;\n }\n const id = normalizeAgentId(agentId);\n const root = await profileMarkdownRootReal(cfg, id);\n for (const name of agentAvatarFilenames()) {\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n continue;\n }\n try {\n const st = await stat(abs);\n if (!st.isFile() || st.size <= 0 || st.size > AGENT_AVATAR_MAX_BYTES) {\n continue;\n }\n const buffer = await readFile(abs);\n const detected = detectImageMimeFromBytes(buffer);\n if (!detected) {\n continue;\n }\n return { ok: true, data: { agentId: id, buffer, contentType: detected, path: abs } };\n } catch {\n /* try next */\n }\n }\n return { ok: false, error: 'avatar not found', status: 404 };\n}\n\nexport async function writeAgentAvatarFromBase64(\n cfg: Config,\n agentId: string,\n base64: string,\n mimeType: string,\n): Promise<AgentAdminResult<{ agentId: string; path: string }>> {\n const missingAgent = assertAgentExistsForAvatar(cfg, agentId);\n if (missingAgent) {\n return missingAgent;\n }\n const id = normalizeAgentId(agentId);\n const ext = mimeToExt(mimeType);\n if (!ext) {\n return { ok: false, error: 'unsupported mimeType (use image/png, image/jpeg, or image/webp)', status: 400 };\n }\n let raw: Buffer;\n try {\n raw = Buffer.from(base64, 'base64');\n } catch {\n return { ok: false, error: 'invalid base64', status: 400 };\n }\n if (raw.length === 0 || raw.length > AGENT_AVATAR_MAX_BYTES) {\n return { ok: false, error: `avatar must be non-empty and at most ${AGENT_AVATAR_MAX_BYTES} bytes`, status: 400 };\n }\n const detected = detectImageMimeFromBytes(raw);\n if (!detected || !extMatchesDetectedMime(ext, detected)) {\n return { ok: false, error: 'file content does not match declared image type', status: 400 };\n }\n\n const root = await profileMarkdownRootReal(cfg, id);\n const rootReal = await profileMarkdownRootReal(cfg, id);\n const targetName = `${AGENT_AVATAR_BASENAME}${ext}`;\n const abs = resolveWorkspaceSafePath(root, targetName);\n if (!abs || !isPathUnderWorkspace(rootReal, abs)) {\n return { ok: false, error: 'invalid path', status: 400 };\n }\n for (const name of agentAvatarFilenames()) {\n if (name === targetName) {\n continue;\n }\n const other = resolveWorkspaceSafePath(root, name);\n if (other && isPathUnderWorkspace(rootReal, other)) {\n try {\n await unlink(other);\n } catch {\n /* absent */\n }\n }\n }\n await writeFile(abs, raw);\n return { ok: true, data: { agentId: id, path: abs } };\n}\n\nfunction mimeToExtToMime(ext: '.png' | '.jpg' | '.jpeg' | '.webp'): 'image/png' | 'image/jpeg' | 'image/webp' {\n if (ext === '.png') return 'image/png';\n if (ext === '.webp') return 'image/webp';\n return 'image/jpeg';\n}\n\nfunction extMatchesDetectedMime(\n ext: '.png' | '.jpg' | '.jpeg' | '.webp',\n detected: 'image/png' | 'image/jpeg' | 'image/webp',\n): boolean {\n return detected === mimeToExtToMime(ext);\n}\n\n/** Remove any `agent-avatar.*` in the agent profile markdown root. Idempotent: ok even when no file existed. */\nexport async function deleteAgentAvatarFile(cfg: Config, agentId: string): Promise<AgentAdminResult<{ agentId: string }>> {\n const missingAgent = assertAgentExistsForAvatar(cfg, agentId);\n if (missingAgent) {\n return missingAgent;\n }\n const id = normalizeAgentId(agentId);\n const root = await profileMarkdownRootReal(cfg, id);\n const rootReal = await profileMarkdownRootReal(cfg, id);\n for (const name of agentAvatarFilenames()) {\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs || !isPathUnderWorkspace(rootReal, abs)) {\n continue;\n }\n try {\n await unlink(abs);\n } catch {\n /* absent */\n }\n }\n return { ok: true, data: { agentId: id } };\n}\n"],"mappings":";;;;;;;;;;;;;;;;kBAiBiC;YAcoB;AAOrD,MAAM,kCAAkC,IAAI,IAAY,CAAC,GAAG,oCAAoC,CAAC;AA2CjG,SAAS,uBAAuB,KAAuB;CACrD,MAAM,UAAU,iBAAiB,IAAI,CAAC,QAAQ,MAAM,EAAE,YAAY,MAAM;CACxE,MAAM,YAAY,sBAAsB,IAAI;AAC5C,KAAI,QAAQ,WAAW,EACrB,QAAO,CAAC,UAAU;CAEpB,MAAM,sBAAM,IAAI,KAAa;AAC7B,MAAK,MAAM,KAAK,QACd,KAAI,IAAI,iBAAiB,EAAE,GAAG,CAAC;AAEjC,KAAI,IAAI,UAAU;AAClB,QAAO,CAAC,GAAG,IAAI;;AAGjB,SAAS,mBACP,OACmB;AACnB,QAAO,OAAO,QAAQ,SAAS,EAAE,CAAC,CAC/B,KAAK,CAAC,IAAI,WAAW;EAAE;EAAI,GAAG;EAAM,EAAE,CACtC,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,CAAC;;;AAI7C,SAAgB,kCAAkC,SAAqC;AACrF,QAAO,sBAAsB,QAAQ,CAAC,UAAU,KAAA;;AAGlD,SAAgB,sBAAsB,SAKpC;CACA,MAAM,MAAmF,EAAE;AAC3F,MAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK,EAAE;EACtC,MAAM,QAAQ,KAAK,MAAM,8DAA8D;AACvF,MAAI,OAAO;GACT,MAAM,MAAM,MAAM,IAAI,aAAa;GACnC,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI;AAC9B,OAAI,CAAC,KAAK,aAAa,KAAK,EAAE,CAAE;AAChC,OAAI,QAAQ,OAAQ,KAAI,OAAO;AAC/B,OAAI,QAAQ,cAAe,KAAI,cAAc;AAC7C,OAAI,QAAQ,WAAY,KAAI,WAAW;AACvC,OAAI,QAAQ,SAAU,KAAI,SAAS;;;AAGvC,QAAO;;AAGT,eAAsB,kBACpB,KACA,WAAgC,EAAE,EACE;CACpC,MAAM,YAAY,sBAAsB,IAAI;CAC5C,MAAM,SAA4B,EAAE;CAEpC,MAAM,eAAyB,EAAE;CACjC,MAAM,oBAA2D,EAAE;AACnE,MAAK,MAAM,MAAM,uBAAuB,IAAI,EAAE;EAC5C,MAAM,UAAU,6BAA6B,KAAK,GAAG;EACrD,MAAM,QAAQ,iBAAiB,IAAI,CAAC,MAAM,MAAM,iBAAiB,EAAE,GAAG,KAAK,GAAG;EAC9E,MAAM,QACJ,QAAQ,mBAAmB,QAAQ,UAAU,SAAS,IAClD;GACE,GAAI,QAAQ,kBAAkB,EAAE,SAAS,QAAQ,iBAAiB,GAAG,EAAE;GACvE,GAAI,QAAQ,UAAU,SAAS,IAAI,EAAE,WAAW,QAAQ,WAAW,GAAG,EAAE;GACzE,GACD,KAAA;EACN,MAAM,cAAc,OAAO,OAAO,SAAS,cAAc,MAAM,OAAO,SAAS,EAAE,GAAG,KAAA;EACpF,MAAM,eAAe,OAAO,QAAQ,OAAO,MAAM,WAAW,EAAE,CAAC,CAC5D,QAAQ,GAAG,YAAY,OAAO,SAAS,OAAO,CAC9C,KAAK,CAAC,UAAU,KAAK;EACxB,MAAM,mBAAmB,mBAAmB,OAAO,QAAQ,MAAM;EACjE,MAAM,uBAAuB,CAAC,GAAG,4BAA4B,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,MACvF,EAAE,GAAG,cAAc,EAAE,GAAG,CACzB;EACD,IAAI,WAAqD,EAAE;AAC3D,MAAI;AAGF,cAAW,sBAAsB,MADX,SADD,KAAK,uBAAuB,KAAK,GAAG,EAAE,gBAAgB,SAChC,EAAE,QAAQ,CACZ;UACnC;AAGR,SAAO,KAAK;GACV;GACA,GAAI,SAAS,OAAO,EAAE,MAAM,SAAS,MAAM,GAAG,EAAE;GAChD,GAAI,SAAS,cAAc,EAAE,aAAa,SAAS,aAAa,GAAG,EAAE;GACrE,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,UAAU,GAAG,EAAE;GAC5D,GAAI,SAAS,SAAS,EAAE,QAAQ,SAAS,QAAQ,GAAG,EAAE;GACtD,WAAW,QAAQ;GACnB,YAAY,uBAAuB,KAAK,GAAG;GAC3C,GAAI,QAAQ,EAAE,OAAO,GAAG,EAAE;GAC1B,aAAa;IACX,aAAa,QAAQ,SAAS,OAAO;IACrC,QAAQ,CAAC,GAAG,kBAAkB;IAC9B,GAAI,iBAAiB,SAAS,IAAI,EAAE,OAAO,kBAAkB,GAAG,EAAE;IAClE,WAAW;IACZ;GACD,SAAS,CAAC,GAAI,OAAO,WAAW,EAAE,CAAE;GACpC,WAAW,OAAO;GAClB,QAAQ;IACN,QAA2C,EAAE;IAC7C,GAAI,gBAAgB,KAAA,IAAY,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,EAAE;IAChE,GAAI,QAAQ,oBAAoB,KAAA,IAC5B,EAAE,oBAAoB,CAAC,GAAG,QAAQ,gBAAgB,EAAE,GACpD,EAAE;IACP;GACD,OAAO;IACL,cAAc,CAAC,GAAG,aAAa;IAC/B,cAAc,CAAC,GAAG,aAAa;IAC/B,kBAAkB,CAAC,GAAG,QAAQ,MAAM,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC;IAC/E;GACF,CAAC;;AAEJ,QAAO,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,CAAC;AAC/C,QAAO;EAAE;EAAW;EAAQ,gBAAgB,CAAC,GAAG,yBAAyB;EAAE;;AAG7E,SAAgB,iCACd,KACA,YACyD;CACzD,MAAM,UAAU,iBAAiB,WAAW;CAC5C,MAAM,QAAQ,iBAAiB,IAAI,CAAC,MAAM,MAAM,iBAAiB,EAAE,GAAG,KAAK,QAAQ;AACnF,KAAI,CAAC,MACH,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,QAAQ;EAAc,QAAQ;EAAK;AAE1E,KAAI;AACF,SAAO;GACL,IAAI;GACJ,MAAM,8BAA8B;IAClC,OAAO;IACP,SAAS,IAAI,OAAO;IACrB,CAAC;GACH;UACM,KAAK;AACZ,SAAO;GACL,IAAI;GACJ,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACvD,QAAQ;GACT;;;AAyBL,SAAS,eAAe,IAA4C;AAClE,KAAI,iBAAiB,GAAG,KAAA,OACtB,QAAO;EAAE,IAAI;EAAO,OAAO,IAAI,iBAAiB;EAAgB,QAAQ;EAAK;AAE/E,QAAO;;AAGT,SAAgB,mBACd,KACA,MAC8E;CAC9E,MAAM,YAAY,KAAK,WAAW,MAAM,IAAI;AAC5C,KAAI,CAAC,UACH,QAAO;EAAE,IAAI;EAAO,OAAO;EAAyB,QAAQ;EAAK;AAEnE,KAAI,KAAK,iBAAiB,KAAA,GAAW;AACnC,MAAI,OAAO,KAAK,iBAAiB,YAAY,KAAK,iBAAiB,QAAQ,MAAM,QAAQ,KAAK,aAAa,CACzG,QAAO;GAAE,IAAI;GAAO,OAAO;GAAkC,QAAQ;GAAK;AAE5E,OAAK,MAAM,CAAC,MAAM,YAAY,OAAO,QAAQ,KAAK,aAAa,EAAE;GAC/D,MAAM,MAAM,kBAAkB,KAAK;AACnC,OAAI,IACF,QAAO;AAET,OAAI,OAAO,YAAY,SACrB,QAAO;IAAE,IAAI;IAAO,OAAO,iBAAiB,KAAK;IAAsB,QAAQ;IAAK;;;AAI1F,KAAI,CAAC,KAAK,aAAa,OAAO,KAAK,eAAe,gBAAgB,cAAc,SAC9E,QAAO;EAAE,IAAI;EAAO,OAAO,iBAAiB,gBAAgB,SAAS;EAAiB,QAAQ;EAAK;CAMrG,MAAM,YAHW,KAAK,eAAe,gBAAgB,YACjD,sBAAsB,KAAK,aAAa,gBAAgB,UAAU,GAClE,EAAE,EACoB,QAAQ,KAAK,MAAM;CAC7C,MAAM,QAAQ,2BAA2B,KAAK,IAAI,SAAS;AAC3D,KAAI,MAAM,OAAO,MACf,QAAO;EAAE,IAAI;EAAO,OAAO,MAAM;EAAO,QAAQ;EAAK;CAEvD,MAAM,UAAU,MAAM;AACtB,KAAI,oBAAoB,iBAAiB,IAAI,EAAE,QAAQ,IAAI,EACzD,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,QAAQ;EAAmB,QAAQ;EAAK;CAI/E,IAAI;AACJ,KAAI,KAAK,WAAW;EAClB,MAAM,QAAQ,iBAAiB,KAAK,UAAU;AAC9C,qBAAmB,iBAAiB,IAAI,CAAC,MAAM,MAAM,iBAAiB,EAAE,GAAG,KAAK,MAAM;AACtF,MAAI,CAAC,oBAAoB,UAAU,sBAAsB,IAAI,CAC3D,QAAO;GAAE,IAAI;GAAO,OAAO,iBAAiB,MAAM;GAAc,QAAQ;GAAK;;CAIjF,MAAM,QAAQ,gBAAgB,UAAU;CAExC,MAAM,YAAY,KAAK,UAAU,kBAAkB;CACnD,MAAM,kBACJ,WAAW,QACP;EACE,aAAa,UAAU,eAAe,OAAO,KAAK,UAAU,MAAM,CAAC,MAAM;EACzE,OAAO,UAAU;EAClB,GACD,KAAA;AACN,KAAI,mBAAmB,CAAC,gBAAgB,MAAM,gBAAgB,aAC5D,QAAO;EAAE,IAAI;EAAO,OAAO;EAAkD,QAAQ;EAAK;AAe5F,QAAO;EAAE,IAAI;EAAM,MAAM;GAAE,YAZhB,iBAAiB,KAAK;IAC/B;IACA,WAAW;IACX,GAAI,kBAAkB,EAAE,QAAQ,iBAAiB,GAAG,EAAE;IACtD,GAAI,KAAK,WAAW,KAAA,IAChB,EAAE,QAAQ,KAAK,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,QAAQ,EAAE,GACpE,kBAAkB,OAAO,SAAS,eAAe,KAAK,YACpD,EAAE,QAAQ,CAAC,GAAI,iBAAiB,OAAO,SAAS,EAAE,CAAE,EAAE,GACtD,EAAE;IACR,GAAI,KAAK,UAAU,KAAA,IAAY,EAAE,OAAO,KAAK,OAAO,GAAG,kBAAkB,SAAS,KAAK,YAAY,EAAE,OAAO,iBAAiB,OAAO,GAAG,EAAE;IAC1I,CAE0C;GAAE;GAAS,WAAW;GAAO;EAAE;;AAG5E,eAAsB,wBACpB,KACA,SACA,MACiC;CACjC,MAAM,SAAS,yBAAyB,KAAK,QAAQ;CACrD,MAAM,cAAc,uBAAuB,KAAK,QAAQ;CACxD,MAAM,SAAS,gBAAgB,KAAK,QAAQ;AAC5C,OAAM,MAAM,QAAQ,EAAE,WAAW,MAAM,CAAC;AACxC,OAAM,MAAM,aAAa,EAAE,WAAW,MAAM,CAAC;AAC7C,OAAM,MAAM,QAAQ,EAAE,WAAW,MAAM,CAAC;CACxC,MAAM,KAAK,iBAAiB,QAAQ;CACpC,MAAM,cAAc,MAAM,eAAe,gBAAgB,YACpD,sBAAsB,KAAK,aAAa,gBAAgB,UAAU,CAAC,QAAQ,KAC5E;AAGJ,KAAI,MAAM,WAAW;EACnB,MAAM,iBAAiB,uBAAuB,KAAK,iBAAiB,KAAK,UAAU,CAAC;AACpF,MAAI;AAEF,QAAI,MADkB,KAAK,eAAe,EAC9B,aAAa,EAAE;IACzB,MAAM,WAAW,MAAM,QAAQ,eAAe;AAC9C,SAAK,MAAM,YAAY,UAAU;KAC/B,MAAM,UAAU,KAAK,gBAAgB,SAAS;KAC9C,MAAM,UAAU,KAAK,aAAa,SAAS;AAC3C,SAAI;AAEF,WAAI,MADmB,KAAK,QAAQ,EACvB,QAAQ,CACnB,OAAM,GAAG,SAAS,QAAQ;aAEtB;;;UAKN;AAEN,iCAA8B,aAAa,QAAQ,EAAE,aAAa,CAAC;;OAGrE,+BAA8B,aAAa,QAAQ,EAAE,aAAa,CAAC;CAGrE,MAAM,eAAe,MAAM;AAC3B,KAAI,gBAAgB,OAAO,KAAK,aAAa,CAAC,SAAS,EACrD,MAAK,MAAM,CAAC,MAAM,YAAY,OAAO,QAAQ,aAAa,EAAE;EAC1D,MAAM,UAAU,MAAM,sBAAsB,KAAK,SAAS,MAAM,QAAQ;AACxE,MAAI,QAAQ,OAAO,MACjB,QAAO;;AAKb,QAAO;EAAE,IAAI;EAAM,MAAM,KAAA;EAAW;;AAmBtC,SAAgB,mBACd,KACA,YACA,MAC0C;CAC1C,MAAM,UAAU,iBAAiB,WAAW;CAC5C,IAAI,OAAO,CAAC,GAAG,iBAAiB,IAAI,CAAC;CACrC,IAAI,MAAM,oBAAoB,MAAM,QAAQ;AAC5C,KAAI,MAAM,KAAK,YAAY,sBAAsB,IAAI,EAAE;AACrD,SAAO,CAAC,GAAG,MAAM;GACf,IAAI;GACJ,SAAS;GACT,UAAU;IAAE,MAAM;IAAS,MAAM;IAAS,UAAU;IAAM,MAAM;IAAU;GAC1E,kBAAkB,EAAE,SAAS,CAAC,+BAA+B,EAAE;GAC/D,WAAW,EAAE,MAAM,qBAAqB,WAAW;GACnD,QAAQ;IAAE,aAAa;IAAQ,OAAO,EAAE,MAAM,EAAE,OAAO,kBAAkB,EAAE;IAAE;GAC7E,OAAO,EAAE,SAAS,EAAE,EAAE;GACtB,QAAQ,EAAE,MAAM,OAAO;GACvB,QAAQ;IAAE,MAAM;IAAgB,SAAS,CAAC,WAAW,UAAU;IAAE,aAAa,EAAE,SAAS,WAAW;IAAE;GACtG,WAAW,EAAE;GACb,YAAY;IAAE,sBAAsB,EAAE;IAAE,WAAW,EAAE;IAAE,YAAY,EAAE;IAAE;GACxE,CAAC;AACF,QAAM,KAAK,SAAS;;AAEtB,KAAI,MAAM,EACR,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,QAAQ;EAAc,QAAQ;EAAK;CAI1E,MAAM,QAAe,EAAE,GAAG,KAAK,MAAM;AAErC,KAAI,KAAK,cAAc,KAAA,GAAW;EAChC,MAAM,IAAI,KAAK,UAAU,MAAM;AAC/B,MAAI,EACF,OAAM,YAAY,EAAE,MAAM,gBAAgB,EAAE,EAAE;;AAGlD,KAAI,KAAK,YAAY,KAAA,GAAW;EAC9B,MAAM,cAAc,MAAM,KAAK,IAAI,IAAI,KAAK,QAAQ,KAAK,OAAO,iBAAiB,GAAG,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC;AACvG,OAAK,MAAM,YAAY,YACrB,KAAI,CAAC,IAAI,OAAO,kBAAkB,UAChC,QAAO;GAAE,IAAI;GAAO,OAAO,sBAAsB,SAAS;GAAc,QAAQ;GAAK;AAGzF,MAAI,YAAY,SAAS,EACvB,OAAM,UAAU;MAEhB,QAAO,MAAM;;AAGjB,KAAI,KAAK,WAAW,KAAA,EAClB,KAAI,KAAK,WAAW,KAClB,QAAO;EAAE,IAAI;EAAO,OAAO;EAAiE,QAAQ;EAAK;MACpG;AACL,MAAI,KAAK,OAAO,gBAAgB,KAAA,GAAW;AACzC,OAAI,KAAK,OAAO,gBAAgB,QAAQ,CAAC,KAAK,OAAO,YAAY,MAAM,CACrE,QAAO;IAAE,IAAI;IAAO,OAAO;IAAiD,QAAQ;IAAK;AAE3F,SAAM,SAAS;IAAE,GAAG,MAAM;IAAQ,aAAa,KAAK,OAAO,YAAY,MAAM;IAAE;;AAEjF,MAAI,OAAO,OAAO,KAAK,QAAQ,QAAQ;OACjC,KAAK,OAAO,UAAU,KAAA,GAAW;IACnC,MAAM,QAAQ,OAAO,YACnB,OAAO,QAAQ,KAAK,OAAO,MAAM,CAC9B,KAAK,CAAC,IAAI,UAAU;KACnB,IAAI,GAAG,MAAM;KACb,OAAO,IAAI,MAAM,MAAM;KACvB,aAAa,IAAI,aAAa,MAAM;KACrC,EAAE,CACF,QAAQ,QAAQ,IAAI,MAAM,IAAI,MAAM,CACpC,KAAK,QAAQ,CACZ,IAAI,IACJ,IAAI,cAAc;KAAE,OAAO,IAAI;KAAO,aAAa,IAAI;KAAa,GAAG,EAAE,OAAO,IAAI,OAAO,CAC5F,CAAC,CACL;AACD,UAAM,SAAS;KAAE,GAAG,MAAM;KAAQ;KAAO;;;AAG7C,MAAI,CAAC,MAAM,OAAO,MAAM,MAAM,OAAO,aACnC,QAAO;GAAE,IAAI;GAAO,OAAO;GAAkD,QAAQ;GAAK;;AAKhG,KAAI,KAAK,WAAW,KAAA,EAClB,KAAI,KAAK,WAAW,KAClB,OAAM,SAAS,EAAE,MAAM,OAAO;MACzB;EACL,MAAM,OAAO,KAAK,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,QAAQ;AACrE,MAAI,KAAK,WAAW,EAClB,OAAM,SAAS;GAAE,MAAM;GAAa,OAAO,EAAE;GAAE;MAE/C,OAAM,SAAS;GAAE,MAAM;GAAa,OAAO;GAAM;;AAKvD,KAAI,KAAK,UAAU,KAAA,EACjB,KAAI,KAAK,UAAU,KACjB,OAAM,QAAQ,EAAE,SAAS,EAAE,EAAE;KAE7B,OAAM,QAAQ,KAAK;AAIvB,KAAI,KAAK,WAAW,KAAA,EAClB,OAAM,SAAS,KAAK;AAGtB,MAAK,OAAO;CACZ,IAAI,OAAe;EACjB,GAAG;EACH,QAAQ;GACN,GAAG,IAAI;GACP;GACD;EACF;AAED,KAAI,KAAK,eAAe,KACtB,QAAO;EACL,GAAG;EACH,QAAQ;GACN,GAAG,KAAK;GACR,SAAS;GACV;EACF;AAEH,QAAO;EAAE,IAAI;EAAM,MAAM,EAAE,YAAY,MAAM;EAAE;;AAGjD,SAAgB,mBACd,KACA,YAC2D;CAC3D,MAAM,UAAU,iBAAiB,WAAW;CAC5C,MAAM,WAAW,eAAe,QAAQ;AACxC,KAAI,SACF,QAAO;AAET,KAAI,oBAAoB,iBAAiB,IAAI,EAAE,QAAQ,GAAG,EACxD,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,QAAQ;EAAc,QAAQ;EAAK;CAE1E,MAAM,EAAE,QAAQ,WAAW,iBAAiB,KAAK,QAAQ;AACzD,QAAO;EAAE,IAAI;EAAM,MAAM;GAAE,YAAY;GAAQ;GAAS;EAAE;;AAG5D,eAAsB,oBAAoB,KAAa,SAAgC;AACrF,OAAM,wBAAwB,KAAK,QAAQ;;AAU7C,eAAe,wBAAwB,KAAa,SAAkC;CACpF,MAAM,MAAM,uBAAuB,KAAK,QAAQ;AAChD,OAAM,MAAM,KAAK,EAAE,WAAW,MAAM,CAAC;AACrC,KAAI;AACF,SAAO,MAAM,SAAS,IAAI;SACpB;AACN,SAAOA,QAAY,IAAI;;;AAI3B,SAAS,kBAAkB,MAA8C;AACvE,KAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,KAAK,IAAI,CAAC,gCAAgC,IAAI,KAAK,CAClG,QAAO;EAAE,IAAI;EAAO,OAAO,qBAAqB,KAAK;EAAI,QAAQ;EAAK;AAExE,QAAO;;AAGT,eAAsB,sBACpB,KACA,SAC6F;CAC7F,MAAM,KAAK,iBAAiB,QAAQ;AACpC,KAAI,uBAAuB,IAAI,CAAC,OAAO,MAAM,MAAM,GAAG,CACpD,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,GAAG;EAAc,QAAQ;EAAK;CAErE,MAAM,OAAO,MAAM,wBAAwB,KAAK,GAAG;CACnD,MAAM,QAAQ,CAAC,GAAG,gCAAgC;CAClD,MAAM,QAA0B,EAAE;AAClC,MAAK,MAAM,QAAQ,MAAM,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC,EAAE;EAC3D,MAAM,MAAM,yBAAyB,MAAM,KAAK;AAChD,MAAI,CAAC,IACH;AAEF,MAAI;GACF,MAAM,KAAK,MAAM,KAAK,IAAI;AAC1B,OAAI,CAAC,GAAG,QAAQ,CACd;AAEF,SAAM,KAAK;IACT;IACA,SAAS;IACT,MAAM,GAAG;IACT,aAAa,GAAG;IACjB,CAAC;UACI;AACN,SAAM,KAAK;IAAE;IAAM,SAAS;IAAM,CAAC;;;AAGvC,OAAM,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,KAAK,CAAC;AAClD,QAAO;EAAE,IAAI;EAAM,MAAM;GAAE,SAAS;GAAI,YAAY;GAAM;GAAO;EAAE;;AAGrE,eAAsB,qBACpB,KACA,SACA,MAC+E;CAC/E,MAAM,MAAM,kBAAkB,KAAK;AACnC,KAAI,IACF,QAAO;CAET,MAAM,KAAK,iBAAiB,QAAQ;AACpC,KAAI,uBAAuB,IAAI,CAAC,OAAO,MAAM,MAAM,GAAG,CACpD,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,GAAG;EAAc,QAAQ;EAAK;CAGrE,MAAM,MAAM,yBAAyB,MADlB,wBAAwB,KAAK,GAAG,EACR,KAAK;AAChD,KAAI,CAAC,IACH,QAAO;EAAE,IAAI;EAAO,OAAO;EAAgB,QAAQ;EAAK;AAE1D,KAAI;AAEF,SAAO;GAAE,IAAI;GAAM,MAAM;IAAE,SAAS;IAAI,SAAA,MADlB,SAAS,KAAK,QAAQ;IACK,MAAM;IAAK;GAAE;SACxD;AACN,SAAO;GAAE,IAAI;GAAO,OAAO;GAAkB,QAAQ;GAAK;;;AAI9D,eAAsB,sBACpB,KACA,SACA,MACA,SAC8D;CAC9D,MAAM,MAAM,kBAAkB,KAAK;AACnC,KAAI,IACF,QAAO;CAET,MAAM,KAAK,iBAAiB,QAAQ;AACpC,KAAI,uBAAuB,IAAI,CAAC,OAAO,MAAM,MAAM,GAAG,CACpD,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,GAAG;EAAc,QAAQ;EAAK;CAGrE,MAAM,MAAM,yBAAyB,MADlB,wBAAwB,KAAK,GAAG,EACR,KAAK;AAChD,KAAI,CAAC,IACH,QAAO;EAAE,IAAI;EAAO,OAAO;EAAgB,QAAQ;EAAK;AAG1D,KAAI,CAAC,qBAAqB,MADH,wBAAwB,KAAK,GAAG,EACnB,IAAI,CACtC,QAAO;EAAE,IAAI;EAAO,OAAO;EAAsC,QAAQ;EAAK;AAEhF,OAAM,UAAU,KAAK,SAAS,QAAQ;AACtC,QAAO;EAAE,IAAI;EAAM,MAAM;GAAE,SAAS;GAAI,MAAM;GAAK;EAAE;;AAOvD,MAAM,yBAAyB,MAAM;AACrC,MAAM,wBAAwB;AAE9B,MAAM,0BAA0B;CAAC;CAAQ;CAAQ;CAAS;CAAQ;AAElE,SAAS,uBAAiC;AACxC,QAAO,wBAAwB,KAAK,QAAQ,GAAG,wBAAwB,MAAM;;AAG/E,SAAS,UAAU,MAA0D;CAC3E,MAAM,IAAI,KAAK,aAAa,CAAC,MAAM;AACnC,KAAI,MAAM,YAAa,QAAO;AAC9B,KAAI,MAAM,gBAAgB,MAAM,YAAa,QAAO;AACpD,KAAI,MAAM,aAAc,QAAO;AAC/B,QAAO;;AAGT,SAAS,yBAAyB,KAAmE;AACnG,KAAI,IAAI,UAAU,KAAK,IAAI,OAAO,OAAQ,IAAI,OAAO,MAAQ,IAAI,OAAO,MAAQ,IAAI,OAAO,GACzF,QAAO;AAET,KAAI,IAAI,UAAU,KAAK,IAAI,OAAO,OAAQ,IAAI,OAAO,OAAQ,IAAI,OAAO,IACtE,QAAO;AAET,KACE,IAAI,UAAU,MACd,IAAI,OAAO,MACX,IAAI,OAAO,MACX,IAAI,OAAO,MACX,IAAI,OAAO,MACX,IAAI,OAAO,MACX,IAAI,OAAO,MACX,IAAI,QAAQ,MACZ,IAAI,QAAQ,GAEZ,QAAO;AAET,QAAO;;AAGT,SAAS,2BAA2B,KAAa,IAA4C;AAC3F,KAAI,uBAAuB,IAAI,CAAC,OAAO,MAAM,MAAM,GAAG,CACpD,QAAO;EAAE,IAAI;EAAO,OAAO,UAAU,GAAG;EAAc,QAAQ;EAAK;AAErE,QAAO;;AAGT,eAAsB,oBACpB,KACA,SACmG;CACnG,MAAM,eAAe,2BAA2B,KAAK,QAAQ;AAC7D,KAAI,aACF,QAAO;CAET,MAAM,KAAK,iBAAiB,QAAQ;CACpC,MAAM,OAAO,MAAM,wBAAwB,KAAK,GAAG;AACnD,MAAK,MAAM,QAAQ,sBAAsB,EAAE;EACzC,MAAM,MAAM,yBAAyB,MAAM,KAAK;AAChD,MAAI,CAAC,IACH;AAEF,MAAI;GACF,MAAM,KAAK,MAAM,KAAK,IAAI;AAC1B,OAAI,CAAC,GAAG,QAAQ,IAAI,GAAG,QAAQ,KAAK,GAAG,OAAO,uBAC5C;GAEF,MAAM,SAAS,MAAM,SAAS,IAAI;GAClC,MAAM,WAAW,yBAAyB,OAAO;AACjD,OAAI,CAAC,SACH;AAEF,UAAO;IAAE,IAAI;IAAM,MAAM;KAAE,SAAS;KAAI;KAAQ,aAAa;KAAU,MAAM;KAAK;IAAE;UAC9E;;AAIV,QAAO;EAAE,IAAI;EAAO,OAAO;EAAoB,QAAQ;EAAK;;AAG9D,eAAsB,2BACpB,KACA,SACA,QACA,UAC8D;CAC9D,MAAM,eAAe,2BAA2B,KAAK,QAAQ;AAC7D,KAAI,aACF,QAAO;CAET,MAAM,KAAK,iBAAiB,QAAQ;CACpC,MAAM,MAAM,UAAU,SAAS;AAC/B,KAAI,CAAC,IACH,QAAO;EAAE,IAAI;EAAO,OAAO;EAAmE,QAAQ;EAAK;CAE7G,IAAI;AACJ,KAAI;AACF,QAAM,OAAO,KAAK,QAAQ,SAAS;SAC7B;AACN,SAAO;GAAE,IAAI;GAAO,OAAO;GAAkB,QAAQ;GAAK;;AAE5D,KAAI,IAAI,WAAW,KAAK,IAAI,SAAS,uBACnC,QAAO;EAAE,IAAI;EAAO,OAAO,wCAAwC,uBAAuB;EAAS,QAAQ;EAAK;CAElH,MAAM,WAAW,yBAAyB,IAAI;AAC9C,KAAI,CAAC,YAAY,CAAC,uBAAuB,KAAK,SAAS,CACrD,QAAO;EAAE,IAAI;EAAO,OAAO;EAAmD,QAAQ;EAAK;CAG7F,MAAM,OAAO,MAAM,wBAAwB,KAAK,GAAG;CACnD,MAAM,WAAW,MAAM,wBAAwB,KAAK,GAAG;CACvD,MAAM,aAAa,GAAG,wBAAwB;CAC9C,MAAM,MAAM,yBAAyB,MAAM,WAAW;AACtD,KAAI,CAAC,OAAO,CAAC,qBAAqB,UAAU,IAAI,CAC9C,QAAO;EAAE,IAAI;EAAO,OAAO;EAAgB,QAAQ;EAAK;AAE1D,MAAK,MAAM,QAAQ,sBAAsB,EAAE;AACzC,MAAI,SAAS,WACX;EAEF,MAAM,QAAQ,yBAAyB,MAAM,KAAK;AAClD,MAAI,SAAS,qBAAqB,UAAU,MAAM,CAChD,KAAI;AACF,SAAM,OAAO,MAAM;UACb;;AAKZ,OAAM,UAAU,KAAK,IAAI;AACzB,QAAO;EAAE,IAAI;EAAM,MAAM;GAAE,SAAS;GAAI,MAAM;GAAK;EAAE;;AAGvD,SAAS,gBAAgB,KAAqF;AAC5G,KAAI,QAAQ,OAAQ,QAAO;AAC3B,KAAI,QAAQ,QAAS,QAAO;AAC5B,QAAO;;AAGT,SAAS,uBACP,KACA,UACS;AACT,QAAO,aAAa,gBAAgB,IAAI;;;AAI1C,eAAsB,sBAAsB,KAAa,SAAiE;CACxH,MAAM,eAAe,2BAA2B,KAAK,QAAQ;AAC7D,KAAI,aACF,QAAO;CAET,MAAM,KAAK,iBAAiB,QAAQ;CACpC,MAAM,OAAO,MAAM,wBAAwB,KAAK,GAAG;CACnD,MAAM,WAAW,MAAM,wBAAwB,KAAK,GAAG;AACvD,MAAK,MAAM,QAAQ,sBAAsB,EAAE;EACzC,MAAM,MAAM,yBAAyB,MAAM,KAAK;AAChD,MAAI,CAAC,OAAO,CAAC,qBAAqB,UAAU,IAAI,CAC9C;AAEF,MAAI;AACF,SAAM,OAAO,IAAI;UACX;;AAIV,QAAO;EAAE,IAAI;EAAM,MAAM,EAAE,SAAS,IAAI;EAAE"}
|
|
1
|
+
{"version":3,"file":"agents-admin.js","names":["pathResolve"],"sources":["../../../src/gateway/agents-admin.ts"],"sourcesContent":["/**\n * Gateway REST helpers for multi-agent management.\n */\n\nimport { cp, mkdir, readdir, readFile, realpath, stat, unlink, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve as pathResolve } from 'node:path';\n\nimport {\n listAgentEntries,\n normalizeAgentId,\n resolveAgentDir,\n resolveAgentProfileDir,\n resolveAgentWorkspaceDir,\n resolveDefaultAgentId,\n resolveUserPath,\n validateAgentIdForNewAgent,\n} from '../agent/agent-scope.js';\nimport {\n AGENT_PROFILE_MARKDOWN_SYSTEM_FILES,\n REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET,\n} from '../agent/context/workspace.js';\nimport { seedAgentProfileMarkdownFiles } from '../agent/context/workspace-seed.js';\nimport {\n resolveEffectiveAgentManifest,\n type ResolveManifestResult,\n} from '../agent-manifest/resolver.js';\nimport {\n applyAgentConfig,\n findAgentEntryIndex,\n getAgentDeleteBlocker,\n pruneAgentConfig,\n removeAgentDirsFromDisk,\n} from '../commands/agents.config.js';\nimport type { AgentModelsConfig, Config } from '../config/schema.js';\nimport { resolveUserProfilePath, WORKSPACE_FILES } from '../config/paths.js';\nimport { resolveEffectiveAgentProfile } from '../config/agent-profile.js';\nimport type { AgentTypedModel } from '../config/schema.js';\nimport { resolveEffectiveTypedModels } from '../config/agent-typed-models.js';\nimport { GATEWAY_BUILTIN_TOOL_IDS } from './agent-builtin-tools.js';\nimport { isPathUnderWorkspace, resolveWorkspaceSafePath } from './workspace-editor-path.js';\n\nconst EDITABLE_PROFILE_MARKDOWN_NAMES = new Set<string>([...AGENT_PROFILE_MARKDOWN_SYSTEM_FILES]);\n\nexport type GatewayAgentTypedModelsInfo = {\n defaultRole: string;\n preset: AgentTypedModel[];\n entry?: AgentTypedModel[];\n effective: AgentTypedModel[];\n};\n\nexport type GatewayAgentRow = {\n id: string;\n name?: string;\n description?: string;\n language?: string;\n /** Value from `IDENTITY.md` **Avatar:** line when present (may be URL, `xopc:…`, etc.). */\n avatar?: string;\n workspace: string;\n /** Absolute directory for profile Markdown (`SOUL.md`, …) and gateway avatars: `agents/<id>/profile/`. */\n profileDir: string;\n model?: { primary?: string; fallbacks?: string[] };\n typedModels: GatewayAgentTypedModelsInfo;\n extends: string[];\n isDefault: boolean;\n skills: {\n preset: string[];\n entry?: string[];\n effectiveAllowlist?: string[];\n };\n tools: {\n presetDenied: string[];\n entryDisable: string[];\n effectiveDisable: string[];\n };\n};\n\nexport type GatewayAgentsListResponse = {\n defaultId: string;\n agents: GatewayAgentRow[];\n builtinToolIds: string[];\n};\n\nexport type GatewayAgentEffectiveManifestResponse = ResolveManifestResult;\n\nfunction collectAgentIdsForList(cfg: Config): string[] {\n const entries = listAgentEntries(cfg).filter((e) => e.enabled !== false);\n const defaultId = resolveDefaultAgentId(cfg);\n if (entries.length === 0) {\n return [defaultId];\n }\n const ids = new Set<string>();\n for (const e of entries) {\n ids.add(normalizeAgentId(e.id));\n }\n ids.add(defaultId);\n return [...ids];\n}\n\nfunction rolesToTypedModels(\n roles: Record<string, { model: string; fallbacks?: string[]; description?: string }> | undefined,\n): AgentTypedModel[] {\n return Object.entries(roles ?? {})\n .map(([id, role]) => ({ id, ...role }))\n .sort((a, b) => a.id.localeCompare(b.id));\n}\n\n/** Extract `**Avatar:**` value from profile IDENTITY.md (same line shape as the gateway console parser). */\nexport function extractAvatarFromIdentityMarkdown(content: string): string | undefined {\n return parseIdentityMarkdown(content).avatar || undefined;\n}\n\nexport function parseIdentityMarkdown(content: string): {\n name?: string;\n description?: string;\n language?: string;\n avatar?: string;\n} {\n const out: { name?: string; description?: string; language?: string; avatar?: string } = {};\n for (const line of content.split('\\n')) {\n const match = line.match(/^[-*]\\s+\\*\\*(Name|Description|Language|Avatar):\\*\\*\\s*(.*)/i);\n if (match) {\n const key = match[1]?.toLowerCase();\n const v = match[2]?.trim() ?? '';\n if (!v || /^_\\(.*\\)_$/.test(v)) continue;\n if (key === 'name') out.name = v;\n if (key === 'description') out.description = v;\n if (key === 'language') out.language = v;\n if (key === 'avatar') out.avatar = v;\n }\n }\n return out;\n}\n\nexport async function listGatewayAgents(\n cfg: Config,\n _options: { locale?: string } = {},\n): Promise<GatewayAgentsListResponse> {\n const defaultId = resolveDefaultAgentId(cfg);\n const agents: GatewayAgentRow[] = [];\n const presetSkills: string[] | undefined = undefined;\n const presetDenied: string[] = [];\n const presetTypedModels: ReturnType<typeof rolesToTypedModels> = [];\n for (const id of collectAgentIdsForList(cfg)) {\n const profile = resolveEffectiveAgentProfile(cfg, id);\n const entry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === id);\n const model =\n profile.primaryModelRef || profile.fallbacks.length > 0\n ? {\n ...(profile.primaryModelRef ? { primary: profile.primaryModelRef } : {}),\n ...(profile.fallbacks.length > 0 ? { fallbacks: profile.fallbacks } : {}),\n }\n : undefined;\n const entrySkills = entry?.skills.mode === 'allowlist' ? entry.skills.allow ?? [] : undefined;\n const entryDisable = Object.entries(entry?.tools.builtin ?? {})\n .filter(([, policy]) => policy.mode === 'deny')\n .map(([name]) => name);\n const entryTypedModels = rolesToTypedModels(entry?.models?.roles);\n const effectiveTypedModels = [...resolveEffectiveTypedModels(cfg, id).values()].sort((a, b) =>\n a.id.localeCompare(b.id),\n );\n let identity: ReturnType<typeof parseIdentityMarkdown> = {};\n try {\n const identityPath = join(resolveAgentProfileDir(cfg, id), WORKSPACE_FILES.IDENTITY);\n const content = await readFile(identityPath, 'utf-8');\n identity = parseIdentityMarkdown(content);\n } catch {\n /* missing IDENTITY.md or unreadable */\n }\n agents.push({\n id,\n ...(identity.name ? { name: identity.name } : {}),\n ...(identity.description ? { description: identity.description } : {}),\n ...(identity.language ? { language: identity.language } : {}),\n ...(identity.avatar ? { avatar: identity.avatar } : {}),\n workspace: profile.resolvedWorkspacePath,\n profileDir: resolveAgentProfileDir(cfg, id),\n ...(model ? { model } : {}),\n typedModels: {\n defaultRole: profile.manifest.models.defaultRole,\n preset: [...presetTypedModels],\n ...(entryTypedModels.length > 0 ? { entry: entryTypedModels } : {}),\n effective: effectiveTypedModels,\n },\n extends: [...(entry?.extends ?? [])],\n isDefault: id === defaultId,\n skills: {\n preset: presetSkills ? [...presetSkills] : [],\n ...(entrySkills !== undefined ? { entry: [...entrySkills] } : {}),\n ...(profile.skillsAllowlist !== undefined\n ? { effectiveAllowlist: [...profile.skillsAllowlist] }\n : {}),\n },\n tools: {\n presetDenied: [...presetDenied],\n entryDisable: [...entryDisable],\n effectiveDisable: [...profile.tools.denied].sort((a, b) => a.localeCompare(b)),\n },\n });\n }\n agents.sort((a, b) => a.id.localeCompare(b.id));\n return { defaultId, agents, builtinToolIds: [...GATEWAY_BUILTIN_TOOL_IDS] };\n}\n\nexport function getGatewayAgentEffectiveManifest(\n cfg: Config,\n agentIdRaw: string,\n): AgentAdminResult<GatewayAgentEffectiveManifestResponse> {\n const agentId = normalizeAgentId(agentIdRaw);\n const entry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === agentId);\n if (!entry) {\n return { ok: false, error: `agent \"${agentId}\" not found`, status: 404 };\n }\n try {\n return {\n ok: true,\n data: resolveEffectiveAgentManifest({\n agent: entry,\n presets: cfg.agents.capabilityPresets,\n defaultPresetId: cfg.agents.defaultPreset,\n }),\n };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n status: 400,\n };\n }\n}\n\nexport type CreateAgentBody = {\n /** Optional id seed; normalized agent id defaults from `profileFiles[\"IDENTITY.md\"]` name when omitted. */\n id?: string;\n workspace: string;\n models?: AgentModelsConfig;\n /** Initial `agents.list[].skills` for the new entry. */\n skills?: string[];\n /** Initial `agents.list[].tools` for the new entry. */\n tools?: NonNullable<Config['agents']['list']>[number]['tools'];\n /** Profile markdown files to write after seeding (e.g. `IDENTITY.md`, `SOUL.md`). */\n profileFiles?: Record<string, string>;\n /** Clone from an existing agent id — copies config entry fields and profile directory. */\n cloneFrom?: string;\n};\n\nexport type AgentAdminHttpStatus = 400 | 404 | 409;\n\nexport type AgentAdminResult<T> =\n | { ok: true; data: T }\n | { ok: false; error: string; status?: AgentAdminHttpStatus };\n\nexport function prepareCreateAgent(\n cfg: Config,\n body: CreateAgentBody,\n): AgentAdminResult<{ nextConfig: Config; agentId: string; workspace: string }> {\n const workspace = body.workspace?.trim() ?? '';\n if (!workspace) {\n return { ok: false, error: 'workspace is required', status: 400 };\n }\n if (body.profileFiles !== undefined) {\n if (typeof body.profileFiles !== 'object' || body.profileFiles === null || Array.isArray(body.profileFiles)) {\n return { ok: false, error: 'profileFiles must be an object', status: 400 };\n }\n for (const [name, content] of Object.entries(body.profileFiles)) {\n const bad = assertAllowedFile(name);\n if (bad) {\n return bad;\n }\n if (typeof content !== 'string') {\n return { ok: false, error: `profileFiles[\"${name}\"] must be a string`, status: 400 };\n }\n }\n }\n if (!body.cloneFrom && typeof body.profileFiles?.[WORKSPACE_FILES.IDENTITY] !== 'string') {\n return { ok: false, error: `profileFiles[\"${WORKSPACE_FILES.IDENTITY}\"] is required`, status: 400 };\n }\n\n const identity = body.profileFiles?.[WORKSPACE_FILES.IDENTITY]\n ? parseIdentityMarkdown(body.profileFiles[WORKSPACE_FILES.IDENTITY])\n : {};\n const nameSeed = identity.name ?? body.id ?? '';\n const idRes = validateAgentIdForNewAgent(body.id, nameSeed);\n if (idRes.ok === false) {\n return { ok: false, error: idRes.error, status: 400 };\n }\n const agentId = idRes.agentId;\n if (findAgentEntryIndex(listAgentEntries(cfg), agentId) >= 0) {\n return { ok: false, error: `agent \"${agentId}\" already exists`, status: 409 };\n }\n\n // Resolve fields from cloneFrom source when present\n let cloneSourceEntry: ReturnType<typeof listAgentEntries>[number] | undefined;\n if (body.cloneFrom) {\n const srcId = normalizeAgentId(body.cloneFrom);\n cloneSourceEntry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === srcId);\n if (!cloneSourceEntry && srcId !== resolveDefaultAgentId(cfg)) {\n return { ok: false, error: `source agent \"${srcId}\" not found`, status: 404 };\n }\n }\n\n const wsAbs = resolveUserPath(workspace);\n\n const rawModels = body.models ?? cloneSourceEntry?.models;\n const effectiveModels =\n rawModels?.roles\n ? {\n defaultRole: rawModels.defaultRole ?? Object.keys(rawModels.roles)[0] ?? 'deep',\n roles: rawModels.roles,\n }\n : undefined;\n if (effectiveModels && !effectiveModels.roles[effectiveModels.defaultRole]) {\n return { ok: false, error: 'models.defaultRole must reference models.roles', status: 400 };\n }\n\n let next = applyAgentConfig(cfg, {\n agentId,\n workspace: wsAbs,\n ...(effectiveModels ? { models: effectiveModels } : {}),\n ...(body.skills !== undefined\n ? { skills: body.skills.map((s) => String(s).trim()).filter(Boolean) }\n : cloneSourceEntry?.skills.mode === 'allowlist' && body.cloneFrom\n ? { skills: [...(cloneSourceEntry.skills.allow ?? [])] }\n : {}),\n ...(body.tools !== undefined ? { tools: body.tools } : cloneSourceEntry?.tools && body.cloneFrom ? { tools: cloneSourceEntry.tools } : {}),\n });\n\n return { ok: true, data: { nextConfig: next, agentId, workspace: wsAbs } };\n}\n\nexport async function finalizeCreateAgentDirs(\n cfg: Config,\n agentId: string,\n opts?: { profileFiles?: Record<string, string>; cloneFrom?: string },\n): Promise<AgentAdminResult<void>> {\n const wsPath = resolveAgentWorkspaceDir(cfg, agentId);\n const profilePath = resolveAgentProfileDir(cfg, agentId);\n const adPath = resolveAgentDir(cfg, agentId);\n await mkdir(wsPath, { recursive: true });\n await mkdir(profilePath, { recursive: true });\n await mkdir(adPath, { recursive: true });\n const id = normalizeAgentId(agentId);\n const displayName = opts?.profileFiles?.[WORKSPACE_FILES.IDENTITY]\n ? (parseIdentityMarkdown(opts.profileFiles[WORKSPACE_FILES.IDENTITY]).name ?? id)\n : id;\n\n // When cloning, copy the entire source profile directory instead of seeding\n if (opts?.cloneFrom) {\n const srcProfilePath = resolveAgentProfileDir(cfg, normalizeAgentId(opts.cloneFrom));\n try {\n const srcStat = await stat(srcProfilePath);\n if (srcStat.isDirectory()) {\n const srcFiles = await readdir(srcProfilePath);\n for (const fileName of srcFiles) {\n const srcFile = join(srcProfilePath, fileName);\n const dstFile = join(profilePath, fileName);\n try {\n const fileStat = await stat(srcFile);\n if (fileStat.isFile()) {\n await cp(srcFile, dstFile);\n }\n } catch {\n /* skip unreadable files */\n }\n }\n }\n } catch {\n // Source profile dir doesn't exist — fall through to normal seed\n seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName });\n }\n } else {\n seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName });\n }\n\n const profileFiles = opts?.profileFiles;\n if (profileFiles && Object.keys(profileFiles).length > 0) {\n for (const [name, content] of Object.entries(profileFiles)) {\n const written = await writeAgentProfileFile(cfg, agentId, name, content);\n if (written.ok === false) {\n return written;\n }\n }\n }\n\n return { ok: true, data: undefined };\n}\n\nexport type UpdateAgentBody = {\n workspace?: string;\n extends?: string[];\n models?: {\n defaultRole?: string | null;\n roles?: Record<string, { model: string; fallbacks?: string[]; description?: string }>;\n } | null;\n setDefault?: boolean;\n /** Replace `agents.list[].skills`; `null` resets to all skills. */\n skills?: string[] | null;\n /** Replace `agents.list[].tools`; `null` resets to no explicit policies. */\n tools?: NonNullable<Config['agents']['list']>[number]['tools'] | null;\n /** Replace `agents.list[].memory`; every agent manifest owns its memory policy. */\n memory?: NonNullable<Config['agents']['list']>[number]['memory'];\n};\n\nexport function prepareUpdateAgent(\n cfg: Config,\n agentIdRaw: string,\n body: UpdateAgentBody,\n): AgentAdminResult<{ nextConfig: Config }> {\n const agentId = normalizeAgentId(agentIdRaw);\n let list = [...listAgentEntries(cfg)];\n let idx = findAgentEntryIndex(list, agentId);\n if (idx < 0 && agentId === resolveDefaultAgentId(cfg)) {\n list = [...list, {\n id: agentId,\n enabled: true as const,\n identity: { name: agentId, role: 'Agent', language: 'en', tone: 'direct' },\n responsibilities: { primary: ['Help the user complete tasks'] },\n workspace: { root: `~/.xopc/workspace/${agentId}` },\n tools: { builtin: {} },\n skills: { mode: 'all' },\n memory: { mode: 'confirmWrite', sources: ['session', 'curated'], writePolicy: { curated: 'confirm' } },\n workflows: {},\n boundaries: { requiresConfirmation: [], forbidden: [], escalation: [] },\n }];\n idx = list.length - 1;\n }\n if (idx < 0) {\n return { ok: false, error: `agent \"${agentId}\" not found`, status: 404 };\n }\n\n type Entry = (typeof list)[number];\n const entry: Entry = { ...list[idx] };\n\n if (body.workspace !== undefined) {\n const w = body.workspace.trim();\n if (w) {\n entry.workspace = { root: resolveUserPath(w) };\n }\n }\n if (body.extends !== undefined) {\n const nextExtends = Array.from(new Set(body.extends.map((id) => normalizeAgentId(id)).filter(Boolean)));\n for (const presetId of nextExtends) {\n if (!cfg.agents.capabilityPresets[presetId]) {\n return { ok: false, error: `capability preset \"${presetId}\" not found`, status: 400 };\n }\n }\n if (nextExtends.length > 0) {\n entry.extends = nextExtends;\n } else {\n delete entry.extends;\n }\n }\n if (body.models !== undefined) {\n if (body.models === null) {\n delete entry.models;\n } else {\n if (body.models.defaultRole !== undefined) {\n if (body.models.defaultRole === null || !body.models.defaultRole.trim()) {\n return { ok: false, error: 'models.defaultRole must be a non-empty string', status: 400 };\n }\n entry.models = {\n defaultRole: body.models.defaultRole.trim(),\n roles: entry.models?.roles ?? {},\n ...(entry.models?.policy ? { policy: entry.models.policy } : {}),\n };\n }\n if (Object.hasOwn(body.models, 'roles')) {\n if (body.models.roles !== undefined) {\n const roles = Object.fromEntries(\n Object.entries(body.models.roles)\n .map(([id, row]) => ({\n id: id.trim(),\n model: row.model.trim(),\n fallbacks: (row.fallbacks ?? []).map((ref) => ref.trim()).filter(Boolean),\n description: row.description?.trim(),\n }))\n .filter((row) => row.id && row.model)\n .map((row) => [\n row.id,\n {\n model: row.model,\n ...(row.fallbacks.length > 0 ? { fallbacks: row.fallbacks } : {}),\n ...(row.description ? { description: row.description } : {}),\n },\n ]),\n );\n entry.models = {\n defaultRole: entry.models?.defaultRole ?? Object.keys(roles)[0] ?? 'deep',\n roles,\n ...(entry.models?.policy ? { policy: entry.models.policy } : {}),\n };\n }\n }\n const roles = entry.models?.roles ?? {};\n const defaultRole = entry.models?.defaultRole ?? Object.keys(roles)[0];\n if (!defaultRole || !roles[defaultRole]) {\n return { ok: false, error: 'models.defaultRole must reference models.roles', status: 400 };\n }\n entry.models = { ...entry.models, defaultRole };\n }\n }\n\n if (body.skills !== undefined) {\n if (body.skills === null) {\n entry.skills = { mode: 'all' };\n } else {\n const next = body.skills.map((s) => String(s).trim()).filter(Boolean);\n if (next.length === 0) {\n entry.skills = { mode: 'allowlist', allow: [] };\n } else {\n entry.skills = { mode: 'allowlist', allow: next };\n }\n }\n }\n\n if (body.tools !== undefined) {\n if (body.tools === null) {\n entry.tools = { builtin: {} };\n } else {\n entry.tools = body.tools;\n }\n }\n\n if (body.memory !== undefined) {\n entry.memory = body.memory;\n }\n\n list[idx] = entry;\n let next: Config = {\n ...cfg,\n agents: {\n ...cfg.agents,\n list,\n },\n };\n\n if (body.setDefault === true) {\n next = {\n ...next,\n agents: {\n ...next.agents,\n default: agentId,\n },\n };\n }\n return { ok: true, data: { nextConfig: next } };\n}\n\nexport function prepareDeleteAgent(\n cfg: Config,\n agentIdRaw: string,\n): AgentAdminResult<{ nextConfig: Config; agentId: string }> {\n const agentId = normalizeAgentId(agentIdRaw);\n const blocker = getAgentDeleteBlocker(cfg, agentId);\n if (blocker) {\n return { ok: false, error: blocker, status: 400 };\n }\n if (findAgentEntryIndex(listAgentEntries(cfg), agentId) < 0) {\n return { ok: false, error: `agent \"${agentId}\" not found`, status: 404 };\n }\n const { config: pruned } = pruneAgentConfig(cfg, agentId);\n return { ok: true, data: { nextConfig: pruned, agentId } };\n}\n\nexport async function runAfterDeletePurge(cfg: Config, agentId: string): Promise<void> {\n await removeAgentDirsFromDisk(cfg, agentId);\n}\n\nexport type AgentFileEntry = {\n name: string;\n missing: boolean;\n size?: number;\n updatedAtMs?: number;\n};\n\nasync function profileMarkdownRootReal(cfg: Config, agentId: string): Promise<string> {\n const dir = resolveAgentProfileDir(cfg, agentId);\n await mkdir(dir, { recursive: true });\n try {\n return await realpath(dir);\n } catch {\n return pathResolve(dir);\n }\n}\n\nfunction assertAllowedFile(name: string): AgentAdminResult<never> | null {\n if (!name || name.includes('/') || name.includes('\\\\') || !EDITABLE_PROFILE_MARKDOWN_NAMES.has(name)) {\n return { ok: false, error: `unsupported file \"${name}\"`, status: 400 };\n }\n return null;\n}\n\nexport async function listAgentProfileFiles(\n cfg: Config,\n agentId: string,\n): Promise<AgentAdminResult<{ agentId: string; profileDir: string; files: AgentFileEntry[] }>> {\n const id = normalizeAgentId(agentId);\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n const root = await profileMarkdownRootReal(cfg, id);\n const names = [...EDITABLE_PROFILE_MARKDOWN_NAMES];\n const files: AgentFileEntry[] = [];\n for (const name of names.sort((a, b) => a.localeCompare(b))) {\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n continue;\n }\n try {\n const st = await stat(abs);\n if (!st.isFile()) {\n continue;\n }\n files.push({\n name,\n missing: false,\n size: st.size,\n updatedAtMs: st.mtimeMs,\n });\n } catch {\n if (!REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET.has(name)) {\n continue;\n }\n files.push({ name, missing: true });\n }\n }\n files.sort((a, b) => a.name.localeCompare(b.name));\n return { ok: true, data: { agentId: id, profileDir: root, files } };\n}\n\nexport async function readAgentProfileFile(\n cfg: Config,\n agentId: string,\n name: string,\n): Promise<AgentAdminResult<{ agentId: string; content: string; path: string }>> {\n const bad = assertAllowedFile(name);\n if (bad) {\n return bad;\n }\n const id = normalizeAgentId(agentId);\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n const root = await profileMarkdownRootReal(cfg, id);\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n return { ok: false, error: 'invalid path', status: 400 };\n }\n try {\n const content = await readFile(abs, 'utf-8');\n return { ok: true, data: { agentId: id, content, path: abs } };\n } catch {\n return { ok: false, error: 'file not found', status: 404 };\n }\n}\n\nexport async function writeAgentProfileFile(\n cfg: Config,\n agentId: string,\n name: string,\n content: string,\n): Promise<AgentAdminResult<{ agentId: string; path: string }>> {\n const bad = assertAllowedFile(name);\n if (bad) {\n return bad;\n }\n const id = normalizeAgentId(agentId);\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n const root = await profileMarkdownRootReal(cfg, id);\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n return { ok: false, error: 'invalid path', status: 400 };\n }\n const rootReal = await profileMarkdownRootReal(cfg, id);\n if (!isPathUnderWorkspace(rootReal, abs)) {\n return { ok: false, error: 'path escapes profile markdown root', status: 400 };\n }\n await writeFile(abs, content, 'utf-8');\n return { ok: true, data: { agentId: id, path: abs } };\n}\n\nexport async function readUserProfileFile(): Promise<AgentAdminResult<{ content: string; path: string }>> {\n const path = resolveUserProfilePath();\n try {\n const content = await readFile(path, 'utf-8');\n return { ok: true, data: { content, path } };\n } catch {\n return { ok: true, data: { content: '', path } };\n }\n}\n\nexport async function writeUserProfileFile(\n content: string,\n): Promise<AgentAdminResult<{ path: string }>> {\n const path = resolveUserProfilePath();\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, content, 'utf-8');\n return { ok: true, data: { path } };\n}\n\n// ---------------------------------------------------------------------------\n// Binary agent avatar (profile markdown root dir, not a SOUL/IDENTITY markdown file)\n// ---------------------------------------------------------------------------\n\nconst AGENT_AVATAR_MAX_BYTES = 512 * 1024;\nconst AGENT_AVATAR_BASENAME = 'agent-avatar';\n\nconst AGENT_AVATAR_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.webp'] as const;\n\nfunction agentAvatarFilenames(): string[] {\n return AGENT_AVATAR_EXTENSIONS.map((ext) => `${AGENT_AVATAR_BASENAME}${ext}`);\n}\n\nfunction mimeToExt(mime: string): '.png' | '.jpg' | '.jpeg' | '.webp' | null {\n const m = mime.toLowerCase().trim();\n if (m === 'image/png') return '.png';\n if (m === 'image/jpeg' || m === 'image/jpg') return '.jpg';\n if (m === 'image/webp') return '.webp';\n return null;\n}\n\nfunction detectImageMimeFromBytes(buf: Uint8Array): 'image/png' | 'image/jpeg' | 'image/webp' | null {\n if (buf.length >= 8 && buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {\n return 'image/png';\n }\n if (buf.length >= 3 && buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff) {\n return 'image/jpeg';\n }\n if (\n buf.length >= 12 &&\n buf[0] === 0x52 &&\n buf[1] === 0x49 &&\n buf[2] === 0x46 &&\n buf[3] === 0x46 &&\n buf[8] === 0x57 &&\n buf[9] === 0x45 &&\n buf[10] === 0x42 &&\n buf[11] === 0x50\n ) {\n return 'image/webp';\n }\n return null;\n}\n\nfunction assertAgentExistsForAvatar(cfg: Config, id: string): AgentAdminResult<never> | null {\n if (collectAgentIdsForList(cfg).every((x) => x !== id)) {\n return { ok: false, error: `agent \"${id}\" not found`, status: 404 };\n }\n return null;\n}\n\nexport async function readAgentAvatarFile(\n cfg: Config,\n agentId: string,\n): Promise<AgentAdminResult<{ agentId: string; buffer: Buffer; contentType: string; path: string }>> {\n const missingAgent = assertAgentExistsForAvatar(cfg, agentId);\n if (missingAgent) {\n return missingAgent;\n }\n const id = normalizeAgentId(agentId);\n const root = await profileMarkdownRootReal(cfg, id);\n for (const name of agentAvatarFilenames()) {\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs) {\n continue;\n }\n try {\n const st = await stat(abs);\n if (!st.isFile() || st.size <= 0 || st.size > AGENT_AVATAR_MAX_BYTES) {\n continue;\n }\n const buffer = await readFile(abs);\n const detected = detectImageMimeFromBytes(buffer);\n if (!detected) {\n continue;\n }\n return { ok: true, data: { agentId: id, buffer, contentType: detected, path: abs } };\n } catch {\n /* try next */\n }\n }\n return { ok: false, error: 'avatar not found', status: 404 };\n}\n\nexport async function writeAgentAvatarFromBase64(\n cfg: Config,\n agentId: string,\n base64: string,\n mimeType: string,\n): Promise<AgentAdminResult<{ agentId: string; path: string }>> {\n const missingAgent = assertAgentExistsForAvatar(cfg, agentId);\n if (missingAgent) {\n return missingAgent;\n }\n const id = normalizeAgentId(agentId);\n const ext = mimeToExt(mimeType);\n if (!ext) {\n return { ok: false, error: 'unsupported mimeType (use image/png, image/jpeg, or image/webp)', status: 400 };\n }\n let raw: Buffer;\n try {\n raw = Buffer.from(base64, 'base64');\n } catch {\n return { ok: false, error: 'invalid base64', status: 400 };\n }\n if (raw.length === 0 || raw.length > AGENT_AVATAR_MAX_BYTES) {\n return { ok: false, error: `avatar must be non-empty and at most ${AGENT_AVATAR_MAX_BYTES} bytes`, status: 400 };\n }\n const detected = detectImageMimeFromBytes(raw);\n if (!detected || !extMatchesDetectedMime(ext, detected)) {\n return { ok: false, error: 'file content does not match declared image type', status: 400 };\n }\n\n const root = await profileMarkdownRootReal(cfg, id);\n const rootReal = await profileMarkdownRootReal(cfg, id);\n const targetName = `${AGENT_AVATAR_BASENAME}${ext}`;\n const abs = resolveWorkspaceSafePath(root, targetName);\n if (!abs || !isPathUnderWorkspace(rootReal, abs)) {\n return { ok: false, error: 'invalid path', status: 400 };\n }\n for (const name of agentAvatarFilenames()) {\n if (name === targetName) {\n continue;\n }\n const other = resolveWorkspaceSafePath(root, name);\n if (other && isPathUnderWorkspace(rootReal, other)) {\n try {\n await unlink(other);\n } catch {\n /* absent */\n }\n }\n }\n await writeFile(abs, raw);\n return { ok: true, data: { agentId: id, path: abs } };\n}\n\nfunction mimeToExtToMime(ext: '.png' | '.jpg' | '.jpeg' | '.webp'): 'image/png' | 'image/jpeg' | 'image/webp' {\n if (ext === '.png') return 'image/png';\n if (ext === '.webp') return 'image/webp';\n return 'image/jpeg';\n}\n\nfunction extMatchesDetectedMime(\n ext: '.png' | '.jpg' | '.jpeg' | '.webp',\n detected: 'image/png' | 'image/jpeg' | 'image/webp',\n): boolean {\n return detected === mimeToExtToMime(ext);\n}\n\n/** Remove any `agent-avatar.*` in the agent profile markdown root. Idempotent: ok even when no file existed. */\nexport async function deleteAgentAvatarFile(cfg: Config, agentId: string): Promise<AgentAdminResult<{ agentId: string }>> {\n const missingAgent = assertAgentExistsForAvatar(cfg, agentId);\n if (missingAgent) {\n return missingAgent;\n }\n const id = normalizeAgentId(agentId);\n const root = await profileMarkdownRootReal(cfg, id);\n const rootReal = await profileMarkdownRootReal(cfg, id);\n for (const name of agentAvatarFilenames()) {\n const abs = resolveWorkspaceSafePath(root, name);\n if (!abs || !isPathUnderWorkspace(rootReal, abs)) {\n continue;\n }\n try {\n await unlink(abs);\n } catch {\n /* absent */\n }\n }\n return { ok: true, data: { agentId: id } };\n}\n"],"mappings":"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"}
|
|
@@ -9,7 +9,8 @@ function normalizePresetId(id) {
|
|
|
9
9
|
return id.trim().toLowerCase();
|
|
10
10
|
}
|
|
11
11
|
function agentUsage(cfg, presetId) {
|
|
12
|
-
|
|
12
|
+
const defaultPresetId = cfg.agents.defaultPreset || "default";
|
|
13
|
+
return cfg.agents.list.filter((agent) => presetId === defaultPresetId || (agent.extends ?? []).includes(presetId)).map((agent) => ({
|
|
13
14
|
agentId: agent.id,
|
|
14
15
|
...agent.identity.name ? { agentName: agent.identity.name } : {}
|
|
15
16
|
})).sort((a, b) => a.agentId.localeCompare(b.agentId));
|
|
@@ -91,16 +92,19 @@ function nextConfigWithPresets(cfg, presets) {
|
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
function listCapabilityPresets(cfg) {
|
|
95
|
+
const presets = Object.values(presetMap(cfg)).map((preset) => ({
|
|
96
|
+
...preset,
|
|
97
|
+
usage: agentUsage(cfg, preset.id)
|
|
98
|
+
})).sort((a, b) => a.id.localeCompare(b.id));
|
|
99
|
+
const agents = cfg.agents.list.map((agent) => ({
|
|
100
|
+
id: agent.id,
|
|
101
|
+
...agent.identity.name ? { name: agent.identity.name } : {},
|
|
102
|
+
extends: [...agent.extends ?? []]
|
|
103
|
+
})).sort((a, b) => a.id.localeCompare(b.id));
|
|
94
104
|
return {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})).sort((a, b) => a.id.localeCompare(b.id)),
|
|
99
|
-
agents: cfg.agents.list.map((agent) => ({
|
|
100
|
-
id: agent.id,
|
|
101
|
-
...agent.identity.name ? { name: agent.identity.name } : {},
|
|
102
|
-
extends: [...agent.extends ?? []]
|
|
103
|
-
})).sort((a, b) => a.id.localeCompare(b.id)),
|
|
105
|
+
defaultPresetId: cfg.agents.defaultPreset,
|
|
106
|
+
presets,
|
|
107
|
+
agents,
|
|
104
108
|
builtinToolIds: [...GATEWAY_BUILTIN_TOOL_IDS]
|
|
105
109
|
};
|
|
106
110
|
}
|
|
@@ -198,6 +202,11 @@ function prepareDeleteCapabilityPreset(cfg, presetIdRaw) {
|
|
|
198
202
|
error: `capability preset "${presetId}" not found`,
|
|
199
203
|
status: 404
|
|
200
204
|
};
|
|
205
|
+
if (presetId === cfg.agents.defaultPreset) return {
|
|
206
|
+
ok: false,
|
|
207
|
+
error: `capability preset "${presetId}" is the global default and cannot be deleted`,
|
|
208
|
+
status: 409
|
|
209
|
+
};
|
|
201
210
|
const usage = agentUsage(cfg, presetId);
|
|
202
211
|
if (usage.length > 0) return {
|
|
203
212
|
ok: false,
|