@xopcai/xopc 0.0.116 → 0.0.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -28
- package/README.zh-CN.md +63 -45
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/demo-memory/src/index.d.ts +6 -0
- package/dist/extensions/demo-memory/src/index.js +132 -0
- package/dist/extensions/demo-memory/src/index.js.map +1 -0
- package/dist/extensions/demo-memory/xopc.extension.json +15 -0
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +3 -3
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/command-handler.js +1 -2
- package/dist/extensions/telegram/src/command-handler.js.map +1 -1
- package/dist/extensions/telegram/src/config-schema.d.ts +8 -8
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/update-offset-store.js +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CWM1UU5P.js → agent-avatar-dicebear-dzUrQoeZ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-yXSXY_bu.js → app-management-settings-panel-bxYJVJpx.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DjY1P_ug.js → appearance-settings-BCIykXlI.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page--wMEL00f.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CytE5j-e.js → archive-plugin-Cki4SfU2.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BvvrN6rF.js → attachment-load-D-KnS2Do.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-IBWSitnj.js → binary-plugins-D2sgvJja.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C-wDpsf-.js → block-editor-DIq-4Gvb.js} +27 -27
- package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +2 -0
- package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +3 -0
- package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BAIyjDlq.js → extension-debug-page-DYu1KaFQ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DEhv2GpC.js → extension-page-B3W6QwlZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DOuAxTDW.js → extension-settings-page-D7VQ-cxE.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-CTsREQIe.js → fetch-B7xDPu-R.js} +1 -1
- package/dist/gateway/static/root/assets/{format-interval-label-D35Bfhtx.js → format-interval-label-BzxafKxR.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-config-api-BTBLSeUu.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-C1KAHrd2.js → gateway-startup-retry-CYj9FWCp.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +1 -0
- package/dist/gateway/static/root/assets/{goals-config-api-KnLGpu6h.js → goals-config-api-CQQgzPr3.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BHitvJAv.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DtPtqZi8.js → goals-settings-CYVY4NGp.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-uKw1f0IG.js → heartbeat-config-api-DriO_CN9.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +1 -0
- package/dist/gateway/static/root/assets/index-C17Tsd_b.css +1 -0
- package/dist/gateway/static/root/assets/index-Cc41r16l.js +191 -0
- package/dist/gateway/static/root/assets/{interval-presets-Dq0FXJ65.js → interval-presets-DFPCKW_W.js} +1 -1
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C9_t4m7t.js → keyboard-shortcuts-settings-CcVcqstx.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-SNkWzidV.js → logs-page-C2Uqvae9.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-Ca87W8-h.js → markdown-split-BwOFrJ2E.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BAcUjPRJ.js → media-plugins-Cnz6Q5G6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-hnSX5SSn.js → note-image-lightbox-B-Svpmza.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CNgM20H5.js → preview-open-alternatives-Bss4TiwP.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-CcdjGcfT.js → save-bar-controls-BRNjdgKq.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CYr39z76.js → schedule-field-CUCKODde.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BRAJgZQ2.js → schema-form-Dub9sy8r.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BhzjeGWi.js → settings-collapsible-section-BeFLavGi.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Cz3Pcr9b.js → settings-form-section-dmyaPOTG.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-DL4y9K5e.js → share-preview-page-C8glrdqe.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-FD2jxRZ3.js → system-settings-panel-DI-LN_8G.js} +1 -1
- package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +1 -0
- package/dist/gateway/static/root/assets/{use-channel-catalog-BInPrfR5.js → use-channel-catalog-DqlWTsDb.js} +1 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +1 -0
- package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-C73IVZeC.js +1 -0
- package/dist/gateway/static/root/assets/{voice-player-store-1U3vFppm.js → voice-player-store-C_ArLJPM.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +18 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +1 -1
- package/dist/src/agent/agent-manager.js +14 -14
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.js +5 -9
- package/dist/src/agent/agent-scope.js.map +1 -1
- package/dist/src/agent/background-review/coordinator.js +0 -1
- package/dist/src/agent/background-review/coordinator.js.map +1 -1
- package/dist/src/agent/background-review/prompts.d.ts +2 -2
- package/dist/src/agent/background-review/prompts.js +2 -2
- package/dist/src/agent/background-review/prompts.js.map +1 -1
- package/dist/src/agent/background-review/run-background-review.d.ts +0 -2
- package/dist/src/agent/background-review/run-background-review.js +2 -4
- package/dist/src/agent/background-review/run-background-review.js.map +1 -1
- package/dist/src/agent/background-review/settings.d.ts +1 -1
- package/dist/src/agent/background-review/settings.js +8 -8
- package/dist/src/agent/background-review/settings.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +1 -0
- package/dist/src/agent/bootstrap/bootstrap-cache.js +4 -3
- package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-context.d.ts +2 -2
- package/dist/src/agent/bootstrap/bootstrap-context.js +4 -4
- package/dist/src/agent/bootstrap/bootstrap-context.js.map +1 -1
- package/dist/src/agent/bootstrap/bootstrap-files.d.ts +4 -0
- package/dist/src/agent/bootstrap/bootstrap-files.js +4 -3
- package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +4 -2
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +2 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +18 -17
- package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/project-agents-context.js +1 -1
- package/dist/src/agent/bootstrap/types.d.ts +1 -1
- package/dist/src/agent/context/workspace-seed.js +3 -3
- package/dist/src/agent/context/workspace-state.js +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
- package/dist/src/agent/context/workspace.d.ts +4 -2
- package/dist/src/agent/context/workspace.js +6 -5
- package/dist/src/agent/context/workspace.js.map +1 -1
- package/dist/src/agent/embedded/run-for-session.js +4 -1
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/fallback/candidates.js +11 -9
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.js +2 -2
- package/dist/src/agent/goals/post-turn.js +3 -3
- package/dist/src/agent/image/generation/runtime-types.d.ts +2 -0
- package/dist/src/agent/image/generation/runtime.js +1 -1
- package/dist/src/agent/image/generation/runtime.js.map +1 -1
- package/dist/src/agent/image/image-helpers.d.ts +1 -1
- package/dist/src/agent/image/image-helpers.js +4 -17
- package/dist/src/agent/image/image-helpers.js.map +1 -1
- package/dist/src/agent/image/image-model-fallback.js +1 -1
- package/dist/src/agent/image/image-model-fallback.js.map +1 -1
- package/dist/src/agent/image/inbound-image-handling.js +1 -1
- package/dist/src/agent/image/inbound-image-handling.js.map +1 -1
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/image/tool-model-config.d.ts +1 -1
- package/dist/src/agent/image/tool-model-config.js +2 -2
- package/dist/src/agent/image/tool-model-config.js.map +1 -1
- package/dist/src/agent/ipc/inbox.js +3 -3
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js +1 -1
- package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js.map +1 -1
- package/dist/src/agent/media-generation/runtime-shared.d.ts +5 -2
- package/dist/src/agent/media-generation/runtime-shared.js +1 -1
- package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
- package/dist/src/agent/memory/builtin-memory-store.d.ts +6 -2
- package/dist/src/agent/memory/builtin-memory-store.js +15 -6
- package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
- package/dist/src/agent/memory/builtin-provider.d.ts +31 -9
- package/dist/src/agent/memory/builtin-provider.js +290 -11
- package/dist/src/agent/memory/builtin-provider.js.map +1 -1
- package/dist/src/agent/memory/candidate-extractor.d.ts +6 -0
- package/dist/src/agent/memory/candidate-extractor.js +60 -0
- package/dist/src/agent/memory/candidate-extractor.js.map +1 -0
- package/dist/src/agent/memory/context-assembler.d.ts +10 -0
- package/dist/src/agent/memory/context-assembler.js +26 -0
- package/dist/src/agent/memory/context-assembler.js.map +1 -0
- package/dist/src/agent/memory/create-memory-manager.js +25 -7
- package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
- package/dist/src/agent/memory/dreaming/config.d.ts +1 -6
- package/dist/src/agent/memory/dreaming/config.js +8 -8
- package/dist/src/agent/memory/dreaming/config.js.map +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +2 -0
- package/dist/src/agent/memory/dreaming/deep-promotion.js +25 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/index.d.ts +1 -0
- package/dist/src/agent/memory/index.js +4 -3
- package/dist/src/agent/memory/inject-prefetch.js +6 -2
- package/dist/src/agent/memory/inject-prefetch.js.map +1 -1
- package/dist/src/agent/memory/manager.d.ts +39 -2
- package/dist/src/agent/memory/manager.js +355 -39
- package/dist/src/agent/memory/manager.js.map +1 -1
- package/dist/src/agent/memory/memory-config.js +15 -15
- package/dist/src/agent/memory/memory-config.js.map +1 -1
- package/dist/src/agent/memory/memory-flush.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.d.ts +19 -5
- package/dist/src/agent/memory/plugin-discovery.js +97 -31
- package/dist/src/agent/memory/plugin-discovery.js.map +1 -1
- package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -1
- package/dist/src/agent/memory/provider.d.ts +20 -15
- package/dist/src/agent/memory/stub-memory-provider.d.ts +17 -2
- package/dist/src/agent/memory/stub-memory-provider.js +20 -3
- package/dist/src/agent/memory/stub-memory-provider.js.map +1 -1
- package/dist/src/agent/memory/types.d.ts +162 -3
- package/dist/src/agent/models/manager.d.ts +1 -1
- package/dist/src/agent/models/manager.js +2 -2
- package/dist/src/agent/models/manager.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js +2 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +2 -2
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -6
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +2 -8
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js.map +1 -1
- package/dist/src/agent/prompt/memory/index.d.ts +4 -2
- package/dist/src/agent/prompt/memory/index.js +19 -13
- package/dist/src/agent/prompt/memory/index.js.map +1 -1
- package/dist/src/agent/prompt/sections/memory-skills.js +1 -1
- package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +5 -20
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/reply/post-compaction-context.js +10 -7
- package/dist/src/agent/reply/post-compaction-context.js.map +1 -1
- package/dist/src/agent/reply/startup-context.js +7 -12
- package/dist/src/agent/reply/startup-context.js.map +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +1 -4
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/session-context-report.js +1 -1
- package/dist/src/agent/service/session-context-report.js.map +1 -1
- package/dist/src/agent/service.d.ts +3 -3
- package/dist/src/agent/service.js +30 -35
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +1 -2
- package/dist/src/agent/session/session-hydrator.js +1 -2
- package/dist/src/agent/session/session-hydrator.js.map +1 -1
- package/dist/src/agent/session/session-inspector.d.ts +1 -1
- package/dist/src/agent/session/session-inspector.js +10 -15
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/skills/config.js +2 -2
- package/dist/src/agent/skills/filesystem-watcher.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +3 -3
- package/dist/src/agent/skills/index.js +2 -2
- package/dist/src/agent/skills/installer.js +2 -2
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/skills/skill-view-path.js +1 -1
- package/dist/src/agent/skills/test-framework.js +1 -1
- package/dist/src/agent/starter-agents.d.ts +1 -3
- package/dist/src/agent/starter-agents.js +14 -22
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -2
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/curated-memory-tool.d.ts +2 -5
- package/dist/src/agent/tools/curated-memory-tool.js +77 -18
- package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +0 -4
- package/dist/src/agent/tools/factory.js +19 -58
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/find.js +1 -1
- package/dist/src/agent/tools/grep.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.d.ts +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +20 -15
- package/dist/src/agent/tools/image-generate-tool.js.map +1 -1
- package/dist/src/agent/tools/image-tool.js +1 -3
- package/dist/src/agent/tools/image-tool.js.map +1 -1
- package/dist/src/agent/tools/memory-tool.d.ts +2 -2
- package/dist/src/agent/tools/memory-tool.js +39 -14
- package/dist/src/agent/tools/memory-tool.js.map +1 -1
- package/dist/src/agent/tools/session-search-tool.js +1 -3
- package/dist/src/agent/tools/session-search-tool.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/web-extract.js +8 -9
- package/dist/src/agent/tools/web-extract.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +1 -3
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent-manifest/index.d.ts +4 -0
- package/dist/src/agent-manifest/index.js +10 -0
- package/dist/src/agent-manifest/index.js.map +1 -0
- package/dist/src/agent-manifest/prompt.d.ts +2 -0
- package/dist/src/agent-manifest/prompt.js +57 -0
- package/dist/src/agent-manifest/prompt.js.map +1 -0
- package/dist/src/agent-manifest/resolver.d.ts +12 -0
- package/dist/src/agent-manifest/resolver.js +95 -0
- package/dist/src/agent-manifest/resolver.js.map +1 -0
- package/dist/src/agent-manifest/schema.d.ts +1010 -0
- package/dist/src/agent-manifest/schema.js +269 -0
- package/dist/src/agent-manifest/schema.js.map +1 -0
- package/dist/src/agent-manifest/validator.d.ts +25 -0
- package/dist/src/agent-manifest/validator.js +88 -0
- package/dist/src/agent-manifest/validator.js.map +1 -0
- package/dist/src/agent-runtime/boundary-guard.d.ts +12 -0
- package/dist/src/agent-runtime/boundary-guard.js +23 -0
- package/dist/src/agent-runtime/boundary-guard.js.map +1 -0
- package/dist/src/agent-runtime/index.d.ts +7 -0
- package/dist/src/agent-runtime/index.js +8 -0
- package/dist/src/agent-runtime/memory-runtime.d.ts +21 -0
- package/dist/src/agent-runtime/memory-runtime.js +50 -0
- package/dist/src/agent-runtime/memory-runtime.js.map +1 -0
- package/dist/src/agent-runtime/model-router.d.ts +11 -0
- package/dist/src/agent-runtime/model-router.js +16 -0
- package/dist/src/agent-runtime/model-router.js.map +1 -0
- package/dist/src/agent-runtime/run-trace.d.ts +27 -0
- package/dist/src/agent-runtime/run-trace.js +53 -0
- package/dist/src/agent-runtime/run-trace.js.map +1 -0
- package/dist/src/agent-runtime/runtime-profile.d.ts +24 -0
- package/dist/src/agent-runtime/runtime-profile.js +44 -0
- package/dist/src/agent-runtime/runtime-profile.js.map +1 -0
- package/dist/src/agent-runtime/tool-registry.d.ts +28 -0
- package/dist/src/agent-runtime/tool-registry.js +52 -0
- package/dist/src/agent-runtime/tool-registry.js.map +1 -0
- package/dist/src/agent-runtime/workflow-runtime.d.ts +31 -0
- package/dist/src/agent-runtime/workflow-runtime.js +34 -0
- package/dist/src/agent-runtime/workflow-runtime.js.map +1 -0
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/profiles/store.js +2 -2
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
- package/dist/src/browser/actions/registry.js +5 -8
- package/dist/src/browser/actions/registry.js.map +1 -1
- package/dist/src/browser/backend-from-config.d.ts +1 -1
- package/dist/src/browser/backend-from-config.js +50 -71
- package/dist/src/browser/backend-from-config.js.map +1 -1
- package/dist/src/browser/browser-command-timeout.d.ts +0 -1
- package/dist/src/browser/browser-command-timeout.js +3 -7
- package/dist/src/browser/browser-command-timeout.js.map +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/pipeline/source.js +1 -1
- package/dist/src/browser/providers/browser-ext-install.d.ts +2 -12
- package/dist/src/browser/providers/browser-ext-install.js +7 -12
- package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +5 -5
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/readiness.js +16 -16
- package/dist/src/browser/readiness.js.map +1 -1
- package/dist/src/browser/schemas.js +1 -1
- package/dist/src/browser/schemas.js.map +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/catalog/channel-catalog-service.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/pipeline.d.ts +1 -1
- package/dist/src/channels/pipeline.js.map +1 -1
- package/dist/src/chat-commands/agent-edit.js +2 -3
- package/dist/src/chat-commands/agent-edit.js.map +1 -1
- package/dist/src/chat-commands/builtins/config.js +6 -6
- package/dist/src/chat-commands/builtins/config.js.map +1 -1
- package/dist/src/chat-commands/builtins/model.js +2 -2
- package/dist/src/chat-commands/builtins/model.js.map +1 -1
- package/dist/src/chat-commands/builtins/thinking.js +16 -42
- package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
- package/dist/src/chat-commands/config-paths.js +1 -1
- package/dist/src/chat-commands/config-paths.js.map +1 -1
- package/dist/src/chat-commands/context.js +3 -4
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/cli/command-manifest.d.ts +1 -1
- package/dist/src/cli/command-manifest.js +2 -2
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent.js +3 -1
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/agents.js +3 -6
- package/dist/src/cli/commands/agents.js.map +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +9 -11
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/config.js +6 -6
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +3 -18
- package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -2
- package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
- package/dist/src/cli/commands/extension-create.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-pack.js +2 -2
- package/dist/src/cli/commands/extension.js +3 -3
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/goal.js +1 -1
- package/dist/src/cli/commands/image.js +13 -372
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +7 -6
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/models.js +14 -16
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
- package/dist/src/cli/commands/onboard/model.js +28 -23
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +3 -3
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/skills-test.js +1 -1
- package/dist/src/cli/commands/tui.js +2 -2
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +10 -5
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/registry.js +1 -1
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/cli/templates.d.ts +1 -1
- package/dist/src/cli/templates.js +2 -12
- package/dist/src/cli/templates.js.map +1 -1
- package/dist/src/cli/utils/gateway-client.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.d.ts +1 -4
- package/dist/src/cli/utils/init-workspace-core.js +9 -8
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/commands/agents.config.d.ts +0 -1
- package/dist/src/commands/agents.config.js +59 -13
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.d.ts +5 -17
- package/dist/src/config/agent-profile.js +32 -64
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.d.ts +1 -1
- package/dist/src/config/agent-typed-models.js +3 -6
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +9 -9
- package/dist/src/config/integration.d.ts +1 -1
- package/dist/src/config/loader.js +4 -4
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/paths.d.ts +8 -1
- package/dist/src/config/paths.js +17 -4
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +1 -1
- package/dist/src/config/reload.js +2 -2
- package/dist/src/config/reload.js.map +1 -1
- package/dist/src/config/rules.js +6 -56
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +916 -779
- package/dist/src/config/schema.js +174 -423
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/connectors/composio-triggers.js +1 -1
- package/dist/src/cron/executor.js +1 -1
- package/dist/src/cron/index.js +1 -1
- package/dist/src/cron/service.js +2 -2
- package/dist/src/cron/validation.d.ts +3 -3
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/activation-context.js +13 -7
- package/dist/src/extensions/activation-context.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +2 -2
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/install.js +2 -2
- package/dist/src/extensions/loader.js +2 -2
- package/dist/src/extensions/lockfile.js +3 -3
- package/dist/src/extensions/security.js +1 -1
- package/dist/src/extensions/update.js +2 -2
- package/dist/src/gateway/agents-admin.d.ts +24 -18
- package/dist/src/gateway/agents-admin.js +158 -92
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +56 -0
- package/dist/src/gateway/capability-presets-admin.js +214 -0
- package/dist/src/gateway/capability-presets-admin.js.map +1 -0
- package/dist/src/gateway/chat-stream/mapper.js +9 -2
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/global-defaults-admin.d.ts +36 -0
- package/dist/src/gateway/global-defaults-admin.js +146 -0
- package/dist/src/gateway/global-defaults-admin.js.map +1 -0
- package/dist/src/gateway/hono/lib/agent-model.d.ts +1 -1
- package/dist/src/gateway/hono/lib/agent-model.js +1 -1
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +234 -127
- package/dist/src/gateway/hono/lib/config-payload.js +14 -38
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/routes/agents.js +88 -33
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/browser.js +8 -15
- package/dist/src/gateway/hono/routes/browser.js.map +1 -1
- package/dist/src/gateway/hono/routes/capability-presets.d.ts +3 -0
- package/dist/src/gateway/hono/routes/capability-presets.js +145 -0
- package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +4 -5
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +1 -17
- package/dist/src/gateway/hono/routes/config-patch/agents.js +2 -443
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +7 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +1 -1
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +8 -1
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/global-defaults.d.ts +3 -0
- package/dist/src/gateway/hono/routes/global-defaults.js +61 -0
- package/dist/src/gateway/hono/routes/global-defaults.js.map +1 -0
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- 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 +17 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/memory.d.ts +3 -0
- package/dist/src/gateway/hono/routes/memory.js +361 -0
- package/dist/src/gateway/hono/routes/memory.js.map +1 -0
- package/dist/src/gateway/hono/routes/models.js +2 -2
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +2 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +4 -4
- package/dist/src/gateway/service/marketplace-service.js +13 -9
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service.d.ts +1 -1
- package/dist/src/gateway/service.js +15 -16
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/goals/goal-workflow-judge.js +2 -2
- package/dist/src/i18n/goals-bundle.js +1 -1
- package/dist/src/i18n/index.js +1 -1
- package/dist/src/i18n/share-tool-bundle.js +2 -2
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +1 -1
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +2 -2
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +1 -1
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/media/store.js +1 -1
- package/dist/src/notes/agent-context.js +3 -3
- package/dist/src/notes/service.js +4 -2
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/notes/store.js +2 -2
- package/dist/src/project-trust/trust-store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.d.ts +5 -6
- package/dist/src/providers/index.js +26 -30
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/model-registry.js +4 -4
- package/dist/src/session/index.js +1 -1
- package/dist/src/session/init-session-turn.js +1 -1
- package/dist/src/session/resolve-session.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +1 -1
- package/dist/src/session/thinking-resolve.d.ts +1 -1
- package/dist/src/session/thinking-resolve.js +1 -1
- package/dist/src/session/thinking-resolve.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/storage/sqlite/connection.js +2 -2
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/memory-index-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/memory-index-repository.js +17 -16
- package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +144 -0
- package/dist/src/storage/sqlite/memory-records-repository.js +453 -0
- package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/012_memory_records.sql +63 -0
- package/dist/src/storage/sqlite/migrations/013_memory_trace_events.sql +21 -0
- package/dist/src/storage/sqlite/migrations/014_memory_record_governance.sql +10 -0
- package/dist/src/storage/sqlite/migrations/015_memory_trace_feedback.sql +4 -0
- package/dist/src/storage/sqlite/migrations/discover.js +1 -1
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +4 -4
- 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 +2 -2
- package/dist/src/storage/sqlite/schema.sql +86 -0
- package/dist/src/tui/backends/embedded-backend.d.ts +3 -0
- package/dist/src/tui/backends/embedded-backend.js +43 -24
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +1 -0
- package/dist/src/tui/backends/gateway-sse-backend.js +16 -3
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/components/tui-header.d.ts +0 -1
- package/dist/src/tui/components/tui-header.js +3 -8
- package/dist/src/tui/components/tui-header.js.map +1 -1
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-command-formatters.js +4 -4
- package/dist/src/tui/tui-commands.js +2 -2
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +2 -1
- package/dist/src/tui/tui-startup-resources.js.map +1 -1
- package/dist/src/tui/tui-startup-text.js +12 -12
- package/dist/src/tui/tui-startup-text.js.map +1 -1
- package/dist/src/tui/tui.js +10 -7
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +4 -4
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/streams.js +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +4 -5
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +3 -2
- package/dist/gateway/static/root/assets/agent-browser-settings-page-D1SyFYeh.js +0 -6
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-C9YxgvuI.js +0 -1
- package/dist/gateway/static/root/assets/agents-CteVs3UO.js +0 -71
- package/dist/gateway/static/root/assets/apps-page-CVQ1M8Ax.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-Cd3JbeQ1.js +0 -1
- package/dist/gateway/static/root/assets/config-api-C4RAtTKW.js +0 -3
- package/dist/gateway/static/root/assets/connectors-page-MsMa5qBr.js +0 -2
- package/dist/gateway/static/root/assets/cron-api-sJNMqB6P.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-D30CSwkn.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-6fCUWRQf.js +0 -1
- package/dist/gateway/static/root/assets/gateway-config-api-C6989a-W.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-BpF26t91.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DOjhmRyf.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-Xl9_wrFc.js +0 -2
- package/dist/gateway/static/root/assets/heartbeat-settings-DN9vEj9P.js +0 -1
- package/dist/gateway/static/root/assets/index-C8ytlAF2.js +0 -122
- package/dist/gateway/static/root/assets/index-CVpJW2NS.css +0 -1
- package/dist/gateway/static/root/assets/messages-BqzIDrlr.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BO4o-GmO.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-DLV_XDmT.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-ycsDlkFA.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DQpnE8K9.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BZui7iAY.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DEfzZ1ax.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-CLuSsu1-.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Cq4qpXLi.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-B9F3HyYQ.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Bp9UPPwm.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BIoBsfSV.js +0 -2
- package/dist/gateway/static/root/assets/use-agent-defaults-form-Cz2_pPzu.js +0 -1
- package/dist/gateway/static/root/assets/use-settings-tab-guard-nuHMmZQv.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BUIrKb8s.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-qE3SexnO.js +0 -18
- package/dist/src/agent/context/workspace-templates/USER.md +0 -24
|
@@ -26,10 +26,10 @@ import { resolveBrowserBackendFromConfig } from "../../browser/backend-from-conf
|
|
|
26
26
|
import { checkBrowserReadiness } from "../../browser/readiness.js";
|
|
27
27
|
import { CdpSupervisor } from "../../browser/cdp-supervisor.js";
|
|
28
28
|
import "../../browser/index.js";
|
|
29
|
-
import
|
|
29
|
+
import "./delegate-tool.js";
|
|
30
30
|
import { createWorkflowCatalog } from "../workflow/catalog.js";
|
|
31
31
|
import { createWorkflowTool } from "./workflow-tool.js";
|
|
32
|
-
import
|
|
32
|
+
import "./execute-code-tool.js";
|
|
33
33
|
import { createCronjobTool } from "./cronjob-tool.js";
|
|
34
34
|
import { createGoalTool } from "./goal-tool.js";
|
|
35
35
|
import { createSkillViewTool, createSkillsListTool } from "./skills-tools.js";
|
|
@@ -53,7 +53,7 @@ const CLARIFY_SUPPORTED_CHANNELS = new Set([
|
|
|
53
53
|
"telegram",
|
|
54
54
|
"cli"
|
|
55
55
|
]);
|
|
56
|
-
var AgentToolsFactory = class
|
|
56
|
+
var AgentToolsFactory = class {
|
|
57
57
|
browserManager = null;
|
|
58
58
|
/** One dialog/console supervisor per chat session (browser tab). */
|
|
59
59
|
browserTaskSupervisors = /* @__PURE__ */ new Map();
|
|
@@ -65,9 +65,8 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
65
65
|
browserReadinessKey() {
|
|
66
66
|
const cfg = this.deps.getConfig?.();
|
|
67
67
|
const backend = resolveBrowserBackendFromConfig(cfg);
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
const port = typeof ext?.port === "number" ? ext.port : 19820;
|
|
68
|
+
const host = "127.0.0.1";
|
|
69
|
+
const port = 19820;
|
|
71
70
|
const cdpUrl = backend.mode === "cdp" ? backend.config.wsEndpoint : "";
|
|
72
71
|
const cloudKind = backend.mode === "cloud" ? backend.config.type : "";
|
|
73
72
|
return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;
|
|
@@ -105,10 +104,9 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
105
104
|
browserSupervisorForTask(taskId) {
|
|
106
105
|
let s = this.browserTaskSupervisors.get(taskId);
|
|
107
106
|
if (!s) {
|
|
108
|
-
const b = this.deps.getConfig?.()?.agents?.defaults?.browser;
|
|
109
107
|
s = new CdpSupervisor({
|
|
110
|
-
dialogPolicy:
|
|
111
|
-
dialogTimeoutSeconds:
|
|
108
|
+
dialogPolicy: "auto_dismiss",
|
|
109
|
+
dialogTimeoutSeconds: 300
|
|
112
110
|
});
|
|
113
111
|
this.browserTaskSupervisors.set(taskId, s);
|
|
114
112
|
}
|
|
@@ -125,7 +123,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
125
123
|
}
|
|
126
124
|
ensureBrowserManager() {
|
|
127
125
|
if (!this.browserManager) this.browserManager = new BrowserManager({
|
|
128
|
-
getHeadless: () =>
|
|
126
|
+
getHeadless: () => false,
|
|
129
127
|
getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.())
|
|
130
128
|
});
|
|
131
129
|
return this.browserManager;
|
|
@@ -147,14 +145,13 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
147
145
|
const workspace = options?.workspace ?? this.deps.workspace;
|
|
148
146
|
const { bus } = this.deps;
|
|
149
147
|
const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;
|
|
150
|
-
const getBuiltin = options?.getBuiltinMemoryStore ?? this.deps.getBuiltinMemoryStore;
|
|
151
|
-
const memoriesDir = (getBuiltin?.())?.memoriesDir;
|
|
152
148
|
const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;
|
|
153
149
|
const getSkillMgr = options?.getSkillManager;
|
|
154
150
|
const disabled = options?.disabledTools;
|
|
155
151
|
const primary = getPrimary?.();
|
|
156
152
|
const modelHasVision = primary?.input?.includes("image") ?? false;
|
|
157
153
|
const cfg = this.deps.getConfig?.();
|
|
154
|
+
const browserEnabled = cfg?.browser?.enabled !== false;
|
|
158
155
|
const recordGoalEvidence = createGoalEvidenceRecorder({ getSessionKey: () => this.deps.getCurrentContext()?.sessionKey });
|
|
159
156
|
const optionalTools = [
|
|
160
157
|
createImageTool({
|
|
@@ -237,17 +234,14 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
237
234
|
workspace,
|
|
238
235
|
getConfig: () => this.deps.getConfig?.()
|
|
239
236
|
})] : [],
|
|
240
|
-
createMemorySearchTool({
|
|
237
|
+
...getMemMgr ? [createMemorySearchTool({
|
|
241
238
|
workspaceDir: workspace,
|
|
242
|
-
|
|
243
|
-
}),
|
|
244
|
-
createMemoryGetTool({
|
|
239
|
+
getMemoryManager: () => getMemMgr()
|
|
240
|
+
}), createMemoryGetTool({
|
|
245
241
|
workspaceDir: workspace,
|
|
246
|
-
|
|
247
|
-
}),
|
|
248
|
-
...
|
|
249
|
-
getMemMgr?.().onMemoryWrite(action, target, content);
|
|
250
|
-
} })] : [],
|
|
242
|
+
getMemoryManager: () => getMemMgr()
|
|
243
|
+
})] : [],
|
|
244
|
+
...getMemMgr && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.()) ? [createCuratedMemoryTool(() => getMemMgr())] : [],
|
|
251
245
|
...getMemMgr?.().getAdditionalTools() ?? [],
|
|
252
246
|
...this.deps.getSessionStore ? [createSessionSearchTool({
|
|
253
247
|
getSessionStore: this.deps.getSessionStore,
|
|
@@ -256,7 +250,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
256
250
|
})] : [],
|
|
257
251
|
...this.deps.getCronService ? [createCronjobTool({ getCronService: this.deps.getCronService })] : [],
|
|
258
252
|
createGoalTool(),
|
|
259
|
-
...
|
|
253
|
+
...browserEnabled ? [createBrowserUseTool({
|
|
260
254
|
getManager: () => this.ensureBrowserManager(),
|
|
261
255
|
getPageForTask: () => this.acquireBrowserPage(),
|
|
262
256
|
getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? "default",
|
|
@@ -267,46 +261,19 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
267
261
|
this.browserTaskSupervisors.delete(taskId);
|
|
268
262
|
}
|
|
269
263
|
})] : [],
|
|
270
|
-
...
|
|
264
|
+
...primary ? [createWorkflowTool({
|
|
271
265
|
catalog: createWorkflowCatalog(),
|
|
272
266
|
getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
|
|
273
267
|
getConfig: () => this.deps.getConfig?.(),
|
|
274
268
|
startWorkflowRun: this.deps.getWorkflowRunService ? (params) => this.deps.getWorkflowRunService().startWorkflowRun(params) : void 0
|
|
275
269
|
})] : [],
|
|
276
|
-
...
|
|
277
|
-
workspace,
|
|
278
|
-
getSubagentModel: () => {
|
|
279
|
-
const m = (options?.getPrimaryModel ?? this.deps.getPrimaryModel)?.();
|
|
280
|
-
if (!m) throw new Error("No primary model configured for delegate_task");
|
|
281
|
-
return m;
|
|
282
|
-
},
|
|
283
|
-
bus: this.deps.bus,
|
|
284
|
-
getConfig: () => this.deps.getConfig?.(),
|
|
285
|
-
getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,
|
|
286
|
-
hookRunner: this.deps.hookRunner,
|
|
287
|
-
toolExecutorConfig: this.deps.toolExecutorConfig,
|
|
288
|
-
buildChildTools: (childOpts) => {
|
|
289
|
-
return new AgentToolsFactory({
|
|
290
|
-
workspace: childOpts.workspace,
|
|
291
|
-
bus: childOpts.bus,
|
|
292
|
-
getCurrentContext: () => null,
|
|
293
|
-
getConfig: childOpts.getConfig,
|
|
294
|
-
getPrimaryModel: () => childOpts.model,
|
|
295
|
-
toolExecutorConfig: childOpts.toolExecutorConfig
|
|
296
|
-
}).createAllTools({
|
|
297
|
-
workspace: childOpts.workspace,
|
|
298
|
-
getPrimaryModel: () => childOpts.model,
|
|
299
|
-
disabledTools: new Set(["extensions"])
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
})] : [],
|
|
270
|
+
...[],
|
|
303
271
|
...optionalTools
|
|
304
272
|
], disabled);
|
|
305
273
|
}
|
|
306
274
|
createAllTools(coreOptions) {
|
|
307
275
|
const coreTools = this.createCoreTools(coreOptions);
|
|
308
276
|
const disableExtensions = coreOptions?.disabledTools?.has("extensions");
|
|
309
|
-
const cfg = this.deps.getConfig?.();
|
|
310
277
|
let bundled;
|
|
311
278
|
if (!this.deps.extensionRegistry || disableExtensions) bundled = coreTools;
|
|
312
279
|
else {
|
|
@@ -314,13 +281,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
314
281
|
log.info({ count: extensionTools.length }, "Loaded extension tools");
|
|
315
282
|
bundled = [...coreTools, ...extensionTools];
|
|
316
283
|
}
|
|
317
|
-
|
|
318
|
-
if (cfg?.agents?.defaults?.executeCode?.enabled === true && !coreOptions?.disabledTools?.has("execute_code")) {
|
|
319
|
-
const sandboxMap = buildSandboxToolMap(wrapped);
|
|
320
|
-
const wrappedExecute = wrapToolsWithProtection([createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap })], this.deps.toolExecutorConfig);
|
|
321
|
-
return [...wrapped, ...wrappedExecute];
|
|
322
|
-
}
|
|
323
|
-
return wrapped;
|
|
284
|
+
return wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);
|
|
324
285
|
}
|
|
325
286
|
};
|
|
326
287
|
function filterToolsByDisabledSet(tools, disabled) {
|
|
@@ -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 createEditFileTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createShellTool,\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 createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n createToolManualTool,\n createGoalTool,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { BuiltinMemoryStore } from '../memory/builtin-memory-store.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 { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport { createCronjobTool } from './cronjob-tool.js';\nimport type { CronService } from '../../cron/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';\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 /** Built-in curated memory store (agent home `memories/`). */\n getBuiltinMemoryStore?: () => BuiltinMemoryStore;\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 `cronjob` tool. */\n getCronService?: () => CronService | 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 shell 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/shell 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. `shell`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getBuiltinMemoryStore?: () => BuiltinMemoryStore;\n getMemoryManager?: () => MemoryManager;\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 ext = cfg?.agents?.defaults?.browser?.extension;\n const host = typeof ext?.host === 'string' && ext.host.trim() ? ext.host.trim() : '127.0.0.1';\n const port = typeof ext?.port === 'number' ? ext.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 const b = this.deps.getConfig?.()?.agents?.defaults?.browser;\n const dialogPolicy =\n b?.dialogPolicy === 'must_respond' || b?.dialogPolicy === 'auto_accept' || b?.dialogPolicy === 'auto_dismiss'\n ? b.dialogPolicy\n : 'auto_dismiss';\n const dialogTimeoutSeconds =\n typeof b?.dialogTimeoutSeconds === 'number' &&\n Number.isFinite(b.dialogTimeoutSeconds) &&\n b.dialogTimeoutSeconds >= 1\n ? Math.floor(b.dialogTimeoutSeconds)\n : 300;\n s = new CdpSupervisor({ dialogPolicy, dialogTimeoutSeconds });\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: () => this.deps.getConfig?.()?.agents?.defaults?.browser?.headless === true,\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 getBuiltin = options?.getBuiltinMemoryStore ?? this.deps.getBuiltinMemoryStore;\n const builtinStore = getBuiltin?.();\n const memoriesDir = builtinStore?.memoriesDir;\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 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 editTool = createEditFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\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 getConfig: () => this.deps.getConfig?.(),\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 ...(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 editTool,\n listDir,\n grep,\n find,\n createShellTool(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 createMemorySearchTool({ workspaceDir: workspace, memoriesDir }),\n createMemoryGetTool({ workspaceDir: workspace, memoriesDir }),\n ...(getBuiltin && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(getBuiltin, {\n onMemoryWrite: (action, target, content) => {\n getMemMgr?.().onMemoryWrite(action, target, content);\n },\n }),\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.getCronService\n ? [\n createCronjobTool({\n getCronService: this.deps.getCronService,\n }),\n ]\n : []),\n createGoalTool(),\n ...(cfg?.agents?.defaults?.browser?.enabled !== false\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 ...(cfg?.agents?.defaults?.workflow?.enabled !== false && 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 ...(cfg?.agents?.defaults?.delegate?.enabled === true && 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 disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n const cfg = this.deps.getConfig?.();\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 =\n cfg?.agents?.defaults?.executeCode?.enabled === true &&\n !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 createEditFileTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createShellTool,\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 createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n createToolManualTool,\n createGoalTool,\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 { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport { createCronjobTool } from './cronjob-tool.js';\nimport type { CronService } from '../../cron/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';\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 `cronjob` tool. */\n getCronService?: () => CronService | 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 shell 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/shell 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. `shell`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getMemoryManager?: () => MemoryManager;\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 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 editTool = createEditFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\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 getConfig: () => this.deps.getConfig?.(),\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 ...(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 editTool,\n listDir,\n grep,\n find,\n createShellTool(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, getMemoryManager: () => getMemMgr() }),\n createMemoryGetTool({ workspaceDir: workspace, 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.getCronService\n ? [\n createCronjobTool({\n getCronService: this.deps.getCronService,\n }),\n ]\n : []),\n createGoalTool(),\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 disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\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,7 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
|
|
2
2
|
import { resolveToCwd } from "../../utils/helpers.js";
|
|
3
|
-
import { existsSync } from "fs";
|
|
4
3
|
import path from "path";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
5
|
import { Type } from "@sinclair/typebox";
|
|
6
6
|
import { globSync } from "glob";
|
|
7
7
|
//#region src/agent/tools/find.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_MAX_BYTES, formatSize, truncateHead, truncateLine } from "./truncate.js";
|
|
2
2
|
import { resolveToCwd } from "../../utils/helpers.js";
|
|
3
|
-
import { existsSync, readFileSync, statSync } from "fs";
|
|
4
3
|
import path from "path";
|
|
4
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
5
5
|
import { Type } from "@sinclair/typebox";
|
|
6
6
|
import { globSync } from "glob";
|
|
7
7
|
//#region src/agent/tools/grep.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
2
|
import type { Config } from '../../config/schema.js';
|
|
3
3
|
import { parseImageDataUrl } from '../image/generation/image-assets.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { ToolModelConfig } from '../image/tool-model-config.js';
|
|
5
5
|
export { parseImageDataUrl };
|
|
6
6
|
export declare function resolveImageGenerationModelConfigForTool(params: {
|
|
7
7
|
cfg?: Config;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { buildToolModelConfigFromCandidates, coerceToolModelConfig, hasToolModelConfig } from "../image/tool-model-config.js";
|
|
2
1
|
import { applyImageGenerationModelConfigDefaults } from "../image/image-helpers.js";
|
|
3
2
|
import { isFailoverError } from "../failover-error.js";
|
|
4
3
|
import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
|
|
5
4
|
import { getImageGenerationProvider } from "../image/generation/provider-registry.js";
|
|
6
5
|
import { generateImage, listImageGenerationProvidersSummary } from "../image/generation/runtime.js";
|
|
6
|
+
import path from "node:path";
|
|
7
7
|
import { randomBytes } from "node:crypto";
|
|
8
8
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
9
|
-
import path from "node:path";
|
|
10
9
|
import { Type } from "@sinclair/typebox";
|
|
11
10
|
//#region src/agent/tools/image-generate-tool.ts
|
|
12
11
|
const DEFAULT_COUNT = 1;
|
|
@@ -124,19 +123,24 @@ async function loadInputImages(params) {
|
|
|
124
123
|
return out;
|
|
125
124
|
}
|
|
126
125
|
function resolveImageGenerationModelConfigForTool(params) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
126
|
+
const providers = listImageGenerationProvidersSummary(params.cfg);
|
|
127
|
+
const candidates = [];
|
|
128
|
+
for (const providerSummary of providers) {
|
|
129
|
+
const provider = getImageGenerationProvider(providerSummary.id, params.cfg);
|
|
130
|
+
let configured = false;
|
|
131
|
+
try {
|
|
132
|
+
configured = provider?.isConfigured?.({ cfg: params.cfg }) ?? false;
|
|
133
|
+
} catch {
|
|
134
|
+
configured = false;
|
|
135
|
+
}
|
|
136
|
+
const modelRef = `${providerSummary.id}/${providerSummary.defaultModel ?? providerSummary.models[0] ?? ""}`;
|
|
137
|
+
if (configured && /^[a-z0-9-]+\/.+/.test(modelRef) && !candidates.includes(modelRef)) candidates.push(modelRef);
|
|
138
|
+
}
|
|
139
|
+
if (candidates.length === 0) return null;
|
|
140
|
+
return {
|
|
141
|
+
primary: candidates[0],
|
|
142
|
+
...candidates.length > 1 ? { fallbacks: candidates.slice(1) } : {}
|
|
143
|
+
};
|
|
140
144
|
}
|
|
141
145
|
async function saveGeneratedImages(params) {
|
|
142
146
|
const dir = path.join(params.workspace, "media", "generated");
|
|
@@ -220,6 +224,7 @@ function createImageGenerateTool(options) {
|
|
|
220
224
|
try {
|
|
221
225
|
const result = await generateImage({
|
|
222
226
|
cfg: effectiveCfg,
|
|
227
|
+
modelConfig: imageGenerationModelConfig,
|
|
223
228
|
prompt,
|
|
224
229
|
...modelOverride ? { modelOverride } : {},
|
|
225
230
|
count,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-generate-tool.js","names":[],"sources":["../../../../src/agent/tools/image-generate-tool.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport { isFailoverError } from '../failover-error.js';\nimport {\n imageAssetFromDataUrl,\n imageFileExtensionForMimeType,\n mimeTypeFromFileName,\n parseImageDataUrl,\n sniffImageMimeType,\n} from '../image/generation/image-assets.js';\nimport {\n generateImage,\n listImageGenerationProvidersSummary,\n} from '../image/generation/runtime.js';\nimport { getImageGenerationProvider } from '../image/generation/provider-registry.js';\nimport type {\n ImageGenerationBackground,\n ImageGenerationOutputFormat,\n ImageGenerationProviderOptions,\n ImageGenerationQuality,\n ImageGenerationResolution,\n ImageGenerationSourceImage,\n} from '../image/generation/types.js';\nimport { applyImageGenerationModelConfigDefaults } from '../image/image-helpers.js';\nimport {\n buildToolModelConfigFromCandidates,\n coerceToolModelConfig,\n hasToolModelConfig,\n type ToolModelConfig,\n} from '../image/tool-model-config.js';\n\nconst DEFAULT_COUNT = 1;\nconst MAX_COUNT = 9;\nconst ALLOWED_QUALITIES: ImageGenerationQuality[] = ['low', 'medium', 'high', 'auto'];\nconst ALLOWED_OUTPUT_FORMATS: ImageGenerationOutputFormat[] = ['png', 'jpeg', 'webp'];\nconst ALLOWED_BACKGROUNDS: ImageGenerationBackground[] = ['transparent', 'opaque', 'auto'];\nconst ALLOWED_RESOLUTIONS: ImageGenerationResolution[] = ['1K', '2K', '4K'];\n\nconst ImageGenerateToolSchema = Type.Object({\n action: Type.Optional(\n Type.String({\n description: 'Optional: \"generate\" (default) or \"list\" available image-generation providers.',\n }),\n ),\n prompt: Type.Optional(Type.String({ description: 'Image generation prompt.' })),\n model: Type.Optional(\n Type.String({\n description:\n 'Optional provider/model override, e.g. openai/gpt-image-1 / dashscope/wan2.7-image-pro / minimax/image-01.',\n }),\n ),\n filename: Type.Optional(Type.String({ description: 'Optional basename hint for saved files.' })),\n size: Type.Optional(Type.String({ description: 'Optional pixel size, e.g. 1024x1024.' })),\n aspectRatio: Type.Optional(\n Type.String({ description: 'Optional aspect ratio, e.g. 16:9 / 9:16 / 1:1.' }),\n ),\n resolution: Type.Optional(\n Type.String({\n description: 'Optional resolution tier: 1K / 2K / 4K (provider-dependent).',\n }),\n ),\n count: Type.Optional(\n Type.Number({ minimum: 1, maximum: MAX_COUNT, description: `Number of images (1–${MAX_COUNT}).` }),\n ),\n quality: Type.Optional(\n Type.String({ description: 'Optional quality: low / medium / high / auto.' }),\n ),\n outputFormat: Type.Optional(\n Type.String({ description: 'Optional output format: png / jpeg / webp.' }),\n ),\n background: Type.Optional(\n Type.String({ description: 'Optional background: transparent / opaque / auto.' }),\n ),\n inputImages: Type.Optional(\n Type.Array(\n Type.Object({\n source: Type.String({\n description: 'Workspace-relative file path or `data:image/...;base64,...` URL.',\n }),\n }),\n { description: 'Reference images for edit mode (provider must support edit).' },\n ),\n ),\n providerOptions: Type.Optional(\n Type.Object({\n openai: Type.Optional(\n Type.Object({\n moderation: Type.Optional(Type.String()),\n outputCompression: Type.Optional(Type.Number()),\n user: Type.Optional(Type.String()),\n }),\n ),\n }),\n ),\n});\n\nfunction readStringParam(args: Record<string, unknown>, key: string): string | undefined {\n const v = args[key];\n return typeof v === 'string' && v.trim() ? v.trim() : undefined;\n}\n\nfunction readEnumParam<T extends string>(\n args: Record<string, unknown>,\n key: string,\n allowed: ReadonlyArray<T>,\n): T | undefined {\n const raw = readStringParam(args, key);\n if (!raw) return undefined;\n const lower = raw.toLowerCase() as T;\n return allowed.includes(lower) ? lower : undefined;\n}\n\nfunction readResolutionParam(args: Record<string, unknown>): ImageGenerationResolution | undefined {\n const raw = readStringParam(args, 'resolution');\n if (!raw) return undefined;\n const upper = raw.toUpperCase();\n return (ALLOWED_RESOLUTIONS as ReadonlyArray<string>).includes(upper)\n ? (upper as ImageGenerationResolution)\n : undefined;\n}\n\nfunction readProviderOptions(args: Record<string, unknown>): ImageGenerationProviderOptions | undefined {\n const raw = args.providerOptions;\n if (!raw || typeof raw !== 'object') return undefined;\n const out: ImageGenerationProviderOptions = {};\n const oa = (raw as Record<string, unknown>).openai;\n if (oa && typeof oa === 'object') {\n const oaRec = oa as Record<string, unknown>;\n const moderation = typeof oaRec.moderation === 'string' ? oaRec.moderation.toLowerCase() : undefined;\n const outputCompression =\n typeof oaRec.outputCompression === 'number' && Number.isFinite(oaRec.outputCompression)\n ? oaRec.outputCompression\n : undefined;\n const user = typeof oaRec.user === 'string' && oaRec.user.trim() ? oaRec.user.trim() : undefined;\n out.openai = {\n ...(moderation === 'low' || moderation === 'auto' ? { moderation: moderation as 'low' | 'auto' } : {}),\n ...(outputCompression !== undefined ? { outputCompression } : {}),\n ...(user ? { user } : {}),\n };\n if (Object.keys(out.openai).length === 0) delete out.openai;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nclass ToolInputError extends Error {}\n\nasync function loadInputImages(params: {\n workspace: string;\n sources: ReadonlyArray<{ source: string }>;\n}): Promise<ImageGenerationSourceImage[]> {\n if (!params.sources?.length) return [];\n const out: ImageGenerationSourceImage[] = [];\n const workspaceAbs = path.resolve(params.workspace);\n for (const entry of params.sources) {\n const source = entry?.source;\n if (typeof source !== 'string' || !source.trim()) {\n throw new ToolInputError('inputImages[].source is required.');\n }\n const trimmed = source.trim();\n if (/^data:image\\//i.test(trimmed)) {\n const parsed = imageAssetFromDataUrl(trimmed);\n if (!parsed) throw new ToolInputError('Invalid data URL in inputImages[].source.');\n out.push(parsed);\n continue;\n }\n if (/^https?:\\/\\//i.test(trimmed)) {\n throw new ToolInputError('Sandboxed image_generate does not allow remote URLs.');\n }\n const resolved = path.resolve(workspaceAbs, trimmed);\n if (resolved !== workspaceAbs && !resolved.startsWith(workspaceAbs + path.sep)) {\n throw new ToolInputError('inputImages[].source escapes workspace.');\n }\n let buffer: Buffer;\n try {\n buffer = await readFile(resolved);\n } catch (e) {\n const em = e instanceof Error ? e.message : String(e);\n throw new ToolInputError(`inputImages[].source not readable: ${em}`);\n }\n const mimeType = mimeTypeFromFileName(resolved) ?? sniffImageMimeType(buffer).mimeType;\n out.push({ buffer, mimeType, fileName: path.basename(resolved) });\n }\n return out;\n}\n\n// Re-exported for callers / tests; no behavioural change vs imported helper.\nexport { parseImageDataUrl };\n\nexport function resolveImageGenerationModelConfigForTool(params: { cfg?: Config }): ToolModelConfig | null {\n const explicit = coerceToolModelConfig(params.cfg?.agents?.defaults?.imageGenerationModel);\n if (hasToolModelConfig(explicit)) {\n return explicit;\n }\n // Step 2: tool default = enumerate every provider whose isConfigured() is true,\n // ordered as registered. No more hard-coded openai/dashscope fallback.\n const providers = listImageGenerationProvidersSummary(params.cfg);\n const candidates = providers\n .filter((p) => {\n const provider = getImageGenerationProvider(p.id, params.cfg);\n try {\n return provider?.isConfigured?.({ cfg: params.cfg }) ?? false;\n } catch {\n return false;\n }\n })\n .map((p) => `${p.id}/${p.defaultModel ?? p.models[0] ?? ''}`)\n .filter((s) => /^[a-z0-9-]+\\/.+/.test(s));\n\n return buildToolModelConfigFromCandidates({ explicit, candidates });\n}\n\nasync function saveGeneratedImages(params: {\n workspace: string;\n images: Array<{ buffer: Buffer; mimeType: string; fileName?: string }>;\n filenameHint?: string;\n}): Promise<string[]> {\n const dir = path.join(params.workspace, 'media', 'generated');\n await mkdir(dir, { recursive: true });\n const out: string[] = [];\n const random = randomBytes(4).toString('hex');\n let i = 0;\n for (const img of params.images) {\n i += 1;\n const ext = imageFileExtensionForMimeType(img.mimeType);\n const base = (params.filenameHint?.replace(/[^\\w.-]/g, '') || 'image') + `-${random}`;\n const name = `${base}-${i}.${ext}`;\n const full = path.join(dir, name);\n await writeFile(full, img.buffer);\n out.push(full);\n }\n return out;\n}\n\nexport function createImageGenerateTool(options: {\n config?: Config;\n workspace: string;\n}): AgentTool<any, Record<string, unknown>> | null {\n const imageGenerationModelConfig = resolveImageGenerationModelConfigForTool({ cfg: options.config });\n if (!imageGenerationModelConfig) {\n return null;\n }\n\n const effectiveCfg =\n applyImageGenerationModelConfigDefaults(options.config, imageGenerationModelConfig) ??\n options.config;\n\n return {\n name: 'image_generate',\n label: 'Image Generation',\n description:\n 'Generate images with the configured image-generation model (default OpenAI). Use action=\"list\" to see providers. Saves files under workspace/media/generated/.',\n parameters: ImageGenerateToolSchema,\n async execute(\n _toolCallId: string,\n args: Record<string, unknown>,\n ): Promise<AgentToolResult<Record<string, unknown>>> {\n const params = args as Record<string, unknown>;\n const action = (readStringParam(params, 'action') || 'generate').toLowerCase();\n if (action === 'list') {\n const providers = listImageGenerationProvidersSummary(effectiveCfg);\n const lines = providers.flatMap((p) => [\n `${p.id}${p.defaultModel ? ` (default ${p.defaultModel})` : ''}`,\n ` models: ${p.models.join(', ')}`,\n ]);\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n details: { providers },\n };\n }\n if (action !== 'generate') {\n return {\n content: [{ type: 'text', text: 'action must be \"generate\" or \"list\".' }],\n details: { error: 'bad_action' },\n };\n }\n\n const prompt = readStringParam(params, 'prompt');\n if (!prompt) {\n return {\n content: [{ type: 'text', text: 'prompt is required for image generation.' }],\n details: { error: 'missing_prompt' },\n };\n }\n\n const modelOverride = readStringParam(params, 'model');\n const filename = readStringParam(params, 'filename');\n const size = readStringParam(params, 'size');\n const aspectRatio = readStringParam(params, 'aspectRatio');\n const resolution = readResolutionParam(params);\n const quality = readEnumParam(params, 'quality', ALLOWED_QUALITIES);\n const outputFormat = readEnumParam(params, 'outputFormat', ALLOWED_OUTPUT_FORMATS);\n const background = readEnumParam(params, 'background', ALLOWED_BACKGROUNDS);\n const providerOptions = readProviderOptions(params);\n\n const countRaw = params.count;\n const count =\n typeof countRaw === 'number' && Number.isFinite(countRaw)\n ? Math.min(MAX_COUNT, Math.max(1, Math.floor(countRaw)))\n : DEFAULT_COUNT;\n\n let inputImages: ImageGenerationSourceImage[] = [];\n try {\n inputImages = await loadInputImages({\n workspace: options.workspace,\n sources: (params.inputImages as Array<{ source: string }>) ?? [],\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return {\n content: [{ type: 'text', text: `Image generation failed: ${msg}` }],\n details: {\n error: e instanceof ToolInputError ? 'invalid_input_images' : 'generation_failed',\n },\n };\n }\n\n try {\n const result = await generateImage({\n cfg: effectiveCfg,\n prompt,\n ...(modelOverride ? { modelOverride } : {}),\n count,\n ...(size ? { size } : {}),\n ...(aspectRatio ? { aspectRatio } : {}),\n ...(resolution ? { resolution } : {}),\n ...(quality ? { quality } : {}),\n ...(outputFormat ? { outputFormat } : {}),\n ...(background ? { background } : {}),\n ...(inputImages.length > 0 ? { inputImages } : {}),\n ...(providerOptions ? { providerOptions } : {}),\n });\n\n const paths = await saveGeneratedImages({\n workspace: options.workspace,\n images: result.images,\n ...(filename ? { filenameHint: filename } : {}),\n });\n\n const workspaceRelativePaths = paths.map((p) =>\n path.relative(options.workspace, p).split(path.sep).join('/'),\n );\n\n const lines: string[] = [\n `Generated ${paths.length} image(s) with ${result.provider}/${result.model}.`,\n ...paths.map((p) => `Saved: ${p}`),\n ];\n for (const note of buildNormalizationNotes(result.normalization, result.ignoredOverrides)) {\n lines.push(note);\n }\n\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n details: {\n provider: result.provider,\n model: result.model,\n paths,\n workspaceRelativePaths,\n attempts: result.attempts,\n ...(result.normalization ? { normalization: result.normalization } : {}),\n ...(result.ignoredOverrides.length > 0\n ? { ignoredOverrides: result.ignoredOverrides }\n : {}),\n ...(result.metadata ? { metadata: result.metadata } : {}),\n },\n };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n const failoverFields = isFailoverError(e)\n ? {\n ...(e.reason !== undefined ? { reason: e.reason } : {}),\n ...(e.status !== undefined ? { status: e.status } : {}),\n ...(e.code !== undefined ? { code: e.code } : {}),\n ...(e.provider !== undefined ? { provider: e.provider } : {}),\n ...(e.model !== undefined ? { model: e.model } : {}),\n attempts: e.attempts,\n }\n : {};\n return {\n content: [{ type: 'text', text: `Image generation failed: ${msg}` }],\n details: { error: 'generation_failed', ...failoverFields },\n };\n }\n },\n } as any;\n}\n\nfunction buildNormalizationNotes(\n normalization: import('../image/generation/types.js').ImageGenerationNormalization | undefined,\n ignoredOverrides: ReadonlyArray<import('../image/generation/types.js').ImageGenerationIgnoredOverride>,\n): string[] {\n const notes: string[] = [];\n if (normalization) {\n for (const [key, entry] of Object.entries(normalization)) {\n if (!entry) continue;\n const requested = entry.requested;\n const applied = entry.applied;\n if (requested !== undefined && applied !== undefined && requested !== applied) {\n notes.push(`Note: requested ${key}=\"${requested}\" → applied \"${applied}\".`);\n } else if (applied !== undefined && entry.derivedFrom) {\n notes.push(`Note: ${key}=\"${applied}\" derived from ${entry.derivedFrom}.`);\n }\n }\n }\n for (const ig of ignoredOverrides) {\n notes.push(`Note: ignored ${ig.key}=\"${ig.value}\" (not supported by provider).`);\n }\n return notes;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"image-generate-tool.js","names":[],"sources":["../../../../src/agent/tools/image-generate-tool.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport { isFailoverError } from '../failover-error.js';\nimport {\n imageAssetFromDataUrl,\n imageFileExtensionForMimeType,\n mimeTypeFromFileName,\n parseImageDataUrl,\n sniffImageMimeType,\n} from '../image/generation/image-assets.js';\nimport {\n generateImage,\n listImageGenerationProvidersSummary,\n} from '../image/generation/runtime.js';\nimport { getImageGenerationProvider } from '../image/generation/provider-registry.js';\nimport type {\n ImageGenerationBackground,\n ImageGenerationOutputFormat,\n ImageGenerationProviderOptions,\n ImageGenerationQuality,\n ImageGenerationResolution,\n ImageGenerationSourceImage,\n} from '../image/generation/types.js';\nimport { applyImageGenerationModelConfigDefaults } from '../image/image-helpers.js';\nimport type { ToolModelConfig } from '../image/tool-model-config.js';\n\nconst DEFAULT_COUNT = 1;\nconst MAX_COUNT = 9;\nconst ALLOWED_QUALITIES: ImageGenerationQuality[] = ['low', 'medium', 'high', 'auto'];\nconst ALLOWED_OUTPUT_FORMATS: ImageGenerationOutputFormat[] = ['png', 'jpeg', 'webp'];\nconst ALLOWED_BACKGROUNDS: ImageGenerationBackground[] = ['transparent', 'opaque', 'auto'];\nconst ALLOWED_RESOLUTIONS: ImageGenerationResolution[] = ['1K', '2K', '4K'];\n\nconst ImageGenerateToolSchema = Type.Object({\n action: Type.Optional(\n Type.String({\n description: 'Optional: \"generate\" (default) or \"list\" available image-generation providers.',\n }),\n ),\n prompt: Type.Optional(Type.String({ description: 'Image generation prompt.' })),\n model: Type.Optional(\n Type.String({\n description:\n 'Optional provider/model override, e.g. openai/gpt-image-1 / dashscope/wan2.7-image-pro / minimax/image-01.',\n }),\n ),\n filename: Type.Optional(Type.String({ description: 'Optional basename hint for saved files.' })),\n size: Type.Optional(Type.String({ description: 'Optional pixel size, e.g. 1024x1024.' })),\n aspectRatio: Type.Optional(\n Type.String({ description: 'Optional aspect ratio, e.g. 16:9 / 9:16 / 1:1.' }),\n ),\n resolution: Type.Optional(\n Type.String({\n description: 'Optional resolution tier: 1K / 2K / 4K (provider-dependent).',\n }),\n ),\n count: Type.Optional(\n Type.Number({ minimum: 1, maximum: MAX_COUNT, description: `Number of images (1–${MAX_COUNT}).` }),\n ),\n quality: Type.Optional(\n Type.String({ description: 'Optional quality: low / medium / high / auto.' }),\n ),\n outputFormat: Type.Optional(\n Type.String({ description: 'Optional output format: png / jpeg / webp.' }),\n ),\n background: Type.Optional(\n Type.String({ description: 'Optional background: transparent / opaque / auto.' }),\n ),\n inputImages: Type.Optional(\n Type.Array(\n Type.Object({\n source: Type.String({\n description: 'Workspace-relative file path or `data:image/...;base64,...` URL.',\n }),\n }),\n { description: 'Reference images for edit mode (provider must support edit).' },\n ),\n ),\n providerOptions: Type.Optional(\n Type.Object({\n openai: Type.Optional(\n Type.Object({\n moderation: Type.Optional(Type.String()),\n outputCompression: Type.Optional(Type.Number()),\n user: Type.Optional(Type.String()),\n }),\n ),\n }),\n ),\n});\n\nfunction readStringParam(args: Record<string, unknown>, key: string): string | undefined {\n const v = args[key];\n return typeof v === 'string' && v.trim() ? v.trim() : undefined;\n}\n\nfunction readEnumParam<T extends string>(\n args: Record<string, unknown>,\n key: string,\n allowed: ReadonlyArray<T>,\n): T | undefined {\n const raw = readStringParam(args, key);\n if (!raw) return undefined;\n const lower = raw.toLowerCase() as T;\n return allowed.includes(lower) ? lower : undefined;\n}\n\nfunction readResolutionParam(args: Record<string, unknown>): ImageGenerationResolution | undefined {\n const raw = readStringParam(args, 'resolution');\n if (!raw) return undefined;\n const upper = raw.toUpperCase();\n return (ALLOWED_RESOLUTIONS as ReadonlyArray<string>).includes(upper)\n ? (upper as ImageGenerationResolution)\n : undefined;\n}\n\nfunction readProviderOptions(args: Record<string, unknown>): ImageGenerationProviderOptions | undefined {\n const raw = args.providerOptions;\n if (!raw || typeof raw !== 'object') return undefined;\n const out: ImageGenerationProviderOptions = {};\n const oa = (raw as Record<string, unknown>).openai;\n if (oa && typeof oa === 'object') {\n const oaRec = oa as Record<string, unknown>;\n const moderation = typeof oaRec.moderation === 'string' ? oaRec.moderation.toLowerCase() : undefined;\n const outputCompression =\n typeof oaRec.outputCompression === 'number' && Number.isFinite(oaRec.outputCompression)\n ? oaRec.outputCompression\n : undefined;\n const user = typeof oaRec.user === 'string' && oaRec.user.trim() ? oaRec.user.trim() : undefined;\n out.openai = {\n ...(moderation === 'low' || moderation === 'auto' ? { moderation: moderation as 'low' | 'auto' } : {}),\n ...(outputCompression !== undefined ? { outputCompression } : {}),\n ...(user ? { user } : {}),\n };\n if (Object.keys(out.openai).length === 0) delete out.openai;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nclass ToolInputError extends Error {}\n\nasync function loadInputImages(params: {\n workspace: string;\n sources: ReadonlyArray<{ source: string }>;\n}): Promise<ImageGenerationSourceImage[]> {\n if (!params.sources?.length) return [];\n const out: ImageGenerationSourceImage[] = [];\n const workspaceAbs = path.resolve(params.workspace);\n for (const entry of params.sources) {\n const source = entry?.source;\n if (typeof source !== 'string' || !source.trim()) {\n throw new ToolInputError('inputImages[].source is required.');\n }\n const trimmed = source.trim();\n if (/^data:image\\//i.test(trimmed)) {\n const parsed = imageAssetFromDataUrl(trimmed);\n if (!parsed) throw new ToolInputError('Invalid data URL in inputImages[].source.');\n out.push(parsed);\n continue;\n }\n if (/^https?:\\/\\//i.test(trimmed)) {\n throw new ToolInputError('Sandboxed image_generate does not allow remote URLs.');\n }\n const resolved = path.resolve(workspaceAbs, trimmed);\n if (resolved !== workspaceAbs && !resolved.startsWith(workspaceAbs + path.sep)) {\n throw new ToolInputError('inputImages[].source escapes workspace.');\n }\n let buffer: Buffer;\n try {\n buffer = await readFile(resolved);\n } catch (e) {\n const em = e instanceof Error ? e.message : String(e);\n throw new ToolInputError(`inputImages[].source not readable: ${em}`);\n }\n const mimeType = mimeTypeFromFileName(resolved) ?? sniffImageMimeType(buffer).mimeType;\n out.push({ buffer, mimeType, fileName: path.basename(resolved) });\n }\n return out;\n}\n\n// Re-exported for callers / tests; no behavioural change vs imported helper.\nexport { parseImageDataUrl };\n\nexport function resolveImageGenerationModelConfigForTool(params: { cfg?: Config }): ToolModelConfig | null {\n // Step 2: tool default = enumerate every provider whose isConfigured() is true,\n // ordered as registered. No more hard-coded openai/dashscope fallback.\n const providers = listImageGenerationProvidersSummary(params.cfg);\n const candidates: string[] = [];\n for (const providerSummary of providers) {\n const provider = getImageGenerationProvider(providerSummary.id, params.cfg);\n let configured = false;\n try {\n configured = provider?.isConfigured?.({ cfg: params.cfg }) ?? false;\n } catch {\n configured = false;\n }\n const modelRef = `${providerSummary.id}/${providerSummary.defaultModel ?? providerSummary.models[0] ?? ''}`;\n if (configured && /^[a-z0-9-]+\\/.+/.test(modelRef) && !candidates.includes(modelRef)) {\n candidates.push(modelRef);\n }\n }\n\n if (candidates.length === 0) {\n return null;\n }\n\n return {\n primary: candidates[0],\n ...(candidates.length > 1 ? { fallbacks: candidates.slice(1) } : {}),\n };\n}\n\nasync function saveGeneratedImages(params: {\n workspace: string;\n images: Array<{ buffer: Buffer; mimeType: string; fileName?: string }>;\n filenameHint?: string;\n}): Promise<string[]> {\n const dir = path.join(params.workspace, 'media', 'generated');\n await mkdir(dir, { recursive: true });\n const out: string[] = [];\n const random = randomBytes(4).toString('hex');\n let i = 0;\n for (const img of params.images) {\n i += 1;\n const ext = imageFileExtensionForMimeType(img.mimeType);\n const base = (params.filenameHint?.replace(/[^\\w.-]/g, '') || 'image') + `-${random}`;\n const name = `${base}-${i}.${ext}`;\n const full = path.join(dir, name);\n await writeFile(full, img.buffer);\n out.push(full);\n }\n return out;\n}\n\nexport function createImageGenerateTool(options: {\n config?: Config;\n workspace: string;\n}): AgentTool<any, Record<string, unknown>> | null {\n const imageGenerationModelConfig = resolveImageGenerationModelConfigForTool({ cfg: options.config });\n if (!imageGenerationModelConfig) {\n return null;\n }\n\n const effectiveCfg =\n applyImageGenerationModelConfigDefaults(options.config, imageGenerationModelConfig) ??\n options.config;\n\n return {\n name: 'image_generate',\n label: 'Image Generation',\n description:\n 'Generate images with the configured image-generation model (default OpenAI). Use action=\"list\" to see providers. Saves files under workspace/media/generated/.',\n parameters: ImageGenerateToolSchema,\n async execute(\n _toolCallId: string,\n args: Record<string, unknown>,\n ): Promise<AgentToolResult<Record<string, unknown>>> {\n const params = args as Record<string, unknown>;\n const action = (readStringParam(params, 'action') || 'generate').toLowerCase();\n if (action === 'list') {\n const providers = listImageGenerationProvidersSummary(effectiveCfg);\n const lines = providers.flatMap((p) => [\n `${p.id}${p.defaultModel ? ` (default ${p.defaultModel})` : ''}`,\n ` models: ${p.models.join(', ')}`,\n ]);\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n details: { providers },\n };\n }\n if (action !== 'generate') {\n return {\n content: [{ type: 'text', text: 'action must be \"generate\" or \"list\".' }],\n details: { error: 'bad_action' },\n };\n }\n\n const prompt = readStringParam(params, 'prompt');\n if (!prompt) {\n return {\n content: [{ type: 'text', text: 'prompt is required for image generation.' }],\n details: { error: 'missing_prompt' },\n };\n }\n\n const modelOverride = readStringParam(params, 'model');\n const filename = readStringParam(params, 'filename');\n const size = readStringParam(params, 'size');\n const aspectRatio = readStringParam(params, 'aspectRatio');\n const resolution = readResolutionParam(params);\n const quality = readEnumParam(params, 'quality', ALLOWED_QUALITIES);\n const outputFormat = readEnumParam(params, 'outputFormat', ALLOWED_OUTPUT_FORMATS);\n const background = readEnumParam(params, 'background', ALLOWED_BACKGROUNDS);\n const providerOptions = readProviderOptions(params);\n\n const countRaw = params.count;\n const count =\n typeof countRaw === 'number' && Number.isFinite(countRaw)\n ? Math.min(MAX_COUNT, Math.max(1, Math.floor(countRaw)))\n : DEFAULT_COUNT;\n\n let inputImages: ImageGenerationSourceImage[] = [];\n try {\n inputImages = await loadInputImages({\n workspace: options.workspace,\n sources: (params.inputImages as Array<{ source: string }>) ?? [],\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return {\n content: [{ type: 'text', text: `Image generation failed: ${msg}` }],\n details: {\n error: e instanceof ToolInputError ? 'invalid_input_images' : 'generation_failed',\n },\n };\n }\n\n try {\n const result = await generateImage({\n cfg: effectiveCfg,\n modelConfig: imageGenerationModelConfig,\n prompt,\n ...(modelOverride ? { modelOverride } : {}),\n count,\n ...(size ? { size } : {}),\n ...(aspectRatio ? { aspectRatio } : {}),\n ...(resolution ? { resolution } : {}),\n ...(quality ? { quality } : {}),\n ...(outputFormat ? { outputFormat } : {}),\n ...(background ? { background } : {}),\n ...(inputImages.length > 0 ? { inputImages } : {}),\n ...(providerOptions ? { providerOptions } : {}),\n });\n\n const paths = await saveGeneratedImages({\n workspace: options.workspace,\n images: result.images,\n ...(filename ? { filenameHint: filename } : {}),\n });\n\n const workspaceRelativePaths = paths.map((p) =>\n path.relative(options.workspace, p).split(path.sep).join('/'),\n );\n\n const lines: string[] = [\n `Generated ${paths.length} image(s) with ${result.provider}/${result.model}.`,\n ...paths.map((p) => `Saved: ${p}`),\n ];\n for (const note of buildNormalizationNotes(result.normalization, result.ignoredOverrides)) {\n lines.push(note);\n }\n\n return {\n content: [{ type: 'text', text: lines.join('\\n') }],\n details: {\n provider: result.provider,\n model: result.model,\n paths,\n workspaceRelativePaths,\n attempts: result.attempts,\n ...(result.normalization ? { normalization: result.normalization } : {}),\n ...(result.ignoredOverrides.length > 0\n ? { ignoredOverrides: result.ignoredOverrides }\n : {}),\n ...(result.metadata ? { metadata: result.metadata } : {}),\n },\n };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n const failoverFields = isFailoverError(e)\n ? {\n ...(e.reason !== undefined ? { reason: e.reason } : {}),\n ...(e.status !== undefined ? { status: e.status } : {}),\n ...(e.code !== undefined ? { code: e.code } : {}),\n ...(e.provider !== undefined ? { provider: e.provider } : {}),\n ...(e.model !== undefined ? { model: e.model } : {}),\n attempts: e.attempts,\n }\n : {};\n return {\n content: [{ type: 'text', text: `Image generation failed: ${msg}` }],\n details: { error: 'generation_failed', ...failoverFields },\n };\n }\n },\n } as any;\n}\n\nfunction buildNormalizationNotes(\n normalization: import('../image/generation/types.js').ImageGenerationNormalization | undefined,\n ignoredOverrides: ReadonlyArray<import('../image/generation/types.js').ImageGenerationIgnoredOverride>,\n): string[] {\n const notes: string[] = [];\n if (normalization) {\n for (const [key, entry] of Object.entries(normalization)) {\n if (!entry) continue;\n const requested = entry.requested;\n const applied = entry.applied;\n if (requested !== undefined && applied !== undefined && requested !== applied) {\n notes.push(`Note: requested ${key}=\"${requested}\" → applied \"${applied}\".`);\n } else if (applied !== undefined && entry.derivedFrom) {\n notes.push(`Note: ${key}=\"${applied}\" derived from ${entry.derivedFrom}.`);\n }\n }\n }\n for (const ig of ignoredOverrides) {\n notes.push(`Note: ignored ${ig.key}=\"${ig.value}\" (not supported by provider).`);\n }\n return notes;\n}\n"],"mappings":"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"}
|
|
@@ -9,14 +9,12 @@ const DEFAULT_PROMPT = "Describe the image.";
|
|
|
9
9
|
const DEFAULT_MAX_IMAGES = 20;
|
|
10
10
|
function pickMaxBytes(cfg, maxBytesMb) {
|
|
11
11
|
if (typeof maxBytesMb === "number" && Number.isFinite(maxBytesMb) && maxBytesMb > 0) return Math.floor(maxBytesMb * 1024 * 1024);
|
|
12
|
-
const configured = cfg?.agents?.defaults?.mediaMaxMb;
|
|
13
|
-
if (typeof configured === "number" && Number.isFinite(configured) && configured > 0) return Math.floor(configured * 1024 * 1024);
|
|
14
12
|
return 20 * 1024 * 1024;
|
|
15
13
|
}
|
|
16
14
|
function createImageTool(options) {
|
|
17
15
|
const imageModelConfig = resolveImageModelConfigForTool({ cfg: options.config });
|
|
18
16
|
if (!imageModelConfig) return null;
|
|
19
|
-
const description = options.modelHasVision ? "Analyze one or more images with a vision model. Use `image` for a single path/URL, or `images` for multiple (up to 20). Only use when images were NOT already in the user message." : "Analyze one or more images using the
|
|
17
|
+
const description = options.modelHasVision ? "Analyze one or more images with a vision model. Use `image` for a single path/URL, or `images` for multiple (up to 20). Only use when images were NOT already in the user message." : "Analyze one or more images using the available image model. Use `image` or `images` for paths/URLs; optional `prompt` for what to extract.";
|
|
20
18
|
const localRoots = [options.workspace];
|
|
21
19
|
return {
|
|
22
20
|
name: "image",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-tool.js","names":[],"sources":["../../../../src/agent/tools/image-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport { describeImages } from '../image/understanding/runtime.js';\nimport { buildImageToolTextResult, resolvePromptAndModelOverride } from '../image/image-helpers.js';\nimport { runWithImageModelFallback } from '../image/image-model-fallback.js';\nimport { loadImageForToolInput } from '../image/load-image-media.js';\nimport { resolveImageModelConfigForTool } from '../image/tool-model-config.js';\n\nconst DEFAULT_PROMPT = 'Describe the image.';\nconst DEFAULT_MAX_IMAGES = 20;\n\nexport { resolveImageModelConfigForTool } from '../image/tool-model-config.js';\n\nfunction pickMaxBytes(cfg?: Config, maxBytesMb?: number): number {\n if (typeof maxBytesMb === 'number' && Number.isFinite(maxBytesMb) && maxBytesMb > 0) {\n return Math.floor(maxBytesMb * 1024 * 1024);\n }\n const configured = cfg?.agents?.defaults?.mediaMaxMb;\n if (typeof configured === 'number' && Number.isFinite(configured) && configured > 0) {\n return Math.floor(configured * 1024 * 1024);\n }\n return 20 * 1024 * 1024;\n}\n\nexport function createImageTool(options: {\n config?: Config;\n workspace: string;\n /** When true, session model already receives images in the user message. */\n modelHasVision?: boolean;\n}): AgentTool<any, Record<string, unknown>> | null {\n const imageModelConfig = resolveImageModelConfigForTool({ cfg: options.config });\n if (!imageModelConfig) {\n return null;\n }\n\n const description = options.modelHasVision\n ? 'Analyze one or more images with a vision model. Use `image` for a single path/URL, or `images` for multiple (up to 20). Only use when images were NOT already in the user message.'\n : 'Analyze one or more images using the configured image model (agents.defaults.imageModel). Use `image` or `images` for paths/URLs; optional `prompt` for what to extract.';\n\n const localRoots = [options.workspace];\n\n return {\n name: 'image',\n label: 'Image',\n description,\n parameters: Type.Object({\n prompt: Type.Optional(Type.String()),\n image: Type.Optional(Type.String({ description: 'Single image path or URL.' })),\n images: Type.Optional(\n Type.Array(Type.String(), {\n description: 'Multiple image paths or URLs (up to maxImages, default 20).',\n }),\n ),\n model: Type.Optional(Type.String({ description: 'Optional provider/model override.' })),\n maxBytesMb: Type.Optional(Type.Number()),\n maxImages: Type.Optional(Type.Number()),\n }),\n async execute(\n _toolCallId: string,\n args: Record<string, unknown>,\n ): Promise<AgentToolResult<Record<string, unknown>>> {\n const record = args && typeof args === 'object' ? args : {};\n\n const imageCandidates: string[] = [];\n if (typeof record.image === 'string') {\n imageCandidates.push(record.image);\n }\n if (Array.isArray(record.images)) {\n imageCandidates.push(...record.images.filter((v): v is string => typeof v === 'string'));\n }\n\n const seenImages = new Set<string>();\n const imageInputs: string[] = [];\n for (const candidate of imageCandidates) {\n const trimmedCandidate = candidate.trim();\n const normalizedForDedupe = trimmedCandidate.startsWith('@')\n ? trimmedCandidate.slice(1).trim()\n : trimmedCandidate;\n if (!normalizedForDedupe || seenImages.has(normalizedForDedupe)) {\n continue;\n }\n seenImages.add(normalizedForDedupe);\n imageInputs.push(trimmedCandidate);\n }\n\n if (imageInputs.length === 0) {\n return {\n content: [{ type: 'text', text: 'Error: provide `image` or `images`.' }],\n details: { error: 'missing_image' },\n };\n }\n\n const maxImagesRaw = typeof record.maxImages === 'number' ? record.maxImages : undefined;\n const maxImages =\n typeof maxImagesRaw === 'number' && Number.isFinite(maxImagesRaw) && maxImagesRaw > 0\n ? Math.floor(maxImagesRaw)\n : DEFAULT_MAX_IMAGES;\n if (imageInputs.length > maxImages) {\n return {\n content: [\n {\n type: 'text',\n text: `Too many images: ${imageInputs.length} (max ${maxImages}).`,\n },\n ],\n details: { error: 'too_many_images', count: imageInputs.length, max: maxImages },\n };\n }\n\n const { prompt: promptRaw, modelOverride } = resolvePromptAndModelOverride(\n record,\n DEFAULT_PROMPT,\n );\n const maxBytesMb = typeof record.maxBytesMb === 'number' ? record.maxBytesMb : undefined;\n const maxBytes = pickMaxBytes(options.config, maxBytesMb);\n\n const loadedImages: Array<{ buffer: Buffer; mimeType: string; resolvedImage: string }> = [];\n\n for (const imageRawInput of imageInputs) {\n const trimmed = imageRawInput.trim();\n const imageRaw = trimmed.startsWith('@') ? trimmed.slice(1).trim() : trimmed;\n if (!imageRaw) {\n return {\n content: [{ type: 'text', text: 'Error: empty image entry.' }],\n details: { error: 'empty_image' },\n };\n }\n\n const looksLikeWindowsDrivePath = /^[a-zA-Z]:[\\\\/]/.test(imageRaw);\n const hasScheme = /^[a-z][a-z0-9+.-]*:/i.test(imageRaw);\n const isFileUrl = /^file:/i.test(imageRaw);\n const isHttpUrl = /^https?:\\/\\//i.test(imageRaw);\n const isDataUrl = /^data:/i.test(imageRaw);\n if (hasScheme && !looksLikeWindowsDrivePath && !isFileUrl && !isHttpUrl && !isDataUrl) {\n return {\n content: [\n {\n type: 'text',\n text: `Unsupported image reference: ${imageRawInput}. Use a path, file://, data:, or http(s) URL.`,\n },\n ],\n details: { error: 'unsupported_image_reference', image: imageRawInput },\n };\n }\n\n try {\n const media = await loadImageForToolInput(imageRaw, {\n maxBytes,\n workspace: options.workspace,\n localRoots,\n });\n loadedImages.push({\n buffer: media.buffer,\n mimeType: media.mimeType,\n resolvedImage: imageRaw,\n });\n } catch (e) {\n return {\n content: [\n {\n type: 'text',\n text: `Failed to load image (${imageRawInput}): ${e instanceof Error ? e.message : String(e)}`,\n },\n ],\n details: { error: 'load_failed', image: imageRawInput },\n };\n }\n }\n\n const runResult = await runWithImageModelFallback({\n toolConfig: imageModelConfig,\n modelOverride,\n run: async (modelRef) => {\n const { text, provider, model } = await describeImages({\n modelRef,\n prompt: promptRaw,\n images: loadedImages.map((img) => ({ buffer: img.buffer, mimeType: img.mimeType })),\n timeoutMs: 60_000,\n });\n return { text, provider, model };\n },\n });\n\n const { result: inner, attempts } = runResult;\n const result = {\n text: inner.text,\n provider: inner.provider,\n model: inner.model,\n attempts,\n };\n\n const imageDetails =\n loadedImages.length === 1\n ? { image: loadedImages[0].resolvedImage }\n : {\n images: loadedImages.map((img) => ({ image: img.resolvedImage })),\n };\n\n return buildImageToolTextResult(result, imageDetails);\n },\n } as any;\n}\n"],"mappings":";;;;;;;AASA,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAI3B,SAAS,aAAa,KAAc,YAA6B;AAC/D,KAAI,OAAO,eAAe,YAAY,OAAO,SAAS,WAAW,IAAI,aAAa,EAChF,QAAO,KAAK,MAAM,aAAa,OAAO,KAAK;CAE7C,MAAM,aAAa,KAAK,QAAQ,UAAU;AAC1C,KAAI,OAAO,eAAe,YAAY,OAAO,SAAS,WAAW,IAAI,aAAa,EAChF,QAAO,KAAK,MAAM,aAAa,OAAO,KAAK;AAE7C,QAAO,KAAK,OAAO;;AAGrB,SAAgB,gBAAgB,SAKmB;CACjD,MAAM,mBAAmB,+BAA+B,EAAE,KAAK,QAAQ,QAAQ,CAAC;AAChF,KAAI,CAAC,iBACH,QAAO;CAGT,MAAM,cAAc,QAAQ,iBACxB,uLACA;CAEJ,MAAM,aAAa,CAAC,QAAQ,UAAU;AAEtC,QAAO;EACL,MAAM;EACN,OAAO;EACP;EACA,YAAY,KAAK,OAAO;GACtB,QAAQ,KAAK,SAAS,KAAK,QAAQ,CAAC;GACpC,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,6BAA6B,CAAC,CAAC;GAC/E,QAAQ,KAAK,SACX,KAAK,MAAM,KAAK,QAAQ,EAAE,EACxB,aAAa,+DACd,CAAC,CACH;GACD,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,qCAAqC,CAAC,CAAC;GACvF,YAAY,KAAK,SAAS,KAAK,QAAQ,CAAC;GACxC,WAAW,KAAK,SAAS,KAAK,QAAQ,CAAC;GACxC,CAAC;EACF,MAAM,QACJ,aACA,MACmD;GACnD,MAAM,SAAS,QAAQ,OAAO,SAAS,WAAW,OAAO,EAAE;GAE3D,MAAM,kBAA4B,EAAE;AACpC,OAAI,OAAO,OAAO,UAAU,SAC1B,iBAAgB,KAAK,OAAO,MAAM;AAEpC,OAAI,MAAM,QAAQ,OAAO,OAAO,CAC9B,iBAAgB,KAAK,GAAG,OAAO,OAAO,QAAQ,MAAmB,OAAO,MAAM,SAAS,CAAC;GAG1F,MAAM,6BAAa,IAAI,KAAa;GACpC,MAAM,cAAwB,EAAE;AAChC,QAAK,MAAM,aAAa,iBAAiB;IACvC,MAAM,mBAAmB,UAAU,MAAM;IACzC,MAAM,sBAAsB,iBAAiB,WAAW,IAAI,GACxD,iBAAiB,MAAM,EAAE,CAAC,MAAM,GAChC;AACJ,QAAI,CAAC,uBAAuB,WAAW,IAAI,oBAAoB,CAC7D;AAEF,eAAW,IAAI,oBAAoB;AACnC,gBAAY,KAAK,iBAAiB;;AAGpC,OAAI,YAAY,WAAW,EACzB,QAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAuC,CAAC;IACxE,SAAS,EAAE,OAAO,iBAAiB;IACpC;GAGH,MAAM,eAAe,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;GAC/E,MAAM,YACJ,OAAO,iBAAiB,YAAY,OAAO,SAAS,aAAa,IAAI,eAAe,IAChF,KAAK,MAAM,aAAa,GACxB;AACN,OAAI,YAAY,SAAS,UACvB,QAAO;IACL,SAAS,CACP;KACE,MAAM;KACN,MAAM,oBAAoB,YAAY,OAAO,QAAQ,UAAU;KAChE,CACF;IACD,SAAS;KAAE,OAAO;KAAmB,OAAO,YAAY;KAAQ,KAAK;KAAW;IACjF;GAGH,MAAM,EAAE,QAAQ,WAAW,kBAAkB,8BAC3C,QACA,eACD;GACD,MAAM,aAAa,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa,KAAA;GAC/E,MAAM,WAAW,aAAa,QAAQ,QAAQ,WAAW;GAEzD,MAAM,eAAmF,EAAE;AAE3F,QAAK,MAAM,iBAAiB,aAAa;IACvC,MAAM,UAAU,cAAc,MAAM;IACpC,MAAM,WAAW,QAAQ,WAAW,IAAI,GAAG,QAAQ,MAAM,EAAE,CAAC,MAAM,GAAG;AACrE,QAAI,CAAC,SACH,QAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAA6B,CAAC;KAC9D,SAAS,EAAE,OAAO,eAAe;KAClC;IAGH,MAAM,4BAA4B,kBAAkB,KAAK,SAAS;IAClE,MAAM,YAAY,uBAAuB,KAAK,SAAS;IACvD,MAAM,YAAY,UAAU,KAAK,SAAS;IAC1C,MAAM,YAAY,gBAAgB,KAAK,SAAS;IAChD,MAAM,YAAY,UAAU,KAAK,SAAS;AAC1C,QAAI,aAAa,CAAC,6BAA6B,CAAC,aAAa,CAAC,aAAa,CAAC,UAC1E,QAAO;KACL,SAAS,CACP;MACE,MAAM;MACN,MAAM,gCAAgC,cAAc;MACrD,CACF;KACD,SAAS;MAAE,OAAO;MAA+B,OAAO;MAAe;KACxE;AAGH,QAAI;KACF,MAAM,QAAQ,MAAM,sBAAsB,UAAU;MAClD;MACA,WAAW,QAAQ;MACnB;MACD,CAAC;AACF,kBAAa,KAAK;MAChB,QAAQ,MAAM;MACd,UAAU,MAAM;MAChB,eAAe;MAChB,CAAC;aACK,GAAG;AACV,YAAO;MACL,SAAS,CACP;OACE,MAAM;OACN,MAAM,yBAAyB,cAAc,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;OAC7F,CACF;MACD,SAAS;OAAE,OAAO;OAAe,OAAO;OAAe;MACxD;;;GAkBL,MAAM,EAAE,QAAQ,OAAO,aAAa,MAdZ,0BAA0B;IAChD,YAAY;IACZ;IACA,KAAK,OAAO,aAAa;KACvB,MAAM,EAAE,MAAM,UAAU,UAAU,MAAM,eAAe;MACrD;MACA,QAAQ;MACR,QAAQ,aAAa,KAAK,SAAS;OAAE,QAAQ,IAAI;OAAQ,UAAU,IAAI;OAAU,EAAE;MACnF,WAAW;MACZ,CAAC;AACF,YAAO;MAAE;MAAM;MAAU;MAAO;;IAEnC,CAAC;AAiBF,UAAO,yBAAyB;IAb9B,MAAM,MAAM;IACZ,UAAU,MAAM;IAChB,OAAO,MAAM;IACb;IAUoC,EANpC,aAAa,WAAW,IACpB,EAAE,OAAO,aAAa,GAAG,eAAe,GACxC,EACE,QAAQ,aAAa,KAAK,SAAS,EAAE,OAAO,IAAI,eAAe,EAAE,EAClE,CAE8C;;EAExD"}
|
|
1
|
+
{"version":3,"file":"image-tool.js","names":[],"sources":["../../../../src/agent/tools/image-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport { describeImages } from '../image/understanding/runtime.js';\nimport { buildImageToolTextResult, resolvePromptAndModelOverride } from '../image/image-helpers.js';\nimport { runWithImageModelFallback } from '../image/image-model-fallback.js';\nimport { loadImageForToolInput } from '../image/load-image-media.js';\nimport { resolveImageModelConfigForTool } from '../image/tool-model-config.js';\n\nconst DEFAULT_PROMPT = 'Describe the image.';\nconst DEFAULT_MAX_IMAGES = 20;\n\nexport { resolveImageModelConfigForTool } from '../image/tool-model-config.js';\n\nfunction pickMaxBytes(cfg?: Config, maxBytesMb?: number): number {\n if (typeof maxBytesMb === 'number' && Number.isFinite(maxBytesMb) && maxBytesMb > 0) {\n return Math.floor(maxBytesMb * 1024 * 1024);\n }\n return 20 * 1024 * 1024;\n}\n\nexport function createImageTool(options: {\n config?: Config;\n workspace: string;\n /** When true, session model already receives images in the user message. */\n modelHasVision?: boolean;\n}): AgentTool<any, Record<string, unknown>> | null {\n const imageModelConfig = resolveImageModelConfigForTool({ cfg: options.config });\n if (!imageModelConfig) {\n return null;\n }\n\n const description = options.modelHasVision\n ? 'Analyze one or more images with a vision model. Use `image` for a single path/URL, or `images` for multiple (up to 20). Only use when images were NOT already in the user message.'\n : 'Analyze one or more images using the available image model. Use `image` or `images` for paths/URLs; optional `prompt` for what to extract.';\n\n const localRoots = [options.workspace];\n\n return {\n name: 'image',\n label: 'Image',\n description,\n parameters: Type.Object({\n prompt: Type.Optional(Type.String()),\n image: Type.Optional(Type.String({ description: 'Single image path or URL.' })),\n images: Type.Optional(\n Type.Array(Type.String(), {\n description: 'Multiple image paths or URLs (up to maxImages, default 20).',\n }),\n ),\n model: Type.Optional(Type.String({ description: 'Optional provider/model override.' })),\n maxBytesMb: Type.Optional(Type.Number()),\n maxImages: Type.Optional(Type.Number()),\n }),\n async execute(\n _toolCallId: string,\n args: Record<string, unknown>,\n ): Promise<AgentToolResult<Record<string, unknown>>> {\n const record = args && typeof args === 'object' ? args : {};\n\n const imageCandidates: string[] = [];\n if (typeof record.image === 'string') {\n imageCandidates.push(record.image);\n }\n if (Array.isArray(record.images)) {\n imageCandidates.push(...record.images.filter((v): v is string => typeof v === 'string'));\n }\n\n const seenImages = new Set<string>();\n const imageInputs: string[] = [];\n for (const candidate of imageCandidates) {\n const trimmedCandidate = candidate.trim();\n const normalizedForDedupe = trimmedCandidate.startsWith('@')\n ? trimmedCandidate.slice(1).trim()\n : trimmedCandidate;\n if (!normalizedForDedupe || seenImages.has(normalizedForDedupe)) {\n continue;\n }\n seenImages.add(normalizedForDedupe);\n imageInputs.push(trimmedCandidate);\n }\n\n if (imageInputs.length === 0) {\n return {\n content: [{ type: 'text', text: 'Error: provide `image` or `images`.' }],\n details: { error: 'missing_image' },\n };\n }\n\n const maxImagesRaw = typeof record.maxImages === 'number' ? record.maxImages : undefined;\n const maxImages =\n typeof maxImagesRaw === 'number' && Number.isFinite(maxImagesRaw) && maxImagesRaw > 0\n ? Math.floor(maxImagesRaw)\n : DEFAULT_MAX_IMAGES;\n if (imageInputs.length > maxImages) {\n return {\n content: [\n {\n type: 'text',\n text: `Too many images: ${imageInputs.length} (max ${maxImages}).`,\n },\n ],\n details: { error: 'too_many_images', count: imageInputs.length, max: maxImages },\n };\n }\n\n const { prompt: promptRaw, modelOverride } = resolvePromptAndModelOverride(\n record,\n DEFAULT_PROMPT,\n );\n const maxBytesMb = typeof record.maxBytesMb === 'number' ? record.maxBytesMb : undefined;\n const maxBytes = pickMaxBytes(options.config, maxBytesMb);\n\n const loadedImages: Array<{ buffer: Buffer; mimeType: string; resolvedImage: string }> = [];\n\n for (const imageRawInput of imageInputs) {\n const trimmed = imageRawInput.trim();\n const imageRaw = trimmed.startsWith('@') ? trimmed.slice(1).trim() : trimmed;\n if (!imageRaw) {\n return {\n content: [{ type: 'text', text: 'Error: empty image entry.' }],\n details: { error: 'empty_image' },\n };\n }\n\n const looksLikeWindowsDrivePath = /^[a-zA-Z]:[\\\\/]/.test(imageRaw);\n const hasScheme = /^[a-z][a-z0-9+.-]*:/i.test(imageRaw);\n const isFileUrl = /^file:/i.test(imageRaw);\n const isHttpUrl = /^https?:\\/\\//i.test(imageRaw);\n const isDataUrl = /^data:/i.test(imageRaw);\n if (hasScheme && !looksLikeWindowsDrivePath && !isFileUrl && !isHttpUrl && !isDataUrl) {\n return {\n content: [\n {\n type: 'text',\n text: `Unsupported image reference: ${imageRawInput}. Use a path, file://, data:, or http(s) URL.`,\n },\n ],\n details: { error: 'unsupported_image_reference', image: imageRawInput },\n };\n }\n\n try {\n const media = await loadImageForToolInput(imageRaw, {\n maxBytes,\n workspace: options.workspace,\n localRoots,\n });\n loadedImages.push({\n buffer: media.buffer,\n mimeType: media.mimeType,\n resolvedImage: imageRaw,\n });\n } catch (e) {\n return {\n content: [\n {\n type: 'text',\n text: `Failed to load image (${imageRawInput}): ${e instanceof Error ? e.message : String(e)}`,\n },\n ],\n details: { error: 'load_failed', image: imageRawInput },\n };\n }\n }\n\n const runResult = await runWithImageModelFallback({\n toolConfig: imageModelConfig,\n modelOverride,\n run: async (modelRef) => {\n const { text, provider, model } = await describeImages({\n modelRef,\n prompt: promptRaw,\n images: loadedImages.map((img) => ({ buffer: img.buffer, mimeType: img.mimeType })),\n timeoutMs: 60_000,\n });\n return { text, provider, model };\n },\n });\n\n const { result: inner, attempts } = runResult;\n const result = {\n text: inner.text,\n provider: inner.provider,\n model: inner.model,\n attempts,\n };\n\n const imageDetails =\n loadedImages.length === 1\n ? { image: loadedImages[0].resolvedImage }\n : {\n images: loadedImages.map((img) => ({ image: img.resolvedImage })),\n };\n\n return buildImageToolTextResult(result, imageDetails);\n },\n } as any;\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
|
+
import type { MemoryManager } from '../memory/manager.js';
|
|
2
3
|
export interface MemoryToolOptions {
|
|
3
4
|
workspaceDir: string;
|
|
4
|
-
|
|
5
|
-
memoriesDir?: string;
|
|
5
|
+
getMemoryManager: () => MemoryManager;
|
|
6
6
|
}
|
|
7
7
|
export declare function createMemorySearchTool(options: MemoryToolOptions): AgentTool;
|
|
8
8
|
export declare function createMemoryGetTool(options: MemoryToolOptions): AgentTool;
|