@xopcai/xopc 0.0.127 → 0.0.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CgGgO4OV.js → agent-avatar-dicebear-DHzfg5D-.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CMxKKFQD.js +2 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-ptk9c5BN.js +1 -0
- package/dist/gateway/static/root/assets/{appearance-settings-BnHQW7Hv.js → appearance-settings-bYeEj3IW.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DdZvDf5B.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-5NXT7Zqv.js → archive-plugin-Dy6lsTHw.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DghwhYe0.js → attachment-load-qOtBYR6Y.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-DYmESgwl.js → automation-suggestion-card-BFH-RfaV.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-B8JTjkCr.js +4 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DSbPKdWX.js → binary-plugins-DJvi_thc.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CoZ-_np-.js → block-editor-DlMnizlt.js} +4 -4
- package/dist/gateway/static/root/assets/browser-settings-page-slHLiZgi.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-D4q7vHVJ.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Dng8Grpv.js +1 -0
- package/dist/gateway/static/root/assets/channel-recipient-api-BrW5Kcgc.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-KIsISXw0.js +1 -0
- package/dist/gateway/static/root/assets/{code-editor-gbRgS14t.js → code-editor--tMO38Tr.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-C5fx4Qs9.js +2 -0
- package/dist/gateway/static/root/assets/desktop-pet-Jmdn6q47.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-settings-npJ0Oh5p.js → desktop-pet-settings-B-u63N4e.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BR2ItBuf.js → directory-picker-path-field-8p1ehIHn.js} +1 -1
- package/dist/gateway/static/root/assets/dreaming-settings-CCkKP-I4.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Tl0f1rNv.js → extension-debug-page-DJ1ABK95.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Ck7QuwE3.js → extension-page-CP9P2lGM.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-DnhU-tx0.js +1 -0
- package/dist/gateway/static/root/assets/fetch-BMjlW0g1.js +1 -0
- package/dist/gateway/static/root/assets/gateway-config-api-CjxDn46s.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-TING7224.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Yh8h3hkj.js → gateway-startup-retry-CY5W2Pp4.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-2lPbGfp3.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-DHWVRafk.js +4 -0
- package/dist/gateway/static/root/assets/goals-config-api-BqhuxG8P.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-CMk-9ZYN.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-BHzOAU_l.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-BQIm0P3V.js +1 -0
- package/dist/gateway/static/root/assets/{html-workspace-editor-DV90ddkE.js → html-workspace-editor-COqmtESs.js} +1 -1
- package/dist/gateway/static/root/assets/index-C4k6QSXw.js +257 -0
- package/dist/gateway/static/root/assets/index-EKmpPvZj.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfQrt_Rb.js → keyboard-shortcuts-settings-BrENZzM7.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BiL302Ve.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-editor-BFOjBBla.js → markdown-editor-jD1LPiP-.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-BwiMdCf_.js → markdown-split-BYF4ReGM.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DhoizyZv.js → media-plugins-CpQDz-QJ.js} +1 -1
- package/dist/gateway/static/root/assets/messages-YzjnURPJ.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-CFPpl3Cq.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-BurgcdVZ.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-BAELRM_O.js +2 -0
- package/dist/gateway/static/root/assets/{page-tabs-DDC2t4Z8.js → page-tabs-RnYYOIWO.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BTmk-XDM.js → preview-open-alternatives-CTRt06Ri.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-iXX1Ceo2.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-GDVTFAY7.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BUrbUnwv.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-DqU-yKIh.js → save-bar-controls-c4pZeikq.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CUttkoSB.js → schedule-field-Cb6R7iuP.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-CVSQA9nI.js → schema-form-BqET_hEP.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CiOreA2k.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-C-qvptlu.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-CK7ogS-P.js → settings-collapsible-section-DuOvqNsI.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Bugp38Fa.js → settings-form-section-DptSsbWd.js} +1 -1
- package/dist/gateway/static/root/assets/settings-loading-skeleton-BlVfBCb9.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-DBRWwdhh.js → settings-page-layout-DVt69dJJ.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-xQx2Pkg5.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-DWB8VdLK.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-8m_ACH0z.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-CgxfhNxI.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BBFUOxmf.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-bo695odu.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-DJ6YuLqR.js → system-settings-panel-CW22OkZ4.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-B0T7N8Km.js → typed-models-lib-BqpGAKxV.js} +1 -1
- package/dist/gateway/static/root/assets/url-DFGNSBNT.js +1 -0
- package/dist/gateway/static/root/assets/use-channel-catalog-CPdJ0o0i.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-settings-panel-CERVLuaW.js +1 -0
- package/dist/gateway/static/root/assets/{utils-CehXcWAY.js → utils-BnmysurA.js} +1 -1
- package/dist/gateway/static/root/assets/vendor-codemirror-C1WKjCk5.js +45 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-Jr3jvPcB.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-B-8rex4u.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-c4jeaohQ.js → workflow-run-setup-panel-Ci9GSPnS.js} +2 -2
- package/dist/gateway/static/root/assets/{workflow-start-dialog-ENRHjoqa.js → workflow-start-dialog-BhDj8pqH.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-Brb3UGvs.js +18 -0
- package/dist/gateway/static/root/index.html +7 -6
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +3 -0
- package/dist/src/agent/agent-manager.js +14 -6
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/capabilities/definitions.d.ts +14 -0
- package/dist/src/agent/capabilities/definitions.js +19 -0
- package/dist/src/agent/capabilities/definitions.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +23 -2
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/messaging/command-handler.d.ts +4 -0
- package/dist/src/agent/messaging/command-handler.js +6 -0
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +23 -0
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/skills/hub-lock.d.ts +5 -5
- package/dist/src/agent/skills/hub-lock.js +12 -12
- package/dist/src/agent/skills/hub-lock.js.map +1 -1
- package/dist/src/agent/skills/hub-pull.d.ts +15 -0
- package/dist/src/agent/skills/hub-pull.js +299 -24
- package/dist/src/agent/skills/hub-pull.js.map +1 -1
- package/dist/src/agent/skills/index.js +4 -40
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/install-target.d.ts +3 -0
- package/dist/src/agent/skills/install-target.js +11 -0
- package/dist/src/agent/skills/install-target.js.map +1 -0
- package/dist/src/agent/skills/managed-store.d.ts +5 -3
- package/dist/src/agent/skills/managed-store.js +10 -9
- package/dist/src/agent/skills/managed-store.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +5 -3
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +21 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +62 -6
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
- package/dist/src/agent/skills/marketplace/resolve-adapter.js +1 -1
- package/dist/src/agent/skills/marketplace/resolve-adapter.js.map +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -2
- package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -6
- package/dist/src/agent/skills/skill-manager.js.map +1 -1
- package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
- package/dist/src/agent/skills/workspace-skills-dir.js +5 -1
- package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +6 -6
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +20 -20
- package/dist/src/agent/tools/composio-tool.d.ts +3 -3
- package/dist/src/agent/tools/desktop-pet-tool.d.ts +7 -7
- package/dist/src/agent/tools/factory.d.ts +3 -0
- package/dist/src/agent/tools/factory.js +6 -1
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/goal-tool.d.ts +16 -16
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/skill-install-tool.d.ts +28 -0
- package/dist/src/agent/tools/skill-install-tool.js +81 -0
- package/dist/src/agent/tools/skill-install-tool.js.map +1 -0
- package/dist/src/agent/tools/skill-manage-tool.js +3 -6
- package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
- package/dist/src/agent/tools/tool-manual-tool.d.ts +2 -2
- package/dist/src/agent/tools/xopc-use-tool.d.ts +5 -5
- package/dist/src/automations/domain/types.d.ts +1 -0
- package/dist/src/automations/draft/automation-draft-service.js +1 -1
- package/dist/src/automations/service/automation-service.js +9 -0
- package/dist/src/automations/service/automation-service.js.map +1 -1
- package/dist/src/browser/schemas.d.ts +52 -52
- package/dist/src/capabilities/store-connector.d.ts +17 -0
- package/dist/src/capabilities/store-connector.js +191 -0
- package/dist/src/capabilities/store-connector.js.map +1 -0
- package/dist/src/chat-commands/builtins/skill.d.ts +1 -0
- package/dist/src/chat-commands/builtins/skill.js +132 -0
- package/dist/src/chat-commands/builtins/skill.js.map +1 -0
- package/dist/src/chat-commands/context.d.ts +3 -0
- package/dist/src/chat-commands/context.js +2 -0
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -0
- package/dist/src/chat-commands/index.js +3 -1
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +17 -0
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/connectors.d.ts +4 -0
- package/dist/src/cli/commands/connectors.js +96 -0
- package/dist/src/cli/commands/connectors.js.map +1 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/commands/tunnel.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/config/schema.js +2 -2
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/connectors/install.js +3 -1
- package/dist/src/connectors/install.js.map +1 -1
- package/dist/src/connectors/materialize.js +2 -0
- package/dist/src/connectors/materialize.js.map +1 -1
- package/dist/src/connectors/types.d.ts +19 -1
- package/dist/src/extensions/install.js +1 -1
- package/dist/src/extensions/types/manifest.d.ts +1 -1
- package/dist/src/extensions/update.js +5 -3
- package/dist/src/extensions/update.js.map +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +5 -1
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +2 -0
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/middleware/auth.d.ts +2 -2
- package/dist/src/gateway/hono/middleware/logger.d.ts +1 -1
- package/dist/src/gateway/hono/middleware/route-errors.d.ts +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +2 -2
- package/dist/src/gateway/hono/routes/capabilities.d.ts +3 -0
- package/dist/src/gateway/hono/routes/capabilities.js +79 -0
- package/dist/src/gateway/hono/routes/capabilities.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +81 -3
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +2 -2
- package/dist/src/gateway/hono/routes/goals.js +212 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/index.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/mobile.d.ts +3 -0
- package/dist/src/gateway/hono/routes/mobile.js +113 -0
- package/dist/src/gateway/hono/routes/mobile.js.map +1 -0
- package/dist/src/gateway/hono/routes/projects.js +17 -0
- package/dist/src/gateway/hono/routes/projects.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +4 -1
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +3 -3
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +23 -1
- package/dist/src/gateway/service/marketplace-service.js +57 -6
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +12 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-contract-draft.d.ts +15 -0
- package/dist/src/goals/goal-contract-draft.js +114 -0
- package/dist/src/goals/goal-contract-draft.js.map +1 -0
- package/dist/src/goals/goal-evidence-review.d.ts +15 -0
- package/dist/src/goals/goal-evidence-review.js +91 -0
- package/dist/src/goals/goal-evidence-review.js.map +1 -0
- package/dist/src/goals/goal-runner.js +3 -1
- package/dist/src/goals/goal-runner.js.map +1 -1
- package/dist/src/goals/goal-service.d.ts +17 -1
- package/dist/src/goals/goal-service.js +44 -3
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-store.d.ts +18 -1
- package/dist/src/goals/goal-store.js +190 -1
- package/dist/src/goals/goal-store.js.map +1 -1
- package/dist/src/goals/index.d.ts +4 -0
- package/dist/src/goals/index.js +3 -1
- package/dist/src/goals/types.d.ts +42 -0
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/mobile/notification-service.d.ts +8 -0
- package/dist/src/mobile/notification-service.js +139 -0
- package/dist/src/mobile/notification-service.js.map +1 -0
- package/dist/src/mobile/notification-store.d.ts +28 -0
- package/dist/src/mobile/notification-store.js +134 -0
- package/dist/src/mobile/notification-store.js.map +1 -0
- package/dist/src/mobile/notification-types.d.ts +37 -0
- package/dist/src/mobile/notification-types.js +11 -0
- package/dist/src/mobile/notification-types.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/026_goal_contracts.sql +10 -0
- package/dist/src/storage/sqlite/migrations/027_mobile_notifications.sql +43 -0
- package/dist/src/storage/sqlite/migrations/028_goal_evidence_requirements.sql +47 -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 +44 -0
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/package.json +1 -1
- package/skills/THIRD_PARTY_NOTICES.md +16 -0
- package/skills/creative/algorithmic-art/SKILL.md +37 -0
- package/skills/creative/algorithmic-art/templates/generator-template.js +27 -0
- package/skills/creative/algorithmic-art/templates/viewer.html +27 -0
- package/skills/documents/doc-coauthoring/SKILL.md +40 -0
- package/skills/documents/doc-coauthoring/references/reader-review.md +9 -0
- package/skills/documents/docx/SKILL.md +40 -0
- package/skills/documents/docx/references/editing-checklist.md +8 -0
- package/skills/documents/docx/scripts/inspect_ooxml.py +36 -0
- package/skills/documents/docx/scripts/render_docx.py +33 -0
- package/skills/documents/pdf/SKILL.md +47 -0
- package/skills/documents/pdf/references/operations.md +16 -0
- package/skills/documents/pdf/scripts/inspect_pdf.py +41 -0
- package/skills/documents/pdf/scripts/render_pdf.py +32 -0
- package/skills/documents/pptx/SKILL.md +41 -0
- package/skills/documents/pptx/references/qa-checklist.md +6 -0
- package/skills/documents/pptx/scripts/inspect_ooxml.py +34 -0
- package/skills/documents/pptx/scripts/render_pptx.py +33 -0
- package/skills/engineering/define-goal/SKILL.md +41 -0
- package/skills/engineering/define-goal/references/objective-rubric.md +12 -0
- package/dist/gateway/static/root/assets/agents-k59l7NMb.js +0 -2
- package/dist/gateway/static/root/assets/app-management-settings-panel-DeQsTsyy.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BG9b4abG.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-De8mVutL.js +0 -4
- package/dist/gateway/static/root/assets/browser-settings-page-C_ZRa4LF.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-api-hny224j-.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Drc0qLsw.js +0 -1
- package/dist/gateway/static/root/assets/channel-recipient-api-DAlOHxKJ.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CA20zBV9.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-qMyMB5te.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-XG6Vb_fZ.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-CkUZ997f.js +0 -3
- package/dist/gateway/static/root/assets/extension-settings-page-3RMhQtZ3.js +0 -1
- package/dist/gateway/static/root/assets/fetch-pg2ErdAk.js +0 -1
- package/dist/gateway/static/root/assets/gateway-config-api-DbG97ia2.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-B8cyqKk-.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-DmeW7Zz3.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DrTyGbVD.js +0 -1
- package/dist/gateway/static/root/assets/goals-config-api-CxCWGIBB.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-DV1bJhIh.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-9DrfOkP5.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-KaDpZrv0.js +0 -1
- package/dist/gateway/static/root/assets/index-C2F0Clvm.js +0 -256
- package/dist/gateway/static/root/assets/index-COQSX5d_.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-C9dpiNTF.js +0 -2
- package/dist/gateway/static/root/assets/messages-DmnbiNxU.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-zdCdmBmH.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-MpGeFfPt.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-DYCM3yd2.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-Cu0ElRnS.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DakNaUjZ.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DYKjt7L9.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CcGHDsz1.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CuFdeKNu.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-0AJoUvxi.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D6a_hEk7.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-BtsuETKF.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-CcEFT7S9.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BcN_RuTD.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BbRZZZA5.js +0 -2
- package/dist/gateway/static/root/assets/use-channel-catalog-C6vrxdzZ.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-DZ0nKMgj.js +0 -1
- package/dist/gateway/static/root/assets/vendor-codemirror-BvNgyE1Q.js +0 -45
- package/dist/gateway/static/root/assets/voice-api-key-field-2QKflCx8.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-DfJnuWq1.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BJwwFTm_.js +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","names":[],"sources":["../../../../src/agent/tools/factory.ts"],"sourcesContent":["/**\n * Agent Tools Factory - Creates and configures agent tools\n *\n * Centralizes tool creation logic to keep service.ts focused on orchestration.\n *\n * TTS: auto TTS is applied at the ChannelManager via maybeApplyTtsToPayload().\n * Optional \\`text_to_speech\\` tool sends explicit voice when TTS is enabled.\n */\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { Page } from 'playwright-core';\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport {\n createReadFileTool,\n createWriteFileTool,\n createApplyPatchTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createExecCommandTool,\n createWebSearchTool,\n createWebFetchTool,\n createWebExtractTool,\n createMessageTool,\n createComposioExecuteTool,\n createSendMediaTool,\n createReadMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createUpdatePlanTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n createToolManualTool,\n createGoalTool,\n createAutomationTool,\n createXopcUseTool,\n createDesktopPetTool,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { MemoryManager } from '../memory/manager.js';\nimport { shouldRegisterCuratedMemoryTool } from '../memory/memory-config.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { GatewayClarifyRequestFn } from './clarify-tool.js';\nimport { createImageTool } from './image-tool.js';\nimport { createImageGenerateTool } from './image-generate-tool.js';\nimport {\n BrowserManager,\n BrowserNotReadyError,\n CdpSupervisor,\n checkBrowserReadiness,\n resolveBrowserBackendFromConfig,\n} from '../../browser/index.js';\nimport { createBrowserUseTool } from './browser/tool/browser-use-tool.js';\nimport { createDelegateTool } from './delegate-tool.js';\nimport { createWorkflowTool } from './workflow-tool.js';\nimport { createWorkflowCatalog } from '../workflow/catalog.js';\nimport { resolveDreamingRootForAgent } from '../memory/dreaming/scope.js';\nimport { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport type { AutomationService } from '../../automations/index.js';\nimport type { NotesService } from '../../notes/index.js';\nimport type { ProjectService } from '../../projects/index.js';\nimport type { WorkItemService } from '../../work-items/index.js';\nimport type { WorkflowRunServiceLike } from '../../workflows/service/workflow-run-service.types.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { wrapToolsWithProtection, type ToolExecutorConfig } from './executor.js';\nimport { createSkillsListTool, createSkillViewTool } from './skills-tools.js';\nimport { createSkillManageTool } from './skill-manage-tool.js';\nimport { createTextToSpeechTool } from './tts-tool.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\nimport { createGoalEvidenceRecorder } from './goal-evidence-recorder.js';\nimport { getAgentCapabilityToolNames } from '../capabilities/index.js';\n\nconst log = createLogger('AgentToolsFactory');\n\n/** Channels where `clarify` can block for a user answer (web UI, Telegram, CLI readline). */\nconst CLARIFY_SUPPORTED_CHANNELS = new Set(['webchat', 'telegram', 'cli']);\n\nexport interface ToolFactoryDeps {\n workspace: string;\n extensionRegistry?: any;\n getCurrentContext: () => { channel: string; chatId: string; sessionKey: string } | null;\n hookRunner?: import('../../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n toolExecutorConfig?: Partial<ToolExecutorConfig>;\n /** Agent defaults (image tools, etc.); use getter so hot-reloaded config applies. */\n getConfig?: () => Config | undefined;\n /** Session / default chat model for vision tool description. */\n getPrimaryModel?: () => Model<Api>;\n /** Memory orchestration (prefetch/sync + external tools). */\n getMemoryManager?: () => MemoryManager;\n /** Session store for `session_search`. */\n getSessionStore?: () => SessionStore;\n /** When set (gateway webchat), enables the `clarify` tool. */\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: enables the `automation` tool. */\n getAutomationService?: () => AutomationService | undefined;\n /** Gateway: enables the `xopc_use` product-object tool. */\n getNotesService?: () => NotesService | undefined;\n getProjectService?: () => ProjectService | undefined;\n getWorkItemService?: () => WorkItemService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => WorkflowRunServiceLike | undefined;\n /** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */\n onSkillsFilesystemMutate?: () => void;\n /** Names registered via skill_view for command env passthrough. */\n getSkillPassthroughEnvVarNames?: () => string[];\n /** Add declared env names for the current session (no values stored). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nexport interface CreateCoreToolsOptions {\n /** Workspace root for file/command tools (defaults to factory workspace). */\n workspace?: string;\n /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */\n profileMarkdownRoot?: string;\n /** Tool `name` values to omit (e.g. `exec_command`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getMemoryManager?: () => MemoryManager;\n /** Agent-scoped memories directory used for dreaming state (`agents/<id>/memories`). */\n dreamingRoot?: string;\n agentId?: string;\n /** When set, registers `skills_list` and `skill_view` bound to this workspace\\'s skills. */\n getSkillManager?: () => SkillManager;\n}\n\nexport class AgentToolsFactory {\n private browserManager: BrowserManager | null = null;\n /** One dialog/console supervisor per chat session (browser tab). */\n private readonly browserTaskSupervisors = new Map<string, CdpSupervisor>();\n /** Cached readiness probe — keyed by backend mode + extension host:port. */\n private browserReadinessCache: {\n key: string;\n expiresAt: number;\n inflight?: Promise<BrowserNotReadyError | null>;\n result?: BrowserNotReadyError | null;\n } | null = null;\n\n constructor(private deps: ToolFactoryDeps) {}\n\n private browserReadinessKey(): string {\n const cfg = this.deps.getConfig?.();\n const backend = resolveBrowserBackendFromConfig(cfg);\n const host = '127.0.0.1';\n const port = 19820;\n const cdpUrl = backend.mode === 'cdp' ? backend.config.wsEndpoint : '';\n const cloudKind = backend.mode === 'cloud' ? backend.config.type : '';\n return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;\n }\n\n private async checkBrowserReadinessCached(): Promise<BrowserNotReadyError | null> {\n const key = this.browserReadinessKey();\n const now = Date.now();\n const cached = this.browserReadinessCache;\n if (cached && cached.key === key && cached.expiresAt > now && cached.inflight === undefined) {\n return cached.result ?? null;\n }\n if (cached && cached.key === key && cached.inflight) {\n return cached.inflight;\n }\n const inflight = checkBrowserReadiness(this.deps.getConfig?.());\n this.browserReadinessCache = { key, expiresAt: now + 30_000, inflight };\n try {\n const result = await inflight;\n this.browserReadinessCache = { key, expiresAt: Date.now() + 30_000, result };\n return result;\n } catch (e) {\n // Probe should never throw, but if it does we just bypass the cache.\n this.browserReadinessCache = null;\n log.warn({ err: e }, 'browserReadiness probe failed');\n return null;\n }\n }\n\n /** Invalidate the readiness cache (config hot-reload, settings-page save, etc.). */\n invalidateBrowserReadinessCache(): void {\n this.browserReadinessCache = null;\n }\n\n private browserSupervisorForTask(taskId: string): CdpSupervisor {\n let s = this.browserTaskSupervisors.get(taskId);\n if (!s) {\n s = new CdpSupervisor({ dialogPolicy: 'auto_dismiss', dialogTimeoutSeconds: 300 });\n this.browserTaskSupervisors.set(taskId, s);\n }\n return s;\n }\n\n private async acquireBrowserPage(): Promise<Page> {\n const taskId = this.deps.getCurrentContext()?.sessionKey ?? 'default';\n const mgr = this.ensureBrowserManager();\n await mgr.ensureConnected();\n if (mgr.getExtensionProvider()) {\n return null as unknown as Page;\n }\n const page = await mgr.getPage(taskId);\n this.browserSupervisorForTask(taskId).attach(page);\n return page;\n }\n\n private ensureBrowserManager(): BrowserManager {\n if (!this.browserManager) {\n this.browserManager = new BrowserManager({\n getHeadless: () => false,\n getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.()),\n });\n }\n return this.browserManager;\n }\n\n /** Close Playwright and all pages (gateway stop, agent manager dispose, or config hot-reload). */\n async shutdownBrowser(): Promise<void> {\n this.browserReadinessCache = null;\n if (!this.browserManager) {\n return;\n }\n await this.browserManager.shutdown();\n this.browserManager = null;\n this.browserTaskSupervisors.clear();\n }\n\n /** Drop the tab for a session when its agent instance is removed. */\n async closeBrowserPageForSession(sessionKey: string): Promise<void> {\n this.browserTaskSupervisors.delete(sessionKey);\n await this.browserManager?.closePage(sessionKey);\n }\n\n createCoreTools(options?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const workspace = options?.workspace ?? this.deps.workspace;\n const { bus } = this.deps;\n const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;\n const getSkillMgr = options?.getSkillManager;\n const disabled = options?.disabledTools;\n\n const primary = getPrimary?.();\n const modelHasVision = primary?.input?.includes('image') ?? false;\n const cfg = this.deps.getConfig?.();\n const dreamingRoot = options?.dreamingRoot ?? (cfg ? resolveDreamingRootForAgent(cfg, options?.agentId) : workspace);\n const browserEnabled = cfg?.browser?.enabled !== false;\n const recordGoalEvidence = createGoalEvidenceRecorder({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n });\n const imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const composioTool = createComposioExecuteTool(() => this.deps.getConfig?.());\n const optionalTools = [imageTool, imageGenerateTool, composioTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\n const applyPatchTool = createApplyPatchTool(workspace, { recordGoalEvidence });\n const listDir = createListDirTool(workspace);\n const grep = createGrepTool(workspace);\n const find = createFindTool(workspace);\n\n const core: AgentTool<any, any>[] = [\n createSessionStatusTool(),\n createDreamingTool({\n getWorkspace: () => workspace,\n getDreamingRoot: () => dreamingRoot,\n getConfig: () => this.deps.getConfig?.(),\n getAgentId: () => options?.agentId,\n }),\n createToolManualTool(),\n createClarifyTool({\n resolveAskUser: () => {\n const req = this.deps.gatewayClarify?.requestClarification;\n if (!req) return null;\n const ctx = this.deps.getCurrentContext();\n if (!ctx?.sessionKey) return null;\n if (!CLARIFY_SUPPORTED_CHANNELS.has(ctx.channel)) return null;\n return (r) => req(ctx.sessionKey, r);\n },\n }),\n createTodoTool({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n createUpdatePlanTool(),\n ...(getSkillMgr\n ? [\n createSkillsListTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n }),\n createSkillViewTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n registerSkillEnvPassthrough: this.deps.registerSkillEnvPassthrough,\n }),\n createSkillManageTool({\n getSkillManager: getSkillMgr,\n getWorkspace: () => workspace,\n onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate,\n }),\n ]\n : []),\n readTool,\n writeTool,\n applyPatchTool,\n listDir,\n grep,\n find,\n createExecCommandTool(workspace, {\n getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,\n recordGoalEvidence,\n }),\n createWebSearchTool(() => this.deps.getConfig?.()),\n createWebFetchTool(() => this.deps.getConfig?.()),\n createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),\n // Note: TTS is NOT handled by send_message tool anymore\n // TTS is applied at the ChannelManager dispatch layer\n createMessageTool(bus, () => this.deps.getCurrentContext()),\n ...(mergeTtsConfigFromAppConfig(cfg?.messages?.tts).enabled\n ? [\n createTextToSpeechTool({\n bus,\n getContext: () => this.deps.getCurrentContext(),\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),\n createReadMediaTool(),\n ...(isShareToolAvailable(cfg)\n ? [\n createCreateShareTool({\n workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n ...(getMemMgr\n ? [\n createMemorySearchTool({ workspaceDir: workspace, dreamingRoot, getMemoryManager: () => getMemMgr() }),\n createMemoryGetTool({ workspaceDir: workspace, dreamingRoot, getMemoryManager: () => getMemMgr() }),\n ]\n : []),\n ...(getMemMgr && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(() => getMemMgr()),\n ]\n : []),\n ...(getMemMgr?.().getAdditionalTools() ?? []),\n ...(this.deps.getSessionStore\n ? [\n createSessionSearchTool({\n getSessionStore: this.deps.getSessionStore,\n getConfig: this.deps.getConfig,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ]\n : []),\n ...(this.deps.getAutomationService\n ? [\n createAutomationTool({\n getAutomationService: this.deps.getAutomationService,\n }),\n ]\n : []),\n ...(this.deps.getProjectService || this.deps.getNotesService || this.deps.getWorkItemService\n ? [\n createXopcUseTool({\n getConfig: () => this.deps.getConfig?.(),\n getCurrentAgentId: () => options.agentId,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getNotesService: this.deps.getNotesService,\n getProjectService: this.deps.getProjectService,\n getWorkItemService: this.deps.getWorkItemService,\n }),\n ]\n : []),\n createGoalTool({\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(browserEnabled\n ? [\n createBrowserUseTool({\n getManager: () => this.ensureBrowserManager(),\n getPageForTask: () => this.acquireBrowserPage(),\n getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? 'default',\n getConfig: () => this.deps.getConfig?.(),\n getReadiness: () => this.checkBrowserReadinessCached(),\n getSupervisor: () =>\n this.browserSupervisorForTask(this.deps.getCurrentContext()?.sessionKey ?? 'default'),\n notifyBrowserPageClosed: (taskId) => {\n this.browserTaskSupervisors.delete(taskId);\n },\n }),\n ]\n : []),\n ...(primary\n ? [\n createWorkflowTool({\n catalog: createWorkflowCatalog(),\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getConfig: () => this.deps.getConfig?.(),\n startWorkflowRun: this.deps.getWorkflowRunService\n ? (params) => this.deps.getWorkflowRunService!().startWorkflowRun(params)\n : undefined,\n }),\n ]\n : []),\n ...(false && primary\n ? [\n createDelegateTool({\n workspace,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for delegate_task');\n }\n return m;\n },\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,\n hookRunner: this.deps.hookRunner,\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `child-agent-factory.ts` does not need to import\n // `AgentToolsFactory` directly (which would form a cycle).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n agentId: options?.agentId ?? childOpts.agentId,\n dreamingRoot: options?.dreamingRoot,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createCapabilityTools(\n capabilityNames: readonly string[],\n options?: Pick<CreateCoreToolsOptions, 'disabledTools'>,\n ): AgentTool<any, any>[] {\n const disabled = options?.disabledTools;\n const raw: AgentTool<any, any>[] = [];\n const toolNames = new Set<string>();\n for (const toolName of getAgentCapabilityToolNames(capabilityNames)) {\n if (disabled?.has(toolName) || toolNames.has(toolName)) continue;\n toolNames.add(toolName);\n if (toolName === 'create_desktop_pet') raw.push(createDesktopPetTool() as AgentTool<any, any>);\n }\n return wrapToolsWithProtection(raw, this.deps.toolExecutorConfig);\n }\n\n getLazyCapabilityToolNames(): string[] {\n return ['create_desktop_pet'];\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n\n let bundled: AgentTool<any, any>[];\n if (!this.deps.extensionRegistry || disableExtensions) {\n bundled = coreTools;\n } else {\n const extensionTools = this.deps.extensionRegistry.getAllTools();\n log.info({ count: extensionTools.length }, 'Loaded extension tools');\n bundled = [...coreTools, ...extensionTools];\n }\n\n const wrapped = wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);\n\n const executeEnabled = false && !coreOptions?.disabledTools?.has('execute_code');\n\n if (executeEnabled) {\n const sandboxMap = buildSandboxToolMap(wrapped);\n const executeTool = createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap });\n const wrappedExecute = wrapToolsWithProtection([executeTool as any], this.deps.toolExecutorConfig);\n return [...wrapped, ...wrappedExecute];\n }\n\n return wrapped;\n }\n}\n\nfunction filterToolsByDisabledSet(\n tools: any[],\n disabled: Set<string> | undefined,\n): any[] {\n if (!disabled || disabled.size === 0) {\n return tools;\n }\n return tools.filter((t) => !disabled.has(t.name));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"factory.js","names":[],"sources":["../../../../src/agent/tools/factory.ts"],"sourcesContent":["/**\n * Agent Tools Factory - Creates and configures agent tools\n *\n * Centralizes tool creation logic to keep service.ts focused on orchestration.\n *\n * TTS: auto TTS is applied at the ChannelManager via maybeApplyTtsToPayload().\n * Optional \\`text_to_speech\\` tool sends explicit voice when TTS is enabled.\n */\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { Page } from 'playwright-core';\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport {\n createReadFileTool,\n createWriteFileTool,\n createApplyPatchTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createExecCommandTool,\n createWebSearchTool,\n createWebFetchTool,\n createWebExtractTool,\n createMessageTool,\n createComposioExecuteTool,\n createSendMediaTool,\n createReadMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createUpdatePlanTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n createToolManualTool,\n createGoalTool,\n createAutomationTool,\n createXopcUseTool,\n createDesktopPetTool,\n createSkillInstallTool,\n type SkillInstallToolOptions,\n type SkillInstallToolResult,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { MemoryManager } from '../memory/manager.js';\nimport { shouldRegisterCuratedMemoryTool } from '../memory/memory-config.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { GatewayClarifyRequestFn } from './clarify-tool.js';\nimport { createImageTool } from './image-tool.js';\nimport { createImageGenerateTool } from './image-generate-tool.js';\nimport {\n BrowserManager,\n BrowserNotReadyError,\n CdpSupervisor,\n checkBrowserReadiness,\n resolveBrowserBackendFromConfig,\n} from '../../browser/index.js';\nimport { createBrowserUseTool } from './browser/tool/browser-use-tool.js';\nimport { createDelegateTool } from './delegate-tool.js';\nimport { createWorkflowTool } from './workflow-tool.js';\nimport { createWorkflowCatalog } from '../workflow/catalog.js';\nimport { resolveDreamingRootForAgent } from '../memory/dreaming/scope.js';\nimport { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport type { AutomationService } from '../../automations/index.js';\nimport type { NotesService } from '../../notes/index.js';\nimport type { ProjectService } from '../../projects/index.js';\nimport type { WorkItemService } from '../../work-items/index.js';\nimport type { WorkflowRunServiceLike } from '../../workflows/service/workflow-run-service.types.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { wrapToolsWithProtection, type ToolExecutorConfig } from './executor.js';\nimport { createSkillsListTool, createSkillViewTool } from './skills-tools.js';\nimport { createSkillManageTool } from './skill-manage-tool.js';\nimport { createTextToSpeechTool } from './tts-tool.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\nimport { createGoalEvidenceRecorder } from './goal-evidence-recorder.js';\nimport { getAgentCapabilityToolNames } from '../capabilities/index.js';\n\nconst log = createLogger('AgentToolsFactory');\n\n/** Channels where `clarify` can block for a user answer (web UI, Telegram, CLI readline). */\nconst CLARIFY_SUPPORTED_CHANNELS = new Set(['webchat', 'telegram', 'cli']);\n\nexport interface ToolFactoryDeps {\n workspace: string;\n extensionRegistry?: any;\n getCurrentContext: () => { channel: string; chatId: string; sessionKey: string } | null;\n hookRunner?: import('../../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n toolExecutorConfig?: Partial<ToolExecutorConfig>;\n /** Agent defaults (image tools, etc.); use getter so hot-reloaded config applies. */\n getConfig?: () => Config | undefined;\n /** Session / default chat model for vision tool description. */\n getPrimaryModel?: () => Model<Api>;\n /** Memory orchestration (prefetch/sync + external tools). */\n getMemoryManager?: () => MemoryManager;\n /** Session store for `session_search`. */\n getSessionStore?: () => SessionStore;\n /** When set (gateway webchat), enables the `clarify` tool. */\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: enables the `automation` tool. */\n getAutomationService?: () => AutomationService | undefined;\n /** Gateway: enables the `xopc_use` product-object tool. */\n getNotesService?: () => NotesService | undefined;\n getProjectService?: () => ProjectService | undefined;\n getWorkItemService?: () => WorkItemService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => WorkflowRunServiceLike | undefined;\n /** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */\n onSkillsFilesystemMutate?: () => void;\n /** Names registered via skill_view for command env passthrough. */\n getSkillPassthroughEnvVarNames?: () => string[];\n /** Add declared env names for the current session (no values stored). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n /** Install managed skills from explicit sources when a capability/tool enables it. */\n installSkillFromSource?: (opts: SkillInstallToolOptions) => Promise<SkillInstallToolResult>;\n}\n\nexport interface CreateCoreToolsOptions {\n /** Workspace root for file/command tools (defaults to factory workspace). */\n workspace?: string;\n /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */\n profileMarkdownRoot?: string;\n /** Tool `name` values to omit (e.g. `exec_command`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getMemoryManager?: () => MemoryManager;\n /** Agent-scoped memories directory used for dreaming state (`agents/<id>/memories`). */\n dreamingRoot?: string;\n agentId?: string;\n /** When set, registers `skills_list` and `skill_view` bound to this workspace\\'s skills. */\n getSkillManager?: () => SkillManager;\n}\n\nexport class AgentToolsFactory {\n private browserManager: BrowserManager | null = null;\n /** One dialog/console supervisor per chat session (browser tab). */\n private readonly browserTaskSupervisors = new Map<string, CdpSupervisor>();\n /** Cached readiness probe — keyed by backend mode + extension host:port. */\n private browserReadinessCache: {\n key: string;\n expiresAt: number;\n inflight?: Promise<BrowserNotReadyError | null>;\n result?: BrowserNotReadyError | null;\n } | null = null;\n\n constructor(private deps: ToolFactoryDeps) {}\n\n private browserReadinessKey(): string {\n const cfg = this.deps.getConfig?.();\n const backend = resolveBrowserBackendFromConfig(cfg);\n const host = '127.0.0.1';\n const port = 19820;\n const cdpUrl = backend.mode === 'cdp' ? backend.config.wsEndpoint : '';\n const cloudKind = backend.mode === 'cloud' ? backend.config.type : '';\n return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;\n }\n\n private async checkBrowserReadinessCached(): Promise<BrowserNotReadyError | null> {\n const key = this.browserReadinessKey();\n const now = Date.now();\n const cached = this.browserReadinessCache;\n if (cached && cached.key === key && cached.expiresAt > now && cached.inflight === undefined) {\n return cached.result ?? null;\n }\n if (cached && cached.key === key && cached.inflight) {\n return cached.inflight;\n }\n const inflight = checkBrowserReadiness(this.deps.getConfig?.());\n this.browserReadinessCache = { key, expiresAt: now + 30_000, inflight };\n try {\n const result = await inflight;\n this.browserReadinessCache = { key, expiresAt: Date.now() + 30_000, result };\n return result;\n } catch (e) {\n // Probe should never throw, but if it does we just bypass the cache.\n this.browserReadinessCache = null;\n log.warn({ err: e }, 'browserReadiness probe failed');\n return null;\n }\n }\n\n /** Invalidate the readiness cache (config hot-reload, settings-page save, etc.). */\n invalidateBrowserReadinessCache(): void {\n this.browserReadinessCache = null;\n }\n\n private browserSupervisorForTask(taskId: string): CdpSupervisor {\n let s = this.browserTaskSupervisors.get(taskId);\n if (!s) {\n s = new CdpSupervisor({ dialogPolicy: 'auto_dismiss', dialogTimeoutSeconds: 300 });\n this.browserTaskSupervisors.set(taskId, s);\n }\n return s;\n }\n\n private async acquireBrowserPage(): Promise<Page> {\n const taskId = this.deps.getCurrentContext()?.sessionKey ?? 'default';\n const mgr = this.ensureBrowserManager();\n await mgr.ensureConnected();\n if (mgr.getExtensionProvider()) {\n return null as unknown as Page;\n }\n const page = await mgr.getPage(taskId);\n this.browserSupervisorForTask(taskId).attach(page);\n return page;\n }\n\n private ensureBrowserManager(): BrowserManager {\n if (!this.browserManager) {\n this.browserManager = new BrowserManager({\n getHeadless: () => false,\n getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.()),\n });\n }\n return this.browserManager;\n }\n\n /** Close Playwright and all pages (gateway stop, agent manager dispose, or config hot-reload). */\n async shutdownBrowser(): Promise<void> {\n this.browserReadinessCache = null;\n if (!this.browserManager) {\n return;\n }\n await this.browserManager.shutdown();\n this.browserManager = null;\n this.browserTaskSupervisors.clear();\n }\n\n /** Drop the tab for a session when its agent instance is removed. */\n async closeBrowserPageForSession(sessionKey: string): Promise<void> {\n this.browserTaskSupervisors.delete(sessionKey);\n await this.browserManager?.closePage(sessionKey);\n }\n\n createCoreTools(options?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const workspace = options?.workspace ?? this.deps.workspace;\n const { bus } = this.deps;\n const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;\n const getSkillMgr = options?.getSkillManager;\n const disabled = options?.disabledTools;\n\n const primary = getPrimary?.();\n const modelHasVision = primary?.input?.includes('image') ?? false;\n const cfg = this.deps.getConfig?.();\n const dreamingRoot = options?.dreamingRoot ?? (cfg ? resolveDreamingRootForAgent(cfg, options?.agentId) : workspace);\n const browserEnabled = cfg?.browser?.enabled !== false;\n const recordGoalEvidence = createGoalEvidenceRecorder({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n });\n const imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const composioTool = createComposioExecuteTool(() => this.deps.getConfig?.());\n const optionalTools = [imageTool, imageGenerateTool, composioTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\n const applyPatchTool = createApplyPatchTool(workspace, { recordGoalEvidence });\n const listDir = createListDirTool(workspace);\n const grep = createGrepTool(workspace);\n const find = createFindTool(workspace);\n\n const core: AgentTool<any, any>[] = [\n createSessionStatusTool(),\n createDreamingTool({\n getWorkspace: () => workspace,\n getDreamingRoot: () => dreamingRoot,\n getConfig: () => this.deps.getConfig?.(),\n getAgentId: () => options?.agentId,\n }),\n createToolManualTool(),\n createClarifyTool({\n resolveAskUser: () => {\n const req = this.deps.gatewayClarify?.requestClarification;\n if (!req) return null;\n const ctx = this.deps.getCurrentContext();\n if (!ctx?.sessionKey) return null;\n if (!CLARIFY_SUPPORTED_CHANNELS.has(ctx.channel)) return null;\n return (r) => req(ctx.sessionKey, r);\n },\n }),\n createTodoTool({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n createUpdatePlanTool(),\n ...(getSkillMgr\n ? [\n createSkillsListTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n }),\n createSkillViewTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n registerSkillEnvPassthrough: this.deps.registerSkillEnvPassthrough,\n }),\n createSkillManageTool({\n getSkillManager: getSkillMgr,\n getWorkspace: () => workspace,\n onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate,\n }),\n ]\n : []),\n readTool,\n writeTool,\n applyPatchTool,\n listDir,\n grep,\n find,\n createExecCommandTool(workspace, {\n getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,\n recordGoalEvidence,\n }),\n createWebSearchTool(() => this.deps.getConfig?.()),\n createWebFetchTool(() => this.deps.getConfig?.()),\n createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),\n // Note: TTS is NOT handled by send_message tool anymore\n // TTS is applied at the ChannelManager dispatch layer\n createMessageTool(bus, () => this.deps.getCurrentContext()),\n ...(mergeTtsConfigFromAppConfig(cfg?.messages?.tts).enabled\n ? [\n createTextToSpeechTool({\n bus,\n getContext: () => this.deps.getCurrentContext(),\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),\n createReadMediaTool(),\n ...(isShareToolAvailable(cfg)\n ? [\n createCreateShareTool({\n workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n ...(getMemMgr\n ? [\n createMemorySearchTool({ workspaceDir: workspace, dreamingRoot, getMemoryManager: () => getMemMgr() }),\n createMemoryGetTool({ workspaceDir: workspace, dreamingRoot, getMemoryManager: () => getMemMgr() }),\n ]\n : []),\n ...(getMemMgr && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(() => getMemMgr()),\n ]\n : []),\n ...(getMemMgr?.().getAdditionalTools() ?? []),\n ...(this.deps.getSessionStore\n ? [\n createSessionSearchTool({\n getSessionStore: this.deps.getSessionStore,\n getConfig: this.deps.getConfig,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ]\n : []),\n ...(this.deps.getAutomationService\n ? [\n createAutomationTool({\n getAutomationService: this.deps.getAutomationService,\n }),\n ]\n : []),\n ...(this.deps.getProjectService || this.deps.getNotesService || this.deps.getWorkItemService\n ? [\n createXopcUseTool({\n getConfig: () => this.deps.getConfig?.(),\n getCurrentAgentId: () => options.agentId,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getNotesService: this.deps.getNotesService,\n getProjectService: this.deps.getProjectService,\n getWorkItemService: this.deps.getWorkItemService,\n }),\n ]\n : []),\n createGoalTool({\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(browserEnabled\n ? [\n createBrowserUseTool({\n getManager: () => this.ensureBrowserManager(),\n getPageForTask: () => this.acquireBrowserPage(),\n getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? 'default',\n getConfig: () => this.deps.getConfig?.(),\n getReadiness: () => this.checkBrowserReadinessCached(),\n getSupervisor: () =>\n this.browserSupervisorForTask(this.deps.getCurrentContext()?.sessionKey ?? 'default'),\n notifyBrowserPageClosed: (taskId) => {\n this.browserTaskSupervisors.delete(taskId);\n },\n }),\n ]\n : []),\n ...(primary\n ? [\n createWorkflowTool({\n catalog: createWorkflowCatalog(),\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getConfig: () => this.deps.getConfig?.(),\n startWorkflowRun: this.deps.getWorkflowRunService\n ? (params) => this.deps.getWorkflowRunService!().startWorkflowRun(params)\n : undefined,\n }),\n ]\n : []),\n ...(false && primary\n ? [\n createDelegateTool({\n workspace,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for delegate_task');\n }\n return m;\n },\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,\n hookRunner: this.deps.hookRunner,\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `child-agent-factory.ts` does not need to import\n // `AgentToolsFactory` directly (which would form a cycle).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n agentId: options?.agentId ?? childOpts.agentId,\n dreamingRoot: options?.dreamingRoot,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createCapabilityTools(\n capabilityNames: readonly string[],\n options?: Pick<CreateCoreToolsOptions, 'disabledTools'>,\n ): AgentTool<any, any>[] {\n const disabled = options?.disabledTools;\n const raw: AgentTool<any, any>[] = [];\n const toolNames = new Set<string>();\n for (const toolName of getAgentCapabilityToolNames(capabilityNames)) {\n if (disabled?.has(toolName) || toolNames.has(toolName)) continue;\n toolNames.add(toolName);\n if (toolName === 'create_desktop_pet') raw.push(createDesktopPetTool() as AgentTool<any, any>);\n if (toolName === 'skill_install') {\n raw.push(createSkillInstallTool({\n installSkillFromSource: this.deps.installSkillFromSource,\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }) as AgentTool<any, any>);\n }\n }\n return wrapToolsWithProtection(raw, this.deps.toolExecutorConfig);\n }\n\n getLazyCapabilityToolNames(): string[] {\n return [\n 'create_desktop_pet',\n ...(this.deps.installSkillFromSource ? ['skill_install'] : []),\n ];\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n\n let bundled: AgentTool<any, any>[];\n if (!this.deps.extensionRegistry || disableExtensions) {\n bundled = coreTools;\n } else {\n const extensionTools = this.deps.extensionRegistry.getAllTools();\n log.info({ count: extensionTools.length }, 'Loaded extension tools');\n bundled = [...coreTools, ...extensionTools];\n }\n\n const wrapped = wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);\n\n const executeEnabled = false && !coreOptions?.disabledTools?.has('execute_code');\n\n if (executeEnabled) {\n const sandboxMap = buildSandboxToolMap(wrapped);\n const executeTool = createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap });\n const wrappedExecute = wrapToolsWithProtection([executeTool as any], this.deps.toolExecutorConfig);\n return [...wrapped, ...wrappedExecute];\n }\n\n return wrapped;\n }\n}\n\nfunction filterToolsByDisabledSet(\n tools: any[],\n disabled: Set<string> | undefined,\n): any[] {\n if (!disabled || disabled.size === 0) {\n return tools;\n }\n return tools.filter((t) => !disabled.has(t.name));\n}\n"],"mappings":"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"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
|
-
declare const GoalToolSchema: import("@sinclair/typebox
|
|
3
|
-
action: import("@sinclair/typebox
|
|
4
|
-
goalId: import("@sinclair/typebox
|
|
5
|
-
title: import("@sinclair/typebox
|
|
6
|
-
description: import("@sinclair/typebox
|
|
7
|
-
status: import("@sinclair/typebox
|
|
8
|
-
priority: import("@sinclair/typebox
|
|
9
|
-
maxTurns: import("@sinclair/typebox
|
|
10
|
-
deadlineAt: import("@sinclair/typebox
|
|
11
|
-
nextAction: import("@sinclair/typebox
|
|
12
|
-
blockedReason: import("@sinclair/typebox
|
|
13
|
-
judgeModelRef: import("@sinclair/typebox
|
|
14
|
-
agentId: import("@sinclair/typebox
|
|
15
|
-
sessionKey: import("@sinclair/typebox
|
|
16
|
-
projectId: import("@sinclair/typebox
|
|
17
|
-
limit: import("@sinclair/typebox
|
|
2
|
+
declare const GoalToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"list">, import("@sinclair/typebox").TLiteral<"create">, import("@sinclair/typebox").TLiteral<"update">]>;
|
|
4
|
+
goalId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
5
|
+
title: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
|
+
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
7
|
+
status: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"active">, import("@sinclair/typebox").TLiteral<"paused">, import("@sinclair/typebox").TLiteral<"blocked">, import("@sinclair/typebox").TLiteral<"needs_input">, import("@sinclair/typebox").TLiteral<"done">, import("@sinclair/typebox").TLiteral<"archived">]>>;
|
|
8
|
+
priority: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"low">, import("@sinclair/typebox").TLiteral<"normal">, import("@sinclair/typebox").TLiteral<"high">]>>;
|
|
9
|
+
maxTurns: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
10
|
+
deadlineAt: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
11
|
+
nextAction: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
12
|
+
blockedReason: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
13
|
+
judgeModelRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
14
|
+
agentId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
15
|
+
sessionKey: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
16
|
+
projectId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
17
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
18
18
|
}>;
|
|
19
19
|
export interface GoalToolOptions {
|
|
20
20
|
getCurrentSessionKey?: () => string | undefined;
|
|
@@ -31,6 +31,7 @@ export { createGoalTool, type GoalToolOptions } from './goal-tool.js';
|
|
|
31
31
|
export { createXopcUseTool, type XopcUseToolDeps, type XopcUseToolInput } from './xopc-use-tool.js';
|
|
32
32
|
export { createSkillsListTool, createSkillViewTool, type SkillsToolsDeps } from './skills-tools.js';
|
|
33
33
|
export { createSkillManageTool, type SkillManageToolDeps } from './skill-manage-tool.js';
|
|
34
|
+
export { createSkillInstallTool, type SkillInstallToolDeps, type SkillInstallToolOptions, type SkillInstallToolResult, } from './skill-install-tool.js';
|
|
34
35
|
export { createToolManualTool } from './tool-manual-tool.js';
|
|
35
36
|
export { createDesktopPetTool, type DesktopPetCreateDetails } from './desktop-pet-tool.js';
|
|
36
37
|
export { createImageTool, resolveImageModelConfigForTool } from './image-tool.js';
|
|
@@ -35,9 +35,10 @@ import { createGoalTool } from "./goal-tool.js";
|
|
|
35
35
|
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
36
36
|
import { createSkillViewTool, createSkillsListTool } from "./skills-tools.js";
|
|
37
37
|
import { createSkillManageTool } from "./skill-manage-tool.js";
|
|
38
|
+
import { createSkillInstallTool } from "./skill-install-tool.js";
|
|
38
39
|
import { createToolManualTool } from "./tool-manual-tool.js";
|
|
39
40
|
import { createDesktopPetTool } from "./desktop-pet-tool.js";
|
|
40
41
|
import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
|
|
41
42
|
import { createImageTool } from "./image-tool.js";
|
|
42
43
|
import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
|
|
43
|
-
export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createClarifyTool, createComposioExecuteTool, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
44
|
+
export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createClarifyTool, createComposioExecuteTool, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
|
+
import { type SkillInstallTarget } from '../skills/install-target.js';
|
|
3
|
+
export interface SkillInstallToolOptions {
|
|
4
|
+
source: string;
|
|
5
|
+
ref?: string;
|
|
6
|
+
path?: string;
|
|
7
|
+
skillId?: string;
|
|
8
|
+
target?: SkillInstallTarget;
|
|
9
|
+
/** Current session whose resolved workspace should receive workspace installs. */
|
|
10
|
+
sessionKey?: string;
|
|
11
|
+
/** Explicit workspace override for workspace installs. */
|
|
12
|
+
workspace?: string;
|
|
13
|
+
force?: boolean;
|
|
14
|
+
strictScan?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface SkillInstallToolResult {
|
|
17
|
+
skillId: string;
|
|
18
|
+
path: string;
|
|
19
|
+
source: string;
|
|
20
|
+
kind: 'git' | 'archive';
|
|
21
|
+
contentHash: string;
|
|
22
|
+
target?: SkillInstallTarget;
|
|
23
|
+
}
|
|
24
|
+
export interface SkillInstallToolDeps {
|
|
25
|
+
installSkillFromSource?: (opts: SkillInstallToolOptions) => Promise<SkillInstallToolResult>;
|
|
26
|
+
getSessionKey?: () => string | undefined;
|
|
27
|
+
}
|
|
28
|
+
export declare function createSkillInstallTool(deps: SkillInstallToolDeps): AgentTool;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { isSkillInstallTarget } from "../skills/install-target.js";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
//#region src/agent/tools/skill-install-tool.ts
|
|
4
|
+
const SkillInstallSchema = Type.Object({
|
|
5
|
+
source: Type.String({ description: "Explicit skill source: Git URL, GitHub repository URL, https .zip/.tar.gz URL, file:// URL, or local archive/path." }),
|
|
6
|
+
ref: Type.Optional(Type.String({ description: "Optional Git branch/tag/ref." })),
|
|
7
|
+
path: Type.Optional(Type.String({ description: "Optional subdirectory inside the source that contains SKILL.md." })),
|
|
8
|
+
skillId: Type.Optional(Type.String({ description: "Optional target managed skill id under the current workspace .xopc/skills." })),
|
|
9
|
+
target: Type.Optional(Type.Union([Type.Literal("workspace"), Type.Literal("global")], { description: "Install target. Defaults to workspace. Use global only when the user explicitly asks for a global/personal install." })),
|
|
10
|
+
force: Type.Optional(Type.Boolean({ description: "Replace an existing managed skill with the same id." })),
|
|
11
|
+
strictScan: Type.Optional(Type.Boolean({ description: "Fail when the current scanner reports critical findings." }))
|
|
12
|
+
});
|
|
13
|
+
function clean(value) {
|
|
14
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
15
|
+
}
|
|
16
|
+
function createSkillInstallTool(deps) {
|
|
17
|
+
return {
|
|
18
|
+
name: "skill_install",
|
|
19
|
+
label: "Install skill",
|
|
20
|
+
description: "Install an xopc skill from an explicit user-provided source. Use only when the user clearly asks to install or update a skill; do not install from a URL the user merely pasted without installation intent.",
|
|
21
|
+
parameters: SkillInstallSchema,
|
|
22
|
+
async execute(_toolCallId, params) {
|
|
23
|
+
if (!deps.installSkillFromSource) return {
|
|
24
|
+
content: [{
|
|
25
|
+
type: "text",
|
|
26
|
+
text: "Skill installation is not available in this runtime context."
|
|
27
|
+
}],
|
|
28
|
+
details: {}
|
|
29
|
+
};
|
|
30
|
+
const source = clean(params.source);
|
|
31
|
+
if (!source) return {
|
|
32
|
+
content: [{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Missing source. Provide a Git URL, archive URL, file URL, or local path."
|
|
35
|
+
}],
|
|
36
|
+
details: { errorCode: "missing_source" }
|
|
37
|
+
};
|
|
38
|
+
try {
|
|
39
|
+
const result = await deps.installSkillFromSource({
|
|
40
|
+
source,
|
|
41
|
+
ref: clean(params.ref),
|
|
42
|
+
path: clean(params.path),
|
|
43
|
+
skillId: clean(params.skillId),
|
|
44
|
+
target: isSkillInstallTarget(params.target) ? params.target : void 0,
|
|
45
|
+
sessionKey: deps.getSessionKey?.(),
|
|
46
|
+
force: params.force === true,
|
|
47
|
+
strictScan: params.strictScan === true
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
content: [{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: [
|
|
53
|
+
`Installed skill "${result.skillId}".`,
|
|
54
|
+
`Target: ${result.target ?? "workspace"}`,
|
|
55
|
+
`Source: ${result.source} (${result.kind})`,
|
|
56
|
+
`Path: ${result.path}`,
|
|
57
|
+
`Tree hash: ${result.contentHash.slice(0, 16)}`
|
|
58
|
+
].join("\n")
|
|
59
|
+
}],
|
|
60
|
+
details: { result }
|
|
61
|
+
};
|
|
62
|
+
} catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
+
return {
|
|
65
|
+
content: [{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `Skill install failed: ${message}`
|
|
68
|
+
}],
|
|
69
|
+
details: {
|
|
70
|
+
errorCode: "install_failed",
|
|
71
|
+
errorMessage: message
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { createSkillInstallTool };
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=skill-install-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-install-tool.js","names":[],"sources":["../../../../src/agent/tools/skill-install-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { isSkillInstallTarget, type SkillInstallTarget } from '../skills/install-target.js';\n\nexport interface SkillInstallToolOptions {\n source: string;\n ref?: string;\n path?: string;\n skillId?: string;\n target?: SkillInstallTarget;\n /** Current session whose resolved workspace should receive workspace installs. */\n sessionKey?: string;\n /** Explicit workspace override for workspace installs. */\n workspace?: string;\n force?: boolean;\n strictScan?: boolean;\n}\n\nexport interface SkillInstallToolResult {\n skillId: string;\n path: string;\n source: string;\n kind: 'git' | 'archive';\n contentHash: string;\n target?: SkillInstallTarget;\n}\n\nexport interface SkillInstallToolDeps {\n installSkillFromSource?: (opts: SkillInstallToolOptions) => Promise<SkillInstallToolResult>;\n getSessionKey?: () => string | undefined;\n}\n\nconst SkillInstallSchema = Type.Object({\n source: Type.String({\n description:\n 'Explicit skill source: Git URL, GitHub repository URL, https .zip/.tar.gz URL, file:// URL, or local archive/path.',\n }),\n ref: Type.Optional(Type.String({ description: 'Optional Git branch/tag/ref.' })),\n path: Type.Optional(\n Type.String({ description: 'Optional subdirectory inside the source that contains SKILL.md.' }),\n ),\n skillId: Type.Optional(\n Type.String({ description: 'Optional target managed skill id under the current workspace .xopc/skills.' }),\n ),\n target: Type.Optional(\n Type.Union([\n Type.Literal('workspace'),\n Type.Literal('global'),\n ], {\n description:\n 'Install target. Defaults to workspace. Use global only when the user explicitly asks for a global/personal install.',\n }),\n ),\n force: Type.Optional(Type.Boolean({ description: 'Replace an existing managed skill with the same id.' })),\n strictScan: Type.Optional(\n Type.Boolean({ description: 'Fail when the current scanner reports critical findings.' }),\n ),\n});\n\nfunction clean(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nexport function createSkillInstallTool(deps: SkillInstallToolDeps): AgentTool {\n return {\n name: 'skill_install',\n label: 'Install skill',\n description:\n 'Install an xopc skill from an explicit user-provided source. Use only when the user clearly asks to install or update a skill; do not install from a URL the user merely pasted without installation intent.',\n parameters: SkillInstallSchema,\n async execute(_toolCallId: string, params: any): Promise<AgentToolResult<{}>> {\n if (!deps.installSkillFromSource) {\n return {\n content: [{ type: 'text', text: 'Skill installation is not available in this runtime context.' }],\n details: {},\n };\n }\n\n const source = clean(params.source);\n if (!source) {\n return {\n content: [{ type: 'text', text: 'Missing source. Provide a Git URL, archive URL, file URL, or local path.' }],\n details: { errorCode: 'missing_source' },\n };\n }\n\n try {\n const result = await deps.installSkillFromSource({\n source,\n ref: clean(params.ref),\n path: clean(params.path),\n skillId: clean(params.skillId),\n target: isSkillInstallTarget(params.target) ? params.target : undefined,\n sessionKey: deps.getSessionKey?.(),\n force: params.force === true,\n strictScan: params.strictScan === true,\n });\n return {\n content: [\n {\n type: 'text',\n text: [\n `Installed skill \"${result.skillId}\".`,\n `Target: ${result.target ?? 'workspace'}`,\n `Source: ${result.source} (${result.kind})`,\n `Path: ${result.path}`,\n `Tree hash: ${result.contentHash.slice(0, 16)}`,\n ].join('\\n'),\n },\n ],\n details: { result },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Skill install failed: ${message}` }],\n details: { errorCode: 'install_failed', errorMessage: message },\n };\n }\n },\n } as any;\n}\n"],"mappings":";;;AAgCA,MAAM,qBAAqB,KAAK,OAAO;CACrC,QAAQ,KAAK,OAAO,EAClB,aACE,sHACH,CAAC;CACF,KAAK,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,gCAAgC,CAAC,CAAC;CAChF,MAAM,KAAK,SACT,KAAK,OAAO,EAAE,aAAa,mEAAmE,CAAC,CAChG;CACD,SAAS,KAAK,SACZ,KAAK,OAAO,EAAE,aAAa,8EAA8E,CAAC,CAC3G;CACD,QAAQ,KAAK,SACX,KAAK,MAAM,CACT,KAAK,QAAQ,YAAY,EACzB,KAAK,QAAQ,SAAS,CACvB,EAAE,EACD,aACE,uHACH,CAAC,CACH;CACD,OAAO,KAAK,SAAS,KAAK,QAAQ,EAAE,aAAa,uDAAuD,CAAC,CAAC;CAC1G,YAAY,KAAK,SACf,KAAK,QAAQ,EAAE,aAAa,4DAA4D,CAAC,CAC1F;CACF,CAAC;AAEF,SAAS,MAAM,OAAoC;AACjD,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;AAGpE,SAAgB,uBAAuB,MAAuC;AAC5E,QAAO;EACL,MAAM;EACN,OAAO;EACP,aACE;EACF,YAAY;EACZ,MAAM,QAAQ,aAAqB,QAA2C;AAC5E,OAAI,CAAC,KAAK,uBACR,QAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAgE,CAAC;IACjG,SAAS,EAAE;IACZ;GAGH,MAAM,SAAS,MAAM,OAAO,OAAO;AACnC,OAAI,CAAC,OACH,QAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAA4E,CAAC;IAC7G,SAAS,EAAE,WAAW,kBAAkB;IACzC;AAGH,OAAI;IACF,MAAM,SAAS,MAAM,KAAK,uBAAuB;KAC/C;KACA,KAAK,MAAM,OAAO,IAAI;KACtB,MAAM,MAAM,OAAO,KAAK;KACxB,SAAS,MAAM,OAAO,QAAQ;KAC9B,QAAQ,qBAAqB,OAAO,OAAO,GAAG,OAAO,SAAS,KAAA;KAC9D,YAAY,KAAK,iBAAiB;KAClC,OAAO,OAAO,UAAU;KACxB,YAAY,OAAO,eAAe;KACnC,CAAC;AACF,WAAO;KACL,SAAS,CACP;MACE,MAAM;MACN,MAAM;OACJ,oBAAoB,OAAO,QAAQ;OACnC,WAAW,OAAO,UAAU;OAC5B,WAAW,OAAO,OAAO,IAAI,OAAO,KAAK;OACzC,SAAS,OAAO;OAChB,cAAc,OAAO,YAAY,MAAM,GAAG,GAAG;OAC9C,CAAC,KAAK,KAAK;MACb,CACF;KACD,SAAS,EAAE,QAAQ;KACpB;YACM,KAAK;IACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAChE,WAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,yBAAyB;MAAW,CAAC;KACrE,SAAS;MAAE,WAAW;MAAkB,cAAc;MAAS;KAChE;;;EAGN"}
|
|
@@ -20,7 +20,7 @@ const SkillManageSchema = Type.Object({
|
|
|
20
20
|
name: Type.Optional(Type.String({ description: "Skill name (directory id / frontmatter name)" })),
|
|
21
21
|
content: Type.Optional(Type.String({ description: "Full SKILL.md for create or edit" })),
|
|
22
22
|
category: Type.Optional(Type.String({ description: "Optional single-segment category folder under skills root" })),
|
|
23
|
-
write_target: Type.Optional(Type.Union([Type.Literal("global"), Type.Literal("workspace")], { description: "Where to create the skill
|
|
23
|
+
write_target: Type.Optional(Type.Union([Type.Literal("global"), Type.Literal("workspace")], { description: "Where to create the skill. Defaults to workspace. Use global only when the user explicitly asks for a global/personal skill. Respects skills.agentWritePolicy." })),
|
|
24
24
|
old_string: Type.Optional(Type.String()),
|
|
25
25
|
new_string: Type.Optional(Type.String()),
|
|
26
26
|
replace_all: Type.Optional(Type.Boolean({ default: false })),
|
|
@@ -73,11 +73,7 @@ function createSkillManageTool(deps) {
|
|
|
73
73
|
success: false,
|
|
74
74
|
error: md.error
|
|
75
75
|
});
|
|
76
|
-
|
|
77
|
-
success: false,
|
|
78
|
-
error: `A skill named "${name}" already exists. Use edit or choose another name.`
|
|
79
|
-
});
|
|
80
|
-
const target = params.write_target ?? "global";
|
|
76
|
+
const target = params.write_target ?? "workspace";
|
|
81
77
|
const dirRes = resolveCreateSkillDir(name, params.category?.trim(), target, workspace, policy);
|
|
82
78
|
if (dirRes.ok === false) return jsonResult({
|
|
83
79
|
success: false,
|
|
@@ -112,6 +108,7 @@ function createSkillManageTool(deps) {
|
|
|
112
108
|
return jsonResult({
|
|
113
109
|
success: true,
|
|
114
110
|
message: `Skill "${name}" created.`,
|
|
111
|
+
target,
|
|
115
112
|
path: dirRes.dir
|
|
116
113
|
});
|
|
117
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-manage-tool.js","names":[],"sources":["../../../../src/agent/tools/skill-manage-tool.ts"],"sourcesContent":["import { Type, type Static } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { existsSync, rmSync } from 'fs';\nimport { join } from 'path';\nimport { readFile, rm } from 'fs/promises';\n\nimport { resolveStateDir } from '../../config/paths.js';\nimport { createSkillConfigManager } from '../skills/config.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport {\n applyPatchToContent,\n atomicWriteUtf8,\n effectiveAgentWritePolicy,\n ensureCategorySegment,\n maxSkillMdChars,\n maxSupportFileBytes,\n mutatableSkillOrNull,\n isPathInsideDir,\n resolveCreateSkillDir,\n scanSkillDirOrError,\n validateSkillMdContent,\n validateSkillNameSegment,\n validateSupportingRelativePath,\n} from '../skills/skill-manage-ops.js';\n\nconst SkillManageSchema = Type.Object({\n action: Type.Union([\n Type.Literal('create'),\n Type.Literal('edit'),\n Type.Literal('patch'),\n Type.Literal('delete'),\n Type.Literal('write_file'),\n Type.Literal('remove_file'),\n ]),\n name: Type.Optional(Type.String({ description: 'Skill name (directory id / frontmatter name)' })),\n content: Type.Optional(Type.String({ description: 'Full SKILL.md for create or edit' })),\n category: Type.Optional(Type.String({ description: 'Optional single-segment category folder under skills root' })),\n write_target: Type.Optional(\n Type.Union([Type.Literal('global'), Type.Literal('workspace')], {\n description: 'Where to create the skill (default global). Respects skills.agentWritePolicy.',\n }),\n ),\n old_string: Type.Optional(Type.String()),\n new_string: Type.Optional(Type.String()),\n replace_all: Type.Optional(Type.Boolean({ default: false })),\n file_path: Type.Optional(\n Type.String({\n description: 'Relative path under skill dir (references/, templates/, scripts/, assets/)',\n }),\n ),\n file_content: Type.Optional(Type.String({ description: 'For write_file' })),\n});\n\nexport interface SkillManageToolDeps {\n getSkillManager: () => SkillManager | undefined;\n getWorkspace: () => string;\n onSkillsFilesystemMutate?: () => void;\n}\n\nfunction jsonResult(obj: Record<string, unknown>): AgentToolResult<{}> {\n return { content: [{ type: 'text', text: JSON.stringify(obj, null, 2) }], details: {} };\n}\n\nexport function createSkillManageTool(deps: SkillManageToolDeps): AgentTool {\n return {\n name: 'skill_manage',\n label: '🛠️ Skill',\n description:\n 'Create, edit, patch, or delete user skills under ~/.xopc/skills and/or workspace .xopc/skills/ (see skills.agentWritePolicy). ' +\n 'Also write_file / remove_file under references/, templates/, scripts/, assets/. ' +\n 'Bundled and extra-dir skills cannot be modified. Runs a security scan after writes.',\n parameters: SkillManageSchema,\n async execute(\n _toolCallId: string,\n params: Static<typeof SkillManageSchema>,\n ): Promise<AgentToolResult<{}>> {\n const mgr = deps.getSkillManager();\n if (!mgr) {\n return jsonResult({ success: false, error: 'Skill manager not available in this context.' });\n }\n\n const workspace = deps.getWorkspace();\n const skillsCfg = createSkillConfigManager(resolveStateDir()).load();\n const policy = effectiveAgentWritePolicy(skillsCfg);\n const mdMax = maxSkillMdChars(skillsCfg);\n const supMax = maxSupportFileBytes(skillsCfg);\n\n const notify = () => deps.onSkillsFilesystemMutate?.();\n\n try {\n switch (params.action) {\n case 'create': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const catErr = ensureCategorySegment(params.category);\n if (catErr) return jsonResult({ success: false, error: catErr });\n\n const md = validateSkillMdContent(params.content ?? '', name, mdMax);\n if (md.ok === false) return jsonResult({ success: false, error: md.error });\n\n if (mgr.hasSkill(name)) {\n return jsonResult({\n success: false,\n error: `A skill named \"${name}\" already exists. Use edit or choose another name.`,\n });\n }\n\n const target = params.write_target ?? 'global';\n const dirRes = resolveCreateSkillDir(name, params.category?.trim(), target, workspace, policy);\n if (dirRes.ok === false) return jsonResult({ success: false, error: dirRes.error });\n\n if (existsSync(dirRes.dir)) {\n return jsonResult({ success: false, error: `Directory already exists: ${dirRes.dir}` });\n }\n\n const skillMdPath = join(dirRes.dir, 'SKILL.md');\n try {\n await atomicWriteUtf8(skillMdPath, params.content!);\n const scanErr = await scanSkillDirOrError(dirRes.dir, name);\n if (scanErr) {\n rmSync(dirRes.dir, { recursive: true, force: true });\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n rmSync(dirRes.dir, { recursive: true, force: true });\n throw e;\n }\n\n notify();\n return jsonResult({\n success: true,\n message: `Skill \"${name}\" created.`,\n path: dirRes.dir,\n });\n }\n\n case 'edit': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable (bundled/extra or policy).`,\n });\n }\n\n const md = validateSkillMdContent(params.content ?? '', name, mdMax);\n if (md.ok === false) return jsonResult({ success: false, error: md.error });\n\n const skillMdPath = join(sk.baseDir, 'SKILL.md');\n let previous: string;\n try {\n previous = await readFile(skillMdPath, 'utf-8');\n } catch {\n return jsonResult({ success: false, error: 'SKILL.md could not be read.' });\n }\n\n try {\n await atomicWriteUtf8(skillMdPath, params.content!);\n const scanErr = await scanSkillDirOrError(sk.baseDir, name);\n if (scanErr) {\n await atomicWriteUtf8(skillMdPath, previous);\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n await atomicWriteUtf8(skillMdPath, previous).catch(() => {});\n throw e;\n }\n\n notify();\n return jsonResult({ success: true, message: `Skill \"${name}\" updated.`, path: sk.baseDir });\n }\n\n case 'patch': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n let relPath: string | undefined;\n if (params.file_path?.trim()) {\n const pErr = validateSupportingRelativePath(params.file_path.trim());\n if (pErr) return jsonResult({ success: false, error: pErr });\n relPath = params.file_path.trim().replace(/\\\\/g, '/');\n }\n\n const targetPath = relPath ? join(sk.baseDir, relPath) : join(sk.baseDir, 'SKILL.md');\n if (!isPathInsideDir(sk.baseDir, targetPath)) {\n return jsonResult({ success: false, error: 'Resolved path escapes skill directory.' });\n }\n\n let previous: string;\n try {\n previous = await readFile(targetPath, 'utf-8');\n } catch {\n return jsonResult({ success: false, error: `File not found: ${relPath ?? 'SKILL.md'}` });\n }\n\n const patched = applyPatchToContent(\n previous,\n params.old_string ?? '',\n params.new_string ?? '',\n params.replace_all === true,\n );\n if (patched.ok === false) return jsonResult({ success: false, error: patched.error });\n\n if (!relPath) {\n const md = validateSkillMdContent(patched.next, name, mdMax);\n if (md.ok === false) return jsonResult({ success: false, error: `Patch rejected: ${md.error}` });\n } else if (Buffer.byteLength(patched.next, 'utf-8') > supMax) {\n return jsonResult({ success: false, error: `File exceeds size limit (${supMax} bytes).` });\n }\n\n try {\n await atomicWriteUtf8(targetPath, patched.next);\n const scanErr = await scanSkillDirOrError(sk.baseDir, name);\n if (scanErr) {\n await atomicWriteUtf8(targetPath, previous);\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n await atomicWriteUtf8(targetPath, previous).catch(() => {});\n throw e;\n }\n\n notify();\n return jsonResult({\n success: true,\n message: `Patched ${relPath ?? 'SKILL.md'} (${patched.replacements} replacement(s)).`,\n });\n }\n\n case 'delete': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n rmSync(sk.baseDir, { recursive: true, force: true });\n notify();\n return jsonResult({ success: true, message: `Skill \"${name}\" removed.`, path: sk.baseDir });\n }\n\n case 'write_file': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n const pErr = validateSupportingRelativePath(params.file_path ?? '');\n if (pErr) return jsonResult({ success: false, error: pErr });\n const rel = params.file_path!.trim().replace(/\\\\/g, '/');\n const targetPath = join(sk.baseDir, rel);\n if (!isPathInsideDir(sk.baseDir, targetPath)) {\n return jsonResult({ success: false, error: 'Resolved path escapes skill directory.' });\n }\n\n const body = params.file_content ?? '';\n if (Buffer.byteLength(body, 'utf-8') > supMax) {\n return jsonResult({ success: false, error: `File exceeds size limit (${supMax} bytes).` });\n }\n\n const existed = existsSync(targetPath);\n let previous: string | null = null;\n if (existed) {\n try {\n previous = await readFile(targetPath, 'utf-8');\n } catch {\n previous = null;\n }\n }\n\n try {\n await atomicWriteUtf8(targetPath, body);\n const scanErr = await scanSkillDirOrError(sk.baseDir, name);\n if (scanErr) {\n if (previous !== null) await atomicWriteUtf8(targetPath, previous);\n else await rm(targetPath, { force: true });\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n if (previous !== null) await atomicWriteUtf8(targetPath, previous).catch(() => {});\n else await rm(targetPath, { force: true }).catch(() => {});\n throw e;\n }\n\n notify();\n return jsonResult({\n success: true,\n message: `Wrote ${rel}.`,\n });\n }\n\n case 'remove_file': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n const pErr = validateSupportingRelativePath(params.file_path ?? '');\n if (pErr) return jsonResult({ success: false, error: pErr });\n const rel = params.file_path!.trim().replace(/\\\\/g, '/');\n const targetPath = join(sk.baseDir, rel);\n if (!isPathInsideDir(sk.baseDir, targetPath)) {\n return jsonResult({ success: false, error: 'Resolved path escapes skill directory.' });\n }\n\n if (!existsSync(targetPath)) {\n return jsonResult({ success: false, error: `File not found: ${rel}` });\n }\n\n await rm(targetPath, { force: true });\n await scanSkillDirOrError(sk.baseDir, name);\n notify();\n return jsonResult({ success: true, message: `Removed ${rel}.` });\n }\n\n default:\n return jsonResult({ success: false, error: 'Unknown action.' });\n }\n } catch (e) {\n return jsonResult({\n success: false,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n },\n } as any;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skill-manage-tool.js","names":[],"sources":["../../../../src/agent/tools/skill-manage-tool.ts"],"sourcesContent":["import { Type, type Static } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { existsSync, rmSync } from 'fs';\nimport { join } from 'path';\nimport { readFile, rm } from 'fs/promises';\n\nimport { resolveStateDir } from '../../config/paths.js';\nimport { createSkillConfigManager } from '../skills/config.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport {\n applyPatchToContent,\n atomicWriteUtf8,\n effectiveAgentWritePolicy,\n ensureCategorySegment,\n maxSkillMdChars,\n maxSupportFileBytes,\n mutatableSkillOrNull,\n isPathInsideDir,\n resolveCreateSkillDir,\n scanSkillDirOrError,\n validateSkillMdContent,\n validateSkillNameSegment,\n validateSupportingRelativePath,\n} from '../skills/skill-manage-ops.js';\n\nconst SkillManageSchema = Type.Object({\n action: Type.Union([\n Type.Literal('create'),\n Type.Literal('edit'),\n Type.Literal('patch'),\n Type.Literal('delete'),\n Type.Literal('write_file'),\n Type.Literal('remove_file'),\n ]),\n name: Type.Optional(Type.String({ description: 'Skill name (directory id / frontmatter name)' })),\n content: Type.Optional(Type.String({ description: 'Full SKILL.md for create or edit' })),\n category: Type.Optional(Type.String({ description: 'Optional single-segment category folder under skills root' })),\n write_target: Type.Optional(\n Type.Union([Type.Literal('global'), Type.Literal('workspace')], {\n description:\n 'Where to create the skill. Defaults to workspace. Use global only when the user explicitly asks for a global/personal skill. Respects skills.agentWritePolicy.',\n }),\n ),\n old_string: Type.Optional(Type.String()),\n new_string: Type.Optional(Type.String()),\n replace_all: Type.Optional(Type.Boolean({ default: false })),\n file_path: Type.Optional(\n Type.String({\n description: 'Relative path under skill dir (references/, templates/, scripts/, assets/)',\n }),\n ),\n file_content: Type.Optional(Type.String({ description: 'For write_file' })),\n});\n\nexport interface SkillManageToolDeps {\n getSkillManager: () => SkillManager | undefined;\n getWorkspace: () => string;\n onSkillsFilesystemMutate?: () => void;\n}\n\nfunction jsonResult(obj: Record<string, unknown>): AgentToolResult<{}> {\n return { content: [{ type: 'text', text: JSON.stringify(obj, null, 2) }], details: {} };\n}\n\nexport function createSkillManageTool(deps: SkillManageToolDeps): AgentTool {\n return {\n name: 'skill_manage',\n label: '🛠️ Skill',\n description:\n 'Create, edit, patch, or delete user skills under ~/.xopc/skills and/or workspace .xopc/skills/ (see skills.agentWritePolicy). ' +\n 'Also write_file / remove_file under references/, templates/, scripts/, assets/. ' +\n 'Bundled and extra-dir skills cannot be modified. Runs a security scan after writes.',\n parameters: SkillManageSchema,\n async execute(\n _toolCallId: string,\n params: Static<typeof SkillManageSchema>,\n ): Promise<AgentToolResult<{}>> {\n const mgr = deps.getSkillManager();\n if (!mgr) {\n return jsonResult({ success: false, error: 'Skill manager not available in this context.' });\n }\n\n const workspace = deps.getWorkspace();\n const skillsCfg = createSkillConfigManager(resolveStateDir()).load();\n const policy = effectiveAgentWritePolicy(skillsCfg);\n const mdMax = maxSkillMdChars(skillsCfg);\n const supMax = maxSupportFileBytes(skillsCfg);\n\n const notify = () => deps.onSkillsFilesystemMutate?.();\n\n try {\n switch (params.action) {\n case 'create': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const catErr = ensureCategorySegment(params.category);\n if (catErr) return jsonResult({ success: false, error: catErr });\n\n const md = validateSkillMdContent(params.content ?? '', name, mdMax);\n if (md.ok === false) return jsonResult({ success: false, error: md.error });\n\n const target = params.write_target ?? 'workspace';\n const dirRes = resolveCreateSkillDir(name, params.category?.trim(), target, workspace, policy);\n if (dirRes.ok === false) return jsonResult({ success: false, error: dirRes.error });\n\n if (existsSync(dirRes.dir)) {\n return jsonResult({ success: false, error: `Directory already exists: ${dirRes.dir}` });\n }\n\n const skillMdPath = join(dirRes.dir, 'SKILL.md');\n try {\n await atomicWriteUtf8(skillMdPath, params.content!);\n const scanErr = await scanSkillDirOrError(dirRes.dir, name);\n if (scanErr) {\n rmSync(dirRes.dir, { recursive: true, force: true });\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n rmSync(dirRes.dir, { recursive: true, force: true });\n throw e;\n }\n\n notify();\n return jsonResult({\n success: true,\n message: `Skill \"${name}\" created.`,\n target,\n path: dirRes.dir,\n });\n }\n\n case 'edit': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable (bundled/extra or policy).`,\n });\n }\n\n const md = validateSkillMdContent(params.content ?? '', name, mdMax);\n if (md.ok === false) return jsonResult({ success: false, error: md.error });\n\n const skillMdPath = join(sk.baseDir, 'SKILL.md');\n let previous: string;\n try {\n previous = await readFile(skillMdPath, 'utf-8');\n } catch {\n return jsonResult({ success: false, error: 'SKILL.md could not be read.' });\n }\n\n try {\n await atomicWriteUtf8(skillMdPath, params.content!);\n const scanErr = await scanSkillDirOrError(sk.baseDir, name);\n if (scanErr) {\n await atomicWriteUtf8(skillMdPath, previous);\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n await atomicWriteUtf8(skillMdPath, previous).catch(() => {});\n throw e;\n }\n\n notify();\n return jsonResult({ success: true, message: `Skill \"${name}\" updated.`, path: sk.baseDir });\n }\n\n case 'patch': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n let relPath: string | undefined;\n if (params.file_path?.trim()) {\n const pErr = validateSupportingRelativePath(params.file_path.trim());\n if (pErr) return jsonResult({ success: false, error: pErr });\n relPath = params.file_path.trim().replace(/\\\\/g, '/');\n }\n\n const targetPath = relPath ? join(sk.baseDir, relPath) : join(sk.baseDir, 'SKILL.md');\n if (!isPathInsideDir(sk.baseDir, targetPath)) {\n return jsonResult({ success: false, error: 'Resolved path escapes skill directory.' });\n }\n\n let previous: string;\n try {\n previous = await readFile(targetPath, 'utf-8');\n } catch {\n return jsonResult({ success: false, error: `File not found: ${relPath ?? 'SKILL.md'}` });\n }\n\n const patched = applyPatchToContent(\n previous,\n params.old_string ?? '',\n params.new_string ?? '',\n params.replace_all === true,\n );\n if (patched.ok === false) return jsonResult({ success: false, error: patched.error });\n\n if (!relPath) {\n const md = validateSkillMdContent(patched.next, name, mdMax);\n if (md.ok === false) return jsonResult({ success: false, error: `Patch rejected: ${md.error}` });\n } else if (Buffer.byteLength(patched.next, 'utf-8') > supMax) {\n return jsonResult({ success: false, error: `File exceeds size limit (${supMax} bytes).` });\n }\n\n try {\n await atomicWriteUtf8(targetPath, patched.next);\n const scanErr = await scanSkillDirOrError(sk.baseDir, name);\n if (scanErr) {\n await atomicWriteUtf8(targetPath, previous);\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n await atomicWriteUtf8(targetPath, previous).catch(() => {});\n throw e;\n }\n\n notify();\n return jsonResult({\n success: true,\n message: `Patched ${relPath ?? 'SKILL.md'} (${patched.replacements} replacement(s)).`,\n });\n }\n\n case 'delete': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n rmSync(sk.baseDir, { recursive: true, force: true });\n notify();\n return jsonResult({ success: true, message: `Skill \"${name}\" removed.`, path: sk.baseDir });\n }\n\n case 'write_file': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n const pErr = validateSupportingRelativePath(params.file_path ?? '');\n if (pErr) return jsonResult({ success: false, error: pErr });\n const rel = params.file_path!.trim().replace(/\\\\/g, '/');\n const targetPath = join(sk.baseDir, rel);\n if (!isPathInsideDir(sk.baseDir, targetPath)) {\n return jsonResult({ success: false, error: 'Resolved path escapes skill directory.' });\n }\n\n const body = params.file_content ?? '';\n if (Buffer.byteLength(body, 'utf-8') > supMax) {\n return jsonResult({ success: false, error: `File exceeds size limit (${supMax} bytes).` });\n }\n\n const existed = existsSync(targetPath);\n let previous: string | null = null;\n if (existed) {\n try {\n previous = await readFile(targetPath, 'utf-8');\n } catch {\n previous = null;\n }\n }\n\n try {\n await atomicWriteUtf8(targetPath, body);\n const scanErr = await scanSkillDirOrError(sk.baseDir, name);\n if (scanErr) {\n if (previous !== null) await atomicWriteUtf8(targetPath, previous);\n else await rm(targetPath, { force: true });\n return jsonResult({ success: false, error: scanErr });\n }\n } catch (e) {\n if (previous !== null) await atomicWriteUtf8(targetPath, previous).catch(() => {});\n else await rm(targetPath, { force: true }).catch(() => {});\n throw e;\n }\n\n notify();\n return jsonResult({\n success: true,\n message: `Wrote ${rel}.`,\n });\n }\n\n case 'remove_file': {\n const nameErr = validateSkillNameSegment(params.name ?? '', 'name');\n if (nameErr) return jsonResult({ success: false, error: nameErr });\n const name = params.name!.trim();\n\n const sk = mutatableSkillOrNull(mgr.findSkill(name), workspace, policy);\n if (!sk) {\n return jsonResult({\n success: false,\n error: `Skill \"${name}\" not found or not writable.`,\n });\n }\n\n const pErr = validateSupportingRelativePath(params.file_path ?? '');\n if (pErr) return jsonResult({ success: false, error: pErr });\n const rel = params.file_path!.trim().replace(/\\\\/g, '/');\n const targetPath = join(sk.baseDir, rel);\n if (!isPathInsideDir(sk.baseDir, targetPath)) {\n return jsonResult({ success: false, error: 'Resolved path escapes skill directory.' });\n }\n\n if (!existsSync(targetPath)) {\n return jsonResult({ success: false, error: `File not found: ${rel}` });\n }\n\n await rm(targetPath, { force: true });\n await scanSkillDirOrError(sk.baseDir, name);\n notify();\n return jsonResult({ success: true, message: `Removed ${rel}.` });\n }\n\n default:\n return jsonResult({ success: false, error: 'Unknown action.' });\n }\n } catch (e) {\n return jsonResult({\n success: false,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n },\n } as any;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
|
-
declare const ToolManualSchema: import("@sinclair/typebox
|
|
3
|
-
tool: import("@sinclair/typebox
|
|
2
|
+
declare const ToolManualSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
tool: import("@sinclair/typebox").TString;
|
|
4
4
|
}>;
|
|
5
5
|
export declare function createToolManualTool(): AgentTool<typeof ToolManualSchema, {}>;
|
|
6
6
|
export {};
|
|
@@ -3,11 +3,11 @@ import type { Config } from '../../config/schema.js';
|
|
|
3
3
|
import type { NotesService } from '../../notes/index.js';
|
|
4
4
|
import { type ProjectService } from '../../projects/index.js';
|
|
5
5
|
import type { WorkItemService } from '../../work-items/index.js';
|
|
6
|
-
declare const XopcUseToolSchema: import("@sinclair/typebox
|
|
7
|
-
mode: import("@sinclair/typebox
|
|
8
|
-
command: import("@sinclair/typebox
|
|
9
|
-
args: import("@sinclair/typebox
|
|
10
|
-
dryRun: import("@sinclair/typebox
|
|
6
|
+
declare const XopcUseToolSchema: import("@sinclair/typebox").TObject<{
|
|
7
|
+
mode: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"project">, import("@sinclair/typebox").TLiteral<"note">, import("@sinclair/typebox").TLiteral<"work_item">]>;
|
|
8
|
+
command: import("@sinclair/typebox").TString;
|
|
9
|
+
args: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
|
|
10
|
+
dryRun: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
11
11
|
}>;
|
|
12
12
|
export type XopcUseMode = 'project' | 'note' | 'work_item';
|
|
13
13
|
export interface XopcUseToolInput {
|
|
@@ -151,6 +151,7 @@ export interface AutomationDeps {
|
|
|
151
151
|
workflowRunService?: {
|
|
152
152
|
startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult>;
|
|
153
153
|
};
|
|
154
|
+
onRunCompleted?: (run: AutomationRun) => void;
|
|
154
155
|
}
|
|
155
156
|
export interface AutomationActionOutcome {
|
|
156
157
|
status: 'succeeded' | 'failed' | 'timeout' | 'cancelled';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
4
|
-
import { buildAutomationDraftPrompt, buildAutomationDraftRepairPrompt, buildAutomationRunRepairPrompt, buildAutomationRunRepairRetryPrompt } from "./automation-draft-prompt.js";
|
|
5
4
|
import { resolveDraftModelRef } from "../../workflows/draft/workflow-draft-service.js";
|
|
5
|
+
import { buildAutomationDraftPrompt, buildAutomationDraftRepairPrompt, buildAutomationRunRepairPrompt, buildAutomationRunRepairRetryPrompt } from "./automation-draft-prompt.js";
|
|
6
6
|
import { buildAutomationDraftResponse, parseGeneratedAutomationDraft, parseGeneratedAutomationRepairDraft } from "./automation-draft-validator.js";
|
|
7
7
|
import { complete } from "@earendil-works/pi-ai/compat";
|
|
8
8
|
//#region src/automations/draft/automation-draft-service.ts
|
|
@@ -329,6 +329,15 @@ var AutomationService = class {
|
|
|
329
329
|
});
|
|
330
330
|
this.activeRuns.delete(initialRun.id);
|
|
331
331
|
this.finishAutomationRun(automation.id, status, error, endedAtMs);
|
|
332
|
+
try {
|
|
333
|
+
this.deps.onRunCompleted?.(run);
|
|
334
|
+
} catch (err) {
|
|
335
|
+
log.warn({
|
|
336
|
+
err,
|
|
337
|
+
automationId: automation.id,
|
|
338
|
+
runId: run.id
|
|
339
|
+
}, "Automation completion hook failed");
|
|
340
|
+
}
|
|
332
341
|
}
|
|
333
342
|
}
|
|
334
343
|
appendRunEvent(run, type, message, data) {
|