@xopcai/xopc 0.0.88 → 0.0.89
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 +8 -1
- package/README.zh-CN.md +8 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/agents-B6PJB07W.js +222 -0
- package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-DIsl75Y3.js → channels-status-swr-DaHGkRF1.js} +1 -1
- package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +1 -0
- package/dist/gateway/static/root/assets/{dist-CJwfHYvT.js → dist-6LecgDx5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BVJohZoZ.js → extension-debug-page-CtuKJ9tE.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BT2tmElC.js → extension-page-ykzjOkR5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BSS47c2j.js → extension-settings-page-Ce2qrdpO.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-BaFNUtkE.js → fetch-C9FFJjuH.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-QwYEq6Hz.js → field-primitives-BFcrNeTU.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-BVSidEDJ.js → heartbeat-config-api-CEg4Vr9R.js} +1 -1
- package/dist/gateway/static/root/assets/{index-qNrVJp-y.js → index-CZfy9oxs.js} +97 -97
- package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +1 -0
- package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-B8N3A3Zo.js → settings-form-section-BqdzA28u.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Q7KqkO-u.js → share-preview-page-Di5Bzh4g.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-BbRc5ugR.js → theme-store-CNqbmTNV.js} +1 -1
- package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +7 -0
- package/dist/gateway/static/root/assets/{utils-CxDGduqK.js → utils-BWm2tG2w.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CTyHz7L_.js → voice-api-key-field-X2UfnHeq.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +27 -0
- package/dist/gateway/static/root/index.html +5 -6
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +8 -7
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +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/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service.js +6 -5
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +3 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/cronjob-tool.js +2 -1
- package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +3 -0
- package/dist/src/agent/tools/factory.js +3 -24
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
- package/dist/src/agent/tools/workflow-tool.js +61 -261
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
- package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
- package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
- package/dist/src/auth/credentials.d.ts +14 -2
- package/dist/src/auth/credentials.js +40 -15
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/oauth/types.d.ts +16 -0
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/auth.js +6 -0
- package/dist/src/cli/commands/auth.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/onboard/model.js +6 -0
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.d.ts +2 -0
- package/dist/src/cron/executor.js +61 -7
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/job-content.js +2 -1
- package/dist/src/cron/job-content.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/cron/types.d.ts +21 -1
- package/dist/src/cron/validation.d.ts +76 -0
- package/dist/src/cron/validation.js +26 -1
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/gateway/agents-admin.js +3 -3
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
- package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth-async.js +40 -15
- package/dist/src/gateway/hono/oauth-async.js.map +1 -1
- package/dist/src/gateway/hono/oauth.js +31 -6
- package/dist/src/gateway/hono/oauth.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/models.js +12 -6
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +69 -190
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +4 -4
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service.d.ts +5 -0
- package/dist/src/gateway/service.js +23 -3
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.d.ts +8 -0
- package/dist/src/providers/index.js +53 -14
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/resolve-session.js +4 -4
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +5 -5
- 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-config.d.ts +3 -2
- package/dist/src/share/site-share-config.js.map +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/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/domain/command.d.ts +2 -1
- package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
- package/dist/src/workflows/domain/definition-utils.js +50 -0
- package/dist/src/workflows/domain/definition-utils.js.map +1 -0
- package/dist/src/workflows/domain/index.d.ts +2 -0
- package/dist/src/workflows/domain/index.js +3 -1
- package/dist/src/workflows/domain/run.d.ts +57 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/domain/validation.d.ts +19 -0
- package/dist/src/workflows/domain/validation.js +66 -0
- package/dist/src/workflows/domain/validation.js.map +1 -0
- package/dist/src/workflows/engine/workflow-engine.d.ts +2 -1
- package/dist/src/workflows/engine/workflow-engine.js +1 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.d.ts +4 -0
- package/dist/src/workflows/index.js +9 -2
- package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js +61 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
- package/dist/src/workflows/service/workflow-run-service.d.ts +36 -0
- package/dist/src/workflows/service/workflow-run-service.js +279 -0
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
- package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
- package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
- package/dist/src/workflows/service/workflow-session-key.js +21 -0
- package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +2 -1
- package/dist/src/workflows/store/run-store.js.map +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-CRxETUZx.js +0 -222
- package/dist/gateway/static/root/assets/apps-page-wKWf3l57.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +0 -1
- package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-N9hvuRrn.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-tlNGNxhP.js +0 -1
- package/dist/gateway/static/root/assets/index-CqZzHNEg.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-DDonPVLn.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +0 -2
- package/dist/gateway/static/root/assets/url-D6jvVYIA.js +0 -7
- package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +0 -27
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
2
1
|
import { init_paths, resolveSkillsLockPath } from "../../config/paths.js";
|
|
2
|
+
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
//#region src/agent/skills/hub-lock.ts
|
|
5
5
|
/**
|
|
@@ -4,9 +4,9 @@ import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
|
|
|
4
4
|
import { getSkillsLockEntry, recordSkillsHubInstall } from "./hub-lock.js";
|
|
5
5
|
import { installSkillFromZip, isValidSkillId } from "./managed-store.js";
|
|
6
6
|
import { computeSkillTreeHashSync } from "./hub-hash.js";
|
|
7
|
-
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
|
-
import { basename, join, normalize, resolve, sep } from "node:path";
|
|
9
7
|
import { tmpdir } from "node:os";
|
|
8
|
+
import { basename, join, normalize, resolve, sep } from "node:path";
|
|
9
|
+
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { execFileSync } from "node:child_process";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { fetch } from "undici";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { resolveStateDir } from "../../config/paths-state.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { resolveStateDir } from "../../config/paths-state.js";
|
|
4
4
|
import { init_paths } from "../../config/paths.js";
|
|
5
5
|
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
6
6
|
import { findInstallSpec, getDefaultInstallerPreferences, hasBinary, init_installer, installSkill } from "./installer.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { init_paths, resolveSkillsDir } from "../../config/paths.js";
|
|
2
2
|
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
3
3
|
import { loadSkillsLock } from "./hub-lock.js";
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
5
4
|
import { dirname, join, resolve, sep } from "node:path";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
import AdmZip from "adm-zip";
|
|
7
7
|
//#region src/agent/skills/managed-store.ts
|
|
8
8
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { readFile, readdir } from "fs/promises";
|
|
4
3
|
import { join } from "path";
|
|
4
|
+
import { readFile, readdir } from "fs/promises";
|
|
5
5
|
//#region src/agent/skills/scanner.ts
|
|
6
6
|
/**
|
|
7
7
|
* Skill security scanner — scans skill directories for potentially dangerous code patterns.
|
|
@@ -2,9 +2,9 @@ import { init_paths, resolveSkillsDir } from "../../config/paths.js";
|
|
|
2
2
|
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
3
3
|
import { fuzzyFindText, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings } from "../tools/edit-diff.js";
|
|
4
4
|
import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
|
|
5
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
6
5
|
import { join, resolve, sep } from "path";
|
|
7
6
|
import { existsSync, realpathSync } from "fs";
|
|
7
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
8
8
|
//#region src/agent/skills/skill-manage-ops.ts
|
|
9
9
|
/**
|
|
10
10
|
* Shared logic for the skill_manage agent tool (create / edit / patch / delete / write_file / remove_file).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { resolveStateDir } from "../../config/paths-state.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { resolveStateDir } from "../../config/paths-state.js";
|
|
4
4
|
import { init_paths, resolveBundledSkillsDir } from "../../config/paths.js";
|
|
5
5
|
import { createSkillConfigManager, isSkillEnabled } from "./config.js";
|
|
6
6
|
import { formatSkillsForPrompt, selectSkillsVisibleInPrompt } from "./format-skills-prompt.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCronPayloadText } from "../../cron/job-content.js";
|
|
1
2
|
import { Type } from "@sinclair/typebox";
|
|
2
3
|
//#region src/agent/tools/cronjob-tool.ts
|
|
3
4
|
const CRON_THREAT_PATTERNS = [
|
|
@@ -42,7 +43,7 @@ function textResult(text) {
|
|
|
42
43
|
}
|
|
43
44
|
function formatJob(job) {
|
|
44
45
|
const status = job.enabled ? "▶️ active" : "⏸️ disabled";
|
|
45
|
-
const payloadText = job
|
|
46
|
+
const payloadText = getCronPayloadText(job);
|
|
46
47
|
const truncatedPayload = payloadText.length > 100 ? `${payloadText.slice(0, 100)}...` : payloadText;
|
|
47
48
|
return [
|
|
48
49
|
`${status} ${job.name ?? "(unnamed)"} (${job.id})`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cronjob-tool.js","names":[],"sources":["../../../../src/agent/tools/cronjob-tool.ts"],"sourcesContent":["// Agent tool for managing scheduled cron jobs (CronService-backed)\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\n\nimport type { CronService } from '../../cron/index.js';\nimport type { CronPayload, JobData, JobExecution, JobWithNextRun } from '../../cron/types.js';\n\nconst CRON_THREAT_PATTERNS: Array<[RegExp, string]> = [\n [/ignore\\s+(previous|all|above)\\s+instructions/i, 'prompt_injection'],\n [/do\\s+not\\s+tell\\s+the\\s+user/i, 'deception'],\n [/system\\s+prompt\\s+override/i, 'sys_prompt_override'],\n [/curl\\s+[^\\n]*\\$\\{?\\w*(KEY|TOKEN|SECRET|PASSWORD)/i, 'exfil_curl'],\n [/cat\\s+[^\\n]*(\\.env|credentials|\\.netrc)/i, 'read_secrets'],\n [/rm\\s+-rf\\s+\\//i, 'destructive_rm'],\n];\n\nexport function scanCronPrompt(prompt: string): string | null {\n for (const [pattern, id] of CRON_THREAT_PATTERNS) {\n if (pattern.test(prompt)) {\n return (\n `Blocked: prompt matches threat pattern '${id}'. ` +\n 'Cron prompts must not contain injection or exfiltration payloads.'\n );\n }\n }\n return null;\n}\n\nconst CronjobSchema = Type.Object({\n action: Type.Union(\n [\n Type.Literal('list'),\n Type.Literal('create'),\n Type.Literal('update'),\n Type.Literal('remove'),\n Type.Literal('enable'),\n Type.Literal('disable'),\n Type.Literal('history'),\n ],\n { description: 'Action to perform on cron jobs' },\n ),\n\n name: Type.Optional(Type.String({ description: 'Human-readable job name' })),\n schedule: Type.Optional(\n Type.String({\n description:\n 'Cron schedule expression. Examples:\\n' +\n ' \"0 9 * * *\" = every day at 9:00 AM\\n' +\n ' \"*/30 * * * *\" = every 30 minutes\\n' +\n ' \"0 9 * * 1-5\" = weekdays at 9:00 AM\\n' +\n ' \"0 0 1 * *\" = first day of each month',\n }),\n ),\n message: Type.Optional(\n Type.String({\n description:\n 'Instruction for the agent when the job runs (agentTurn payload; typically a fresh session).',\n }),\n ),\n timezone: Type.Optional(\n Type.String({\n description:\n 'IANA timezone (e.g. Asia/Shanghai, America/New_York). Must be one supported by the cron store.',\n }),\n ),\n sessionTarget: Type.Optional(\n Type.Union([Type.Literal('main'), Type.Literal('isolated')], {\n description:\n '\"main\" uses the main session context; \"isolated\" (default on create) uses a separate session per run.',\n }),\n ),\n agentId: Type.Optional(\n Type.String({\n description:\n 'Agent profile id for isolated jobs (session key). Omit to use the configured default agent (usually `main`).',\n }),\n ),\n workingDirectory: Type.Optional(\n Type.String({\n description:\n 'Absolute workspace path on the gateway host for isolated jobs. Omit to use the agent default workspace.',\n }),\n ),\n\n jobId: Type.Optional(Type.String({ description: 'Job ID (from list output)' })),\n});\n\nexport type CronjobToolParams = {\n action: 'list' | 'create' | 'update' | 'remove' | 'enable' | 'disable' | 'history';\n name?: string;\n schedule?: string;\n message?: string;\n timezone?: string;\n sessionTarget?: 'main' | 'isolated';\n agentId?: string;\n workingDirectory?: string;\n jobId?: string;\n};\n\nexport interface CronjobToolDeps {\n getCronService: () => CronService | undefined;\n}\n\nfunction textResult(text: string): AgentToolResult<{}> {\n return { content: [{ type: 'text', text }], details: {} };\n}\n\nfunction formatJob(job: JobWithNextRun): string {\n const status = job.enabled ? '▶️ active' : '⏸️ disabled';\n const payloadText =\n job.payload.kind === 'agentTurn' ? job.payload.message : job.payload.text;\n const truncatedPayload =\n payloadText.length > 100 ? `${payloadText.slice(0, 100)}...` : payloadText;\n\n return [\n `${status} ${job.name ?? '(unnamed)'} (${job.id})`,\n ` Schedule: ${job.schedule}${job.timezone ? ` (${job.timezone})` : ''}`,\n ` Type: ${job.payload.kind}`,\n ` Message: ${truncatedPayload}`,\n ` Next run: ${job.next_run ?? 'N/A'}`,\n ` Session: ${job.sessionTarget ?? 'main'}`,\n ` Agent: ${job.agentId?.trim() || '(default)'}`,\n ` Workspace: ${job.workingDirectory?.trim() || '(agent default)'}`,\n ].join('\\n');\n}\n\nfunction formatExecution(exec: JobExecution): string {\n const dur = exec.duration != null ? `${(exec.duration / 1000).toFixed(1)}s` : 'N/A';\n const lines = [`[${exec.status}] ${exec.startedAt} (${dur})`];\n if (exec.summary) {\n lines.push(` Summary: ${exec.summary.slice(0, 200)}`);\n }\n if (exec.error) {\n lines.push(` Error: ${exec.error.slice(0, 200)}`);\n }\n return lines.join('\\n');\n}\n\nexport function createCronjobTool(deps: CronjobToolDeps): AgentTool {\n return {\n name: 'cronjob',\n label: '⏰ Cronjob',\n description:\n 'Manage scheduled tasks (cron jobs) that run automatically.\\n\\n' +\n 'Each job has a cron schedule and a message the agent runs when triggered (agent turn).\\n\\n' +\n 'ACTIONS:\\n' +\n '- list: Show all scheduled jobs with status and next run time\\n' +\n '- create: Create a job (requires schedule and message; optional name, timezone, sessionTarget, agentId, workingDirectory)\\n' +\n '- update: Change schedule, message, name, timezone, sessionTarget, agentId, or workingDirectory (requires jobId)\\n' +\n '- remove: Delete a job (requires jobId)\\n' +\n '- enable / disable: Toggle a job (requires jobId)\\n' +\n '- history: Recent executions for a job (requires jobId)',\n parameters: CronjobSchema,\n\n async execute(_toolCallId, params: CronjobToolParams, _signal) {\n const cron = deps.getCronService();\n if (!cron) {\n return textResult('Cron service is not available in this environment.');\n }\n\n try {\n switch (params.action) {\n case 'list': {\n const jobs = await cron.listJobs();\n if (jobs.length === 0) {\n return textResult('No scheduled jobs.');\n }\n const formatted = jobs.map(formatJob).join('\\n\\n');\n return { content: [{ type: 'text', text: formatted }], details: {} };\n }\n\n case 'create': {\n if (!params.schedule?.trim() || !params.message?.trim()) {\n return textResult('Error: create requires schedule and message.');\n }\n\n const scanResult = scanCronPrompt(params.message);\n if (scanResult) {\n return textResult(`Error: ${scanResult}`);\n }\n\n const payload: CronPayload = {\n kind: 'agentTurn',\n message: params.message.trim(),\n };\n\n const result = await cron.addJob(params.schedule.trim(), {\n name: params.name?.trim() || undefined,\n timezone: params.timezone?.trim() || undefined,\n sessionTarget: params.sessionTarget ?? 'isolated',\n ...(params.agentId?.trim() ? { agentId: params.agentId.trim() } : {}),\n ...(params.workingDirectory?.trim()\n ? { workingDirectory: params.workingDirectory.trim() }\n : {}),\n payload,\n });\n\n return textResult(\n `Created job${params.name ? ` \"${params.name.trim()}\"` : ''} (${result.id})\\n` +\n `Schedule: ${result.schedule}`,\n );\n }\n\n case 'update': {\n if (!params.jobId?.trim()) {\n return textResult('Error: update requires jobId.');\n }\n\n const updates: Partial<Omit<JobData, 'id' | 'created_at' | 'updated_at'>> = {};\n if (params.schedule?.trim()) {\n updates.schedule = params.schedule.trim();\n }\n if (params.message != null && params.message.trim()) {\n const scanResult = scanCronPrompt(params.message);\n if (scanResult) {\n return textResult(`Error: ${scanResult}`);\n }\n updates.payload = { kind: 'agentTurn', message: params.message.trim() };\n }\n if (params.timezone?.trim()) {\n updates.timezone = params.timezone.trim();\n }\n if (params.name !== undefined) {\n updates.name = params.name.trim() || undefined;\n }\n if (params.sessionTarget !== undefined) {\n updates.sessionTarget = params.sessionTarget;\n }\n if (params.agentId !== undefined) {\n const t = params.agentId.trim();\n updates.agentId = t || null;\n }\n if (params.workingDirectory !== undefined) {\n const t = params.workingDirectory.trim();\n updates.workingDirectory = t || null;\n }\n\n if (Object.keys(updates).length === 0) {\n return textResult(\n 'Error: update requires at least one of schedule, message, name, timezone, sessionTarget, agentId, workingDirectory.',\n );\n }\n\n const success = await cron.updateJob(params.jobId.trim(), updates);\n return textResult(\n success ? `Updated job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'remove': {\n if (!params.jobId?.trim()) {\n return textResult('Error: remove requires jobId.');\n }\n const removed = await cron.removeJob(params.jobId.trim());\n return textResult(\n removed ? `Removed job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'disable': {\n if (!params.jobId?.trim()) {\n return textResult('Error: disable requires jobId.');\n }\n const toggled = await cron.toggleJob(params.jobId.trim(), false);\n return textResult(\n toggled ? `Disabled job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'enable': {\n if (!params.jobId?.trim()) {\n return textResult('Error: enable requires jobId.');\n }\n const toggled = await cron.toggleJob(params.jobId.trim(), true);\n return textResult(\n toggled ? `Enabled job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'history': {\n if (!params.jobId?.trim()) {\n return textResult('Error: history requires jobId.');\n }\n const history = await cron.getJobHistory(params.jobId.trim(), 5);\n if (history.length === 0) {\n return textResult(`No execution history for job ${params.jobId.trim()}.`);\n }\n const formatted = history.map(formatExecution).join('\\n\\n');\n return textResult(formatted);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return textResult(`Error: ${message}`);\n }\n },\n } as any;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cronjob-tool.js","names":[],"sources":["../../../../src/agent/tools/cronjob-tool.ts"],"sourcesContent":["// Agent tool for managing scheduled cron jobs (CronService-backed)\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\n\nimport type { CronService } from '../../cron/index.js';\nimport { getCronPayloadText } from '../../cron/job-content.js';\nimport type { CronPayload, JobData, JobExecution, JobWithNextRun } from '../../cron/types.js';\n\nconst CRON_THREAT_PATTERNS: Array<[RegExp, string]> = [\n [/ignore\\s+(previous|all|above)\\s+instructions/i, 'prompt_injection'],\n [/do\\s+not\\s+tell\\s+the\\s+user/i, 'deception'],\n [/system\\s+prompt\\s+override/i, 'sys_prompt_override'],\n [/curl\\s+[^\\n]*\\$\\{?\\w*(KEY|TOKEN|SECRET|PASSWORD)/i, 'exfil_curl'],\n [/cat\\s+[^\\n]*(\\.env|credentials|\\.netrc)/i, 'read_secrets'],\n [/rm\\s+-rf\\s+\\//i, 'destructive_rm'],\n];\n\nexport function scanCronPrompt(prompt: string): string | null {\n for (const [pattern, id] of CRON_THREAT_PATTERNS) {\n if (pattern.test(prompt)) {\n return (\n `Blocked: prompt matches threat pattern '${id}'. ` +\n 'Cron prompts must not contain injection or exfiltration payloads.'\n );\n }\n }\n return null;\n}\n\nconst CronjobSchema = Type.Object({\n action: Type.Union(\n [\n Type.Literal('list'),\n Type.Literal('create'),\n Type.Literal('update'),\n Type.Literal('remove'),\n Type.Literal('enable'),\n Type.Literal('disable'),\n Type.Literal('history'),\n ],\n { description: 'Action to perform on cron jobs' },\n ),\n\n name: Type.Optional(Type.String({ description: 'Human-readable job name' })),\n schedule: Type.Optional(\n Type.String({\n description:\n 'Cron schedule expression. Examples:\\n' +\n ' \"0 9 * * *\" = every day at 9:00 AM\\n' +\n ' \"*/30 * * * *\" = every 30 minutes\\n' +\n ' \"0 9 * * 1-5\" = weekdays at 9:00 AM\\n' +\n ' \"0 0 1 * *\" = first day of each month',\n }),\n ),\n message: Type.Optional(\n Type.String({\n description:\n 'Instruction for the agent when the job runs (agentTurn payload; typically a fresh session).',\n }),\n ),\n timezone: Type.Optional(\n Type.String({\n description:\n 'IANA timezone (e.g. Asia/Shanghai, America/New_York). Must be one supported by the cron store.',\n }),\n ),\n sessionTarget: Type.Optional(\n Type.Union([Type.Literal('main'), Type.Literal('isolated')], {\n description:\n '\"main\" uses the main session context; \"isolated\" (default on create) uses a separate session per run.',\n }),\n ),\n agentId: Type.Optional(\n Type.String({\n description:\n 'Agent profile id for isolated jobs (session key). Omit to use the configured default agent (usually `main`).',\n }),\n ),\n workingDirectory: Type.Optional(\n Type.String({\n description:\n 'Absolute workspace path on the gateway host for isolated jobs. Omit to use the agent default workspace.',\n }),\n ),\n\n jobId: Type.Optional(Type.String({ description: 'Job ID (from list output)' })),\n});\n\nexport type CronjobToolParams = {\n action: 'list' | 'create' | 'update' | 'remove' | 'enable' | 'disable' | 'history';\n name?: string;\n schedule?: string;\n message?: string;\n timezone?: string;\n sessionTarget?: 'main' | 'isolated';\n agentId?: string;\n workingDirectory?: string;\n jobId?: string;\n};\n\nexport interface CronjobToolDeps {\n getCronService: () => CronService | undefined;\n}\n\nfunction textResult(text: string): AgentToolResult<{}> {\n return { content: [{ type: 'text', text }], details: {} };\n}\n\nfunction formatJob(job: JobWithNextRun): string {\n const status = job.enabled ? '▶️ active' : '⏸️ disabled';\n const payloadText = getCronPayloadText(job);\n const truncatedPayload =\n payloadText.length > 100 ? `${payloadText.slice(0, 100)}...` : payloadText;\n\n return [\n `${status} ${job.name ?? '(unnamed)'} (${job.id})`,\n ` Schedule: ${job.schedule}${job.timezone ? ` (${job.timezone})` : ''}`,\n ` Type: ${job.payload.kind}`,\n ` Message: ${truncatedPayload}`,\n ` Next run: ${job.next_run ?? 'N/A'}`,\n ` Session: ${job.sessionTarget ?? 'main'}`,\n ` Agent: ${job.agentId?.trim() || '(default)'}`,\n ` Workspace: ${job.workingDirectory?.trim() || '(agent default)'}`,\n ].join('\\n');\n}\n\nfunction formatExecution(exec: JobExecution): string {\n const dur = exec.duration != null ? `${(exec.duration / 1000).toFixed(1)}s` : 'N/A';\n const lines = [`[${exec.status}] ${exec.startedAt} (${dur})`];\n if (exec.summary) {\n lines.push(` Summary: ${exec.summary.slice(0, 200)}`);\n }\n if (exec.error) {\n lines.push(` Error: ${exec.error.slice(0, 200)}`);\n }\n return lines.join('\\n');\n}\n\nexport function createCronjobTool(deps: CronjobToolDeps): AgentTool {\n return {\n name: 'cronjob',\n label: '⏰ Cronjob',\n description:\n 'Manage scheduled tasks (cron jobs) that run automatically.\\n\\n' +\n 'Each job has a cron schedule and a message the agent runs when triggered (agent turn).\\n\\n' +\n 'ACTIONS:\\n' +\n '- list: Show all scheduled jobs with status and next run time\\n' +\n '- create: Create a job (requires schedule and message; optional name, timezone, sessionTarget, agentId, workingDirectory)\\n' +\n '- update: Change schedule, message, name, timezone, sessionTarget, agentId, or workingDirectory (requires jobId)\\n' +\n '- remove: Delete a job (requires jobId)\\n' +\n '- enable / disable: Toggle a job (requires jobId)\\n' +\n '- history: Recent executions for a job (requires jobId)',\n parameters: CronjobSchema,\n\n async execute(_toolCallId, params: CronjobToolParams, _signal) {\n const cron = deps.getCronService();\n if (!cron) {\n return textResult('Cron service is not available in this environment.');\n }\n\n try {\n switch (params.action) {\n case 'list': {\n const jobs = await cron.listJobs();\n if (jobs.length === 0) {\n return textResult('No scheduled jobs.');\n }\n const formatted = jobs.map(formatJob).join('\\n\\n');\n return { content: [{ type: 'text', text: formatted }], details: {} };\n }\n\n case 'create': {\n if (!params.schedule?.trim() || !params.message?.trim()) {\n return textResult('Error: create requires schedule and message.');\n }\n\n const scanResult = scanCronPrompt(params.message);\n if (scanResult) {\n return textResult(`Error: ${scanResult}`);\n }\n\n const payload: CronPayload = {\n kind: 'agentTurn',\n message: params.message.trim(),\n };\n\n const result = await cron.addJob(params.schedule.trim(), {\n name: params.name?.trim() || undefined,\n timezone: params.timezone?.trim() || undefined,\n sessionTarget: params.sessionTarget ?? 'isolated',\n ...(params.agentId?.trim() ? { agentId: params.agentId.trim() } : {}),\n ...(params.workingDirectory?.trim()\n ? { workingDirectory: params.workingDirectory.trim() }\n : {}),\n payload,\n });\n\n return textResult(\n `Created job${params.name ? ` \"${params.name.trim()}\"` : ''} (${result.id})\\n` +\n `Schedule: ${result.schedule}`,\n );\n }\n\n case 'update': {\n if (!params.jobId?.trim()) {\n return textResult('Error: update requires jobId.');\n }\n\n const updates: Partial<Omit<JobData, 'id' | 'created_at' | 'updated_at'>> = {};\n if (params.schedule?.trim()) {\n updates.schedule = params.schedule.trim();\n }\n if (params.message != null && params.message.trim()) {\n const scanResult = scanCronPrompt(params.message);\n if (scanResult) {\n return textResult(`Error: ${scanResult}`);\n }\n updates.payload = { kind: 'agentTurn', message: params.message.trim() };\n }\n if (params.timezone?.trim()) {\n updates.timezone = params.timezone.trim();\n }\n if (params.name !== undefined) {\n updates.name = params.name.trim() || undefined;\n }\n if (params.sessionTarget !== undefined) {\n updates.sessionTarget = params.sessionTarget;\n }\n if (params.agentId !== undefined) {\n const t = params.agentId.trim();\n updates.agentId = t || null;\n }\n if (params.workingDirectory !== undefined) {\n const t = params.workingDirectory.trim();\n updates.workingDirectory = t || null;\n }\n\n if (Object.keys(updates).length === 0) {\n return textResult(\n 'Error: update requires at least one of schedule, message, name, timezone, sessionTarget, agentId, workingDirectory.',\n );\n }\n\n const success = await cron.updateJob(params.jobId.trim(), updates);\n return textResult(\n success ? `Updated job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'remove': {\n if (!params.jobId?.trim()) {\n return textResult('Error: remove requires jobId.');\n }\n const removed = await cron.removeJob(params.jobId.trim());\n return textResult(\n removed ? `Removed job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'disable': {\n if (!params.jobId?.trim()) {\n return textResult('Error: disable requires jobId.');\n }\n const toggled = await cron.toggleJob(params.jobId.trim(), false);\n return textResult(\n toggled ? `Disabled job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'enable': {\n if (!params.jobId?.trim()) {\n return textResult('Error: enable requires jobId.');\n }\n const toggled = await cron.toggleJob(params.jobId.trim(), true);\n return textResult(\n toggled ? `Enabled job ${params.jobId.trim()}.` : `Job ${params.jobId.trim()} not found.`,\n );\n }\n\n case 'history': {\n if (!params.jobId?.trim()) {\n return textResult('Error: history requires jobId.');\n }\n const history = await cron.getJobHistory(params.jobId.trim(), 5);\n if (history.length === 0) {\n return textResult(`No execution history for job ${params.jobId.trim()}.`);\n }\n const formatted = history.map(formatExecution).join('\\n\\n');\n return textResult(formatted);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return textResult(`Error: ${message}`);\n }\n },\n } as any;\n}\n"],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
3
3
|
import { SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE } from "../memory/dreaming/constants.js";
|
|
4
4
|
import { loadDreamingStore, saveDreamingStore } from "../memory/dreaming/short-term-store.js";
|
|
5
5
|
import { resolveDreamingConfig } from "../memory/dreaming/config.js";
|
|
6
|
-
import fs from "node:fs/promises";
|
|
7
6
|
import path from "node:path";
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
8
|
import { Type } from "@sinclair/typebox";
|
|
9
9
|
//#region src/agent/tools/dreaming-tool.ts
|
|
10
10
|
init_logger();
|
|
@@ -15,6 +15,7 @@ import type { MemoryManager } from '../memory/manager.js';
|
|
|
15
15
|
import type { SessionStore } from '../../session/store.js';
|
|
16
16
|
import type { GatewayClarifyRequestFn } from './clarify-tool.js';
|
|
17
17
|
import type { CronService } from '../../cron/index.js';
|
|
18
|
+
import type { WorkflowRunServiceLike } from '../../workflows/service/workflow-run-service.types.js';
|
|
18
19
|
import type { SkillManager } from '../skills/skill-manager.js';
|
|
19
20
|
import { type ToolExecutorConfig } from './executor.js';
|
|
20
21
|
export interface ToolFactoryDeps {
|
|
@@ -44,6 +45,8 @@ export interface ToolFactoryDeps {
|
|
|
44
45
|
};
|
|
45
46
|
/** Gateway: enables the `cronjob` tool. */
|
|
46
47
|
getCronService?: () => CronService | undefined;
|
|
48
|
+
/** Gateway: starts persisted workflow runs (dedicated chat session per run). */
|
|
49
|
+
getWorkflowRunService?: () => WorkflowRunServiceLike | undefined;
|
|
47
50
|
/** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */
|
|
48
51
|
getSkillIndexingContext?: () => {
|
|
49
52
|
registeredToolNames: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
4
4
|
import { createReadFileTool } from "./read.js";
|
|
5
5
|
import { createWriteFileTool } from "./write.js";
|
|
6
6
|
import { createEditFileTool } from "./edit.js";
|
|
@@ -255,31 +255,10 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
255
255
|
}
|
|
256
256
|
})] : [],
|
|
257
257
|
...cfg?.agents?.defaults?.workflow?.enabled !== false && primary ? [createWorkflowTool({
|
|
258
|
-
workspace,
|
|
259
|
-
bus: this.deps.bus,
|
|
260
|
-
getConfig: () => this.deps.getConfig?.(),
|
|
261
258
|
catalog: createWorkflowCatalog(),
|
|
262
259
|
getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (!m) throw new Error("No primary model configured for workflow");
|
|
266
|
-
return m;
|
|
267
|
-
},
|
|
268
|
-
toolExecutorConfig: this.deps.toolExecutorConfig,
|
|
269
|
-
buildChildTools: (childOpts) => {
|
|
270
|
-
return new AgentToolsFactory({
|
|
271
|
-
workspace: childOpts.workspace,
|
|
272
|
-
bus: childOpts.bus,
|
|
273
|
-
getCurrentContext: () => null,
|
|
274
|
-
getConfig: childOpts.getConfig,
|
|
275
|
-
getPrimaryModel: () => childOpts.model,
|
|
276
|
-
toolExecutorConfig: childOpts.toolExecutorConfig
|
|
277
|
-
}).createAllTools({
|
|
278
|
-
workspace: childOpts.workspace,
|
|
279
|
-
getPrimaryModel: () => childOpts.model,
|
|
280
|
-
disabledTools: new Set(["extensions"])
|
|
281
|
-
});
|
|
282
|
-
}
|
|
260
|
+
getConfig: () => this.deps.getConfig?.(),
|
|
261
|
+
startWorkflowRun: this.deps.getWorkflowRunService ? (params) => this.deps.getWorkflowRunService().startWorkflowRun(params) : void 0
|
|
283
262
|
})] : [],
|
|
284
263
|
...cfg?.agents?.defaults?.delegate?.enabled === true && primary ? [createDelegateTool({
|
|
285
264
|
workspace,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","names":["parseRoutingSessionKey"],"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 createSendMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\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 { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.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 { 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';\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\nfunction clarifyTransportSource(sessionKey: string): string | undefined {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed) return parsed.source;\n // Fallback for simple `<channel>:<chatId>` keys used by webchat and CLI.\n const first = sessionKey.split(':').filter(Boolean)[0] ?? '';\n if (first === 'cli' || first === 'webchat') return first;\n return undefined;\n}\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 /** 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 imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const optionalTools = [imageTool, imageGenerateTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace);\n const editTool = createEditFileTool(workspace);\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 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 const source = clarifyTransportSource(ctx.sessionKey);\n if (!source || !CLARIFY_SUPPORTED_CHANNELS.has(source)) 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 }),\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 ...(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 ...(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 workspace,\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n catalog: createWorkflowCatalog(),\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\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 workflow');\n }\n return m;\n },\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `subagent-runner.ts` doesn't import `AgentToolsFactory`\n // (which would form the same cycle delegate-tool was carved out to avoid).\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 ...(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":["parseRoutingSessionKey"],"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 createSendMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\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 { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.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';\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\nfunction clarifyTransportSource(sessionKey: string): string | undefined {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed) return parsed.source;\n // Fallback for simple `<channel>:<chatId>` keys used by webchat and CLI.\n const first = sessionKey.split(':').filter(Boolean)[0] ?? '';\n if (first === 'cli' || first === 'webchat') return first;\n return undefined;\n}\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 imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const optionalTools = [imageTool, imageGenerateTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace);\n const editTool = createEditFileTool(workspace);\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 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 const source = clarifyTransportSource(ctx.sessionKey);\n if (!source || !CLARIFY_SUPPORTED_CHANNELS.has(source)) 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 }),\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 ...(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 ...(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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"}
|
|
@@ -4,9 +4,9 @@ import { isFailoverError } from "../failover-error.js";
|
|
|
4
4
|
import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
|
|
5
5
|
import { getImageGenerationProvider } from "../image/generation/provider-registry.js";
|
|
6
6
|
import { generateImage, listImageGenerationProvidersSummary } from "../image/generation/runtime.js";
|
|
7
|
+
import path from "node:path";
|
|
7
8
|
import { randomBytes } from "node:crypto";
|
|
8
9
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
9
|
-
import path from "node:path";
|
|
10
10
|
import { Type } from "@sinclair/typebox";
|
|
11
11
|
//#region src/agent/tools/image-generate-tool.ts
|
|
12
12
|
const DEFAULT_COUNT = 1;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { checkFileSafety } from "../prompt/safety.js";
|
|
2
2
|
import { resolvePathUnderWorkspace } from "./tool-paths.js";
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
4
3
|
import { basename } from "node:path";
|
|
4
|
+
import { readFile } from "fs/promises";
|
|
5
5
|
import { Type } from "@sinclair/typebox";
|
|
6
6
|
//#region src/agent/tools/send-media.ts
|
|
7
7
|
const SendMediaSchema = Type.Object({
|
|
@@ -2,9 +2,9 @@ import { resolveStateDir } from "../../config/paths-state.js";
|
|
|
2
2
|
import { init_paths } from "../../config/paths.js";
|
|
3
3
|
import { createSkillConfigManager } from "../skills/config.js";
|
|
4
4
|
import { applyPatchToContent, atomicWriteUtf8, effectiveAgentWritePolicy, ensureCategorySegment, isPathInsideDir, maxSkillMdChars, maxSupportFileBytes, mutatableSkillOrNull, resolveCreateSkillDir, scanSkillDirOrError, validateSkillMdContent, validateSkillNameSegment, validateSupportingRelativePath } from "../skills/skill-manage-ops.js";
|
|
5
|
-
import { readFile, rm } from "fs/promises";
|
|
6
5
|
import { join } from "path";
|
|
7
6
|
import { existsSync, rmSync } from "fs";
|
|
7
|
+
import { readFile, rm } from "fs/promises";
|
|
8
8
|
import { Type } from "@sinclair/typebox";
|
|
9
9
|
//#region src/agent/tools/skill-manage-tool.ts
|
|
10
10
|
init_paths();
|
|
@@ -1,41 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `workflow` —
|
|
3
|
-
*
|
|
4
|
-
* Shape mirrors `delegate-tool`: factory builds a closure over deps; `execute`
|
|
5
|
-
* parses the script, instantiates the {@link DelegateSubagentRunner}, drives the
|
|
6
|
-
* {@link runWorkflow} runtime, and pushes a live text snapshot through
|
|
7
|
-
* `onUpdate` for streaming UIs (TUI, gateway console).
|
|
8
|
-
*
|
|
9
|
-
* Why this lives in `src/agent/tools/` (not under `src/agent/workflow/`):
|
|
10
|
-
* the runtime is reusable infrastructure; the AgentTool wrapping is a
|
|
11
|
-
* presentation concern that depends on the AgentToolsFactory wiring. Keeping
|
|
12
|
-
* the wrapper here matches how `delegate-tool` and `execute-code-tool` are
|
|
13
|
-
* organised today.
|
|
2
|
+
* `workflow` — starts a persisted workflow run in a dedicated chat session.
|
|
14
3
|
*/
|
|
15
4
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
16
|
-
import type {
|
|
17
|
-
import type {
|
|
18
|
-
import type { MessageBus } from '../../infra/bus/index.js';
|
|
19
|
-
import type { BuildChildToolsOptions } from '../child-agent-factory.js';
|
|
20
|
-
import { type WorkflowCatalog } from '../workflow/index.js';
|
|
21
|
-
import type { ToolExecutorConfig } from './executor.js';
|
|
5
|
+
import type { WorkflowCatalog } from '../workflow/catalog.js';
|
|
6
|
+
import type { StartWorkflowRunServiceParams, WorkflowRunServiceResult } from '../../workflows/service/workflow-run-service.types.js';
|
|
22
7
|
export type WorkflowToolInput = {
|
|
23
8
|
name?: string;
|
|
24
9
|
script?: string;
|
|
25
10
|
args?: unknown;
|
|
11
|
+
goal?: string;
|
|
26
12
|
};
|
|
27
13
|
export interface WorkflowToolDeps {
|
|
28
|
-
workspace: string;
|
|
29
|
-
bus: MessageBus;
|
|
30
|
-
/** Returns the parent agent's primary model — subagents default to this. */
|
|
31
|
-
getSubagentModel: () => Model<Api>;
|
|
32
|
-
getConfig: () => Config | undefined;
|
|
33
|
-
/** Same injection point delegate-tool uses; supplied by AgentToolsFactory. */
|
|
34
|
-
buildChildTools: (opts: BuildChildToolsOptions) => AgentTool<any, any>[];
|
|
35
|
-
toolExecutorConfig?: Partial<ToolExecutorConfig>;
|
|
36
|
-
/** Catalog for `name` lookups (built-in + ~/.xopc/workflows/). */
|
|
37
14
|
catalog: WorkflowCatalog;
|
|
38
|
-
/** Per-call sessionKey lookup — used to record "last successful workflow" for /workflow save. */
|
|
39
15
|
getCurrentSessionKey?: () => string | undefined;
|
|
16
|
+
getConfig: () => import('../../config/schema.js').Config | undefined;
|
|
17
|
+
startWorkflowRun?: (params: StartWorkflowRunServiceParams) => Promise<WorkflowRunServiceResult>;
|
|
40
18
|
}
|
|
41
19
|
export declare function createWorkflowTool(deps: WorkflowToolDeps): AgentTool;
|