@hailer/mcp 1.2.1 → 2.0.0-beta.1
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/.claude/agents/agent-hailer-helper.md +118 -0
- package/.claude/commands/app-squad.md +16 -110
- package/.claude/commands/debug-squad.md +13 -290
- package/.claude/commands/publish.md +2 -2
- package/.claude/commands/review-squad.md +17 -139
- package/.claude/skills/create-and-publish-app/SKILL.md +95 -153
- package/.claude/skills/hailer-app-builder/SKILL.md +2 -2
- package/.claude/skills/hailer-ui-guide/SKILL.md +265 -0
- package/.env.example +50 -1
- package/CLAUDE.md +136 -10
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +3 -0
- package/dist/app.js.map +1 -1
- package/dist/bot/bot-manager.d.ts +9 -6
- package/dist/bot/bot-manager.d.ts.map +1 -1
- package/dist/bot/bot-manager.js +142 -31
- package/dist/bot/bot-manager.js.map +1 -1
- package/dist/bot/bot.d.ts +59 -16
- package/dist/bot/bot.d.ts.map +1 -1
- package/dist/bot/bot.js +889 -142
- package/dist/bot/bot.js.map +1 -1
- package/dist/bot/operation-logger.d.ts.map +1 -1
- package/dist/bot/operation-logger.js +24 -12
- package/dist/bot/operation-logger.js.map +1 -1
- package/dist/bot/services/bot-permissions.d.ts +2 -2
- package/dist/bot/services/bot-permissions.d.ts.map +1 -1
- package/dist/bot/services/bot-permissions.js +28 -9
- package/dist/bot/services/bot-permissions.js.map +1 -1
- package/dist/bot/services/conversation-manager.d.ts +23 -23
- package/dist/bot/services/conversation-manager.d.ts.map +1 -1
- package/dist/bot/services/conversation-manager.js +52 -49
- package/dist/bot/services/conversation-manager.js.map +1 -1
- package/dist/bot/services/helper-prompt.d.ts +8 -0
- package/dist/bot/services/helper-prompt.d.ts.map +1 -0
- package/dist/bot/services/helper-prompt.js +177 -0
- package/dist/bot/services/helper-prompt.js.map +1 -0
- package/dist/bot/services/message-classifier.d.ts +16 -16
- package/dist/bot/services/message-classifier.d.ts.map +1 -1
- package/dist/bot/services/message-classifier.js +55 -49
- package/dist/bot/services/message-classifier.js.map +1 -1
- package/dist/bot/services/message-formatter.d.ts +38 -38
- package/dist/bot/services/message-formatter.d.ts.map +1 -1
- package/dist/bot/services/message-formatter.js +81 -74
- package/dist/bot/services/message-formatter.js.map +1 -1
- package/dist/bot/services/permission-guard.d.ts.map +1 -1
- package/dist/bot/services/permission-guard.js +20 -10
- package/dist/bot/services/permission-guard.js.map +1 -1
- package/dist/bot/services/signal-router.d.ts.map +1 -1
- package/dist/bot/services/signal-router.js +11 -6
- package/dist/bot/services/signal-router.js.map +1 -1
- package/dist/bot/services/system-prompt.d.ts +14 -0
- package/dist/bot/services/system-prompt.d.ts.map +1 -1
- package/dist/bot/services/system-prompt.js +179 -4
- package/dist/bot/services/system-prompt.js.map +1 -1
- package/dist/bot/services/token-billing.d.ts +23 -23
- package/dist/bot/services/token-billing.d.ts.map +1 -1
- package/dist/bot/services/token-billing.js +51 -36
- package/dist/bot/services/token-billing.js.map +1 -1
- package/dist/bot/services/types.d.ts +3 -1
- package/dist/bot/services/types.d.ts.map +1 -1
- package/dist/bot/services/typing-indicator.d.ts +8 -8
- package/dist/bot/services/typing-indicator.d.ts.map +1 -1
- package/dist/bot/services/typing-indicator.js +12 -10
- package/dist/bot/services/typing-indicator.js.map +1 -1
- package/dist/bot/services/workspace-refresh.d.ts +3 -3
- package/dist/bot/services/workspace-refresh.d.ts.map +1 -1
- package/dist/bot/services/workspace-refresh.js +23 -13
- package/dist/bot/services/workspace-refresh.js.map +1 -1
- package/dist/bot/tool-executor.d.ts +10 -6
- package/dist/bot/tool-executor.d.ts.map +1 -1
- package/dist/bot/tool-executor.js +12 -6
- package/dist/bot/tool-executor.js.map +1 -1
- package/dist/bot/workspace-overview.d.ts.map +1 -1
- package/dist/bot/workspace-overview.js +6 -3
- package/dist/bot/workspace-overview.js.map +1 -1
- package/dist/bot-config/activity-error.d.ts +47 -0
- package/dist/bot-config/activity-error.d.ts.map +1 -0
- package/dist/bot-config/activity-error.js +67 -0
- package/dist/bot-config/activity-error.js.map +1 -0
- package/dist/bot-config/context.d.ts +4 -4
- package/dist/bot-config/context.d.ts.map +1 -1
- package/dist/bot-config/context.js +18 -14
- package/dist/bot-config/context.js.map +1 -1
- package/dist/bot-config/events.d.ts +45 -0
- package/dist/bot-config/events.d.ts.map +1 -0
- package/dist/bot-config/events.js +51 -0
- package/dist/bot-config/events.js.map +1 -0
- package/dist/bot-config/index.d.ts +3 -0
- package/dist/bot-config/index.d.ts.map +1 -1
- package/dist/bot-config/index.js +8 -1
- package/dist/bot-config/index.js.map +1 -1
- package/dist/bot-config/loader.d.ts +3 -0
- package/dist/bot-config/loader.d.ts.map +1 -1
- package/dist/bot-config/loader.js +45 -20
- package/dist/bot-config/loader.js.map +1 -1
- package/dist/bot-config/persistence.js.map +1 -1
- package/dist/bot-config/reconciler.d.ts +11 -0
- package/dist/bot-config/reconciler.d.ts.map +1 -0
- package/dist/bot-config/reconciler.js +121 -0
- package/dist/bot-config/reconciler.js.map +1 -0
- package/dist/bot-config/state.d.ts.map +1 -1
- package/dist/bot-config/state.js.map +1 -1
- package/dist/bot-config/types.d.ts +32 -0
- package/dist/bot-config/types.d.ts.map +1 -1
- package/dist/bot-config/webhooks.d.ts.map +1 -1
- package/dist/bot-config/webhooks.js.map +1 -1
- package/dist/bot-config/workflow-installer.d.ts +37 -0
- package/dist/bot-config/workflow-installer.d.ts.map +1 -0
- package/dist/bot-config/workflow-installer.js +346 -0
- package/dist/bot-config/workflow-installer.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +12 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +23 -19
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +65 -27
- package/dist/config.js.map +1 -1
- package/dist/core.d.ts +6 -4
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +11 -16
- package/dist/core.js.map +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +7 -4
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/request-logger.d.ts +19 -19
- package/dist/lib/request-logger.d.ts.map +1 -1
- package/dist/lib/request-logger.js +19 -19
- package/dist/lib/request-logger.js.map +1 -1
- package/dist/mcp/UserContextCache.d.ts +28 -22
- package/dist/mcp/UserContextCache.d.ts.map +1 -1
- package/dist/mcp/UserContextCache.js +23 -23
- package/dist/mcp/UserContextCache.js.map +1 -1
- package/dist/mcp/auth.js.map +1 -1
- package/dist/mcp/hailer-clients.d.ts +5 -4
- package/dist/mcp/hailer-clients.d.ts.map +1 -1
- package/dist/mcp/hailer-clients.js +61 -27
- package/dist/mcp/hailer-clients.js.map +1 -1
- package/dist/mcp/hailer-rpc.d.ts +40 -0
- package/dist/mcp/hailer-rpc.d.ts.map +1 -0
- package/dist/mcp/hailer-rpc.js +43 -0
- package/dist/mcp/hailer-rpc.js.map +1 -0
- package/dist/mcp/session-store.d.ts +16 -16
- package/dist/mcp/session-store.d.ts.map +1 -1
- package/dist/mcp/session-store.js +16 -16
- package/dist/mcp/session-store.js.map +1 -1
- package/dist/mcp/tool-profiles.d.ts +69 -0
- package/dist/mcp/tool-profiles.d.ts.map +1 -0
- package/dist/mcp/tool-profiles.js +176 -0
- package/dist/mcp/tool-profiles.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +16 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +91 -39
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/activity.d.ts.map +1 -1
- package/dist/mcp/tools/activity.js +398 -198
- package/dist/mcp/tools/activity.js.map +1 -1
- package/dist/mcp/tools/aliases.d.ts +11 -0
- package/dist/mcp/tools/aliases.d.ts.map +1 -0
- package/dist/mcp/tools/aliases.js +176 -0
- package/dist/mcp/tools/aliases.js.map +1 -0
- package/dist/mcp/tools/app-core.d.ts +6 -8
- package/dist/mcp/tools/app-core.d.ts.map +1 -1
- package/dist/mcp/tools/app-core.js +355 -254
- package/dist/mcp/tools/app-core.js.map +1 -1
- package/dist/mcp/tools/app-marketplace.d.ts +8 -16
- package/dist/mcp/tools/app-marketplace.d.ts.map +1 -1
- package/dist/mcp/tools/app-marketplace.js +604 -930
- package/dist/mcp/tools/app-marketplace.js.map +1 -1
- package/dist/mcp/tools/app.d.ts +4 -7
- package/dist/mcp/tools/app.d.ts.map +1 -1
- package/dist/mcp/tools/app.js +4 -7
- package/dist/mcp/tools/app.js.map +1 -1
- package/dist/mcp/tools/bot-self.d.ts +21 -0
- package/dist/mcp/tools/bot-self.d.ts.map +1 -0
- package/dist/mcp/tools/bot-self.js +174 -0
- package/dist/mcp/tools/bot-self.js.map +1 -0
- package/dist/mcp/tools/calendar.d.ts +21 -0
- package/dist/mcp/tools/calendar.d.ts.map +1 -0
- package/dist/mcp/tools/calendar.js +741 -0
- package/dist/mcp/tools/calendar.js.map +1 -0
- package/dist/mcp/tools/company.d.ts.map +1 -1
- package/dist/mcp/tools/company.js +2 -1
- package/dist/mcp/tools/company.js.map +1 -1
- package/dist/mcp/tools/date.js.map +1 -1
- package/dist/mcp/tools/discussion.d.ts +23 -3
- package/dist/mcp/tools/discussion.d.ts.map +1 -1
- package/dist/mcp/tools/discussion.js +417 -534
- package/dist/mcp/tools/discussion.js.map +1 -1
- package/dist/mcp/tools/file.d.ts.map +1 -1
- package/dist/mcp/tools/file.js +18 -16
- package/dist/mcp/tools/file.js.map +1 -1
- package/dist/mcp/tools/index.js +4 -4
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/insight.d.ts +7 -5
- package/dist/mcp/tools/insight.d.ts.map +1 -1
- package/dist/mcp/tools/insight.js +419 -477
- package/dist/mcp/tools/insight.js.map +1 -1
- package/dist/mcp/tools/user.d.ts.map +1 -1
- package/dist/mcp/tools/user.js +15 -13
- package/dist/mcp/tools/user.js.map +1 -1
- package/dist/mcp/tools/workflow-permissions.d.ts +2 -4
- package/dist/mcp/tools/workflow-permissions.d.ts.map +1 -1
- package/dist/mcp/tools/workflow-permissions.js +88 -97
- package/dist/mcp/tools/workflow-permissions.js.map +1 -1
- package/dist/mcp/tools/workflow.d.ts +2 -7
- package/dist/mcp/tools/workflow.d.ts.map +1 -1
- package/dist/mcp/tools/workflow.js +817 -850
- package/dist/mcp/tools/workflow.js.map +1 -1
- package/dist/mcp/utils/api-errors.d.ts.map +1 -1
- package/dist/mcp/utils/api-errors.js +2 -2
- package/dist/mcp/utils/api-errors.js.map +1 -1
- package/dist/mcp/utils/data-transformers.d.ts.map +1 -1
- package/dist/mcp/utils/data-transformers.js +8 -4
- package/dist/mcp/utils/data-transformers.js.map +1 -1
- package/dist/mcp/utils/file-upload.d.ts.map +1 -1
- package/dist/mcp/utils/file-upload.js +1 -1
- package/dist/mcp/utils/file-upload.js.map +1 -1
- package/dist/mcp/utils/hailer-api-client.d.ts +81 -81
- package/dist/mcp/utils/hailer-api-client.d.ts.map +1 -1
- package/dist/mcp/utils/hailer-api-client.js +103 -101
- package/dist/mcp/utils/hailer-api-client.js.map +1 -1
- package/dist/mcp/utils/index.d.ts.map +1 -1
- package/dist/mcp/utils/index.js.map +1 -1
- package/dist/mcp/utils/logger.d.ts.map +1 -1
- package/dist/mcp/utils/logger.js.map +1 -1
- package/dist/mcp/utils/response-builder.d.ts.map +1 -1
- package/dist/mcp/utils/response-builder.js +8 -4
- package/dist/mcp/utils/response-builder.js.map +1 -1
- package/dist/mcp/utils/role-utils.d.ts.map +1 -1
- package/dist/mcp/utils/role-utils.js +6 -3
- package/dist/mcp/utils/role-utils.js.map +1 -1
- package/dist/mcp/utils/tool-helpers.d.ts.map +1 -1
- package/dist/mcp/utils/tool-helpers.js +2 -2
- package/dist/mcp/utils/tool-helpers.js.map +1 -1
- package/dist/mcp/utils/types.d.ts +1 -1
- package/dist/mcp/utils/types.d.ts.map +1 -1
- package/dist/mcp/utils/types.js.map +1 -1
- package/dist/mcp/webhook-handler.d.ts +43 -8
- package/dist/mcp/webhook-handler.d.ts.map +1 -1
- package/dist/mcp/webhook-handler.js +861 -116
- package/dist/mcp/webhook-handler.js.map +1 -1
- package/dist/mcp/workspace-admin-store.d.ts +49 -0
- package/dist/mcp/workspace-admin-store.d.ts.map +1 -0
- package/dist/mcp/workspace-admin-store.js +168 -0
- package/dist/mcp/workspace-admin-store.js.map +1 -0
- package/dist/mcp/workspace-cache.d.ts +2 -2
- package/dist/mcp/workspace-cache.d.ts.map +1 -1
- package/dist/mcp/workspace-cache.js +9 -5
- package/dist/mcp/workspace-cache.js.map +1 -1
- package/dist/mcp-server.d.ts +26 -11
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +360 -36
- package/dist/mcp-server.js.map +1 -1
- package/dist/plugins/vipunen/client.d.ts +41 -41
- package/dist/plugins/vipunen/client.d.ts.map +1 -1
- package/dist/plugins/vipunen/client.js +53 -48
- package/dist/plugins/vipunen/client.js.map +1 -1
- package/dist/plugins/vipunen/index.js.map +1 -1
- package/dist/plugins/vipunen/tools.d.ts.map +1 -1
- package/dist/plugins/vipunen/tools.js +6 -3
- package/dist/plugins/vipunen/tools.js.map +1 -1
- package/dist/public-chat/graduate.d.ts +29 -0
- package/dist/public-chat/graduate.d.ts.map +1 -0
- package/dist/public-chat/graduate.js +593 -0
- package/dist/public-chat/graduate.js.map +1 -0
- package/dist/public-chat/handler.d.ts +12 -0
- package/dist/public-chat/handler.d.ts.map +1 -0
- package/dist/public-chat/handler.js +179 -0
- package/dist/public-chat/handler.js.map +1 -0
- package/dist/public-chat/index.d.ts +16 -0
- package/dist/public-chat/index.d.ts.map +1 -0
- package/dist/public-chat/index.js +74 -0
- package/dist/public-chat/index.js.map +1 -0
- package/dist/public-chat/knowledge.d.ts +3 -0
- package/dist/public-chat/knowledge.d.ts.map +1 -0
- package/dist/public-chat/knowledge.js +1339 -0
- package/dist/public-chat/knowledge.js.map +1 -0
- package/dist/public-chat/rate-limit.d.ts +16 -0
- package/dist/public-chat/rate-limit.d.ts.map +1 -0
- package/dist/public-chat/rate-limit.js +51 -0
- package/dist/public-chat/rate-limit.js.map +1 -0
- package/dist/public-chat/session-store.d.ts +41 -0
- package/dist/public-chat/session-store.d.ts.map +1 -0
- package/dist/public-chat/session-store.js +95 -0
- package/dist/public-chat/session-store.js.map +1 -0
- package/dist/public-chat/studio-prewarm.d.ts +61 -0
- package/dist/public-chat/studio-prewarm.d.ts.map +1 -0
- package/dist/public-chat/studio-prewarm.js +162 -0
- package/dist/public-chat/studio-prewarm.js.map +1 -0
- package/dist/public-chat/system-prompt.d.ts +22 -0
- package/dist/public-chat/system-prompt.d.ts.map +1 -0
- package/dist/public-chat/system-prompt.js +428 -0
- package/dist/public-chat/system-prompt.js.map +1 -0
- package/package.json +14 -6
- package/scripts/build-public-chat-knowledge.py +101 -0
- package/scripts/probe-mcp-pricing.ts +52 -0
- package/scripts/smoke-public-chat-live.ts +148 -0
- package/scripts/smoke-public-chat.ts +110 -0
- package/.claude/CLAUDE.md +0 -126
- package/.claude/commands/audit-squad.md +0 -158
- package/.claude/commands/cleanup-squad.md +0 -98
- package/.claude/commands/config-squad.md +0 -106
- package/.claude/commands/crud-squad.md +0 -87
- package/.claude/commands/data-squad.md +0 -97
- package/.claude/commands/doc-squad.md +0 -65
- package/.claude/commands/help.md +0 -29
- package/.claude/commands/help:agents.md +0 -182
- package/.claude/commands/help:commands.md +0 -78
- package/.claude/commands/help:faq.md +0 -79
- package/.claude/commands/help:plugins.md +0 -50
- package/.claude/commands/help:skills.md +0 -87
- package/.claude/commands/help:tools.md +0 -75
- package/.claude/commands/hotfix-squad.md +0 -112
- package/.claude/commands/integration-squad.md +0 -82
- package/.claude/commands/janitor-squad.md +0 -167
- package/.claude/commands/onboard-squad.md +0 -130
- package/.claude/commands/swarm.md +0 -210
- package/.claude/commands/tool-builder.md +0 -39
- package/.claude/skills/publish-hailer-app/SKILL.md +0 -280
- package/dist/CLAUDE.md +0 -370
- package/dist/agents/bot-manager.d.ts +0 -48
- package/dist/agents/bot-manager.d.ts.map +0 -1
- package/dist/agents/bot-manager.js +0 -254
- package/dist/agents/bot-manager.js.map +0 -1
- package/dist/agents/bug-fixer/ai.d.ts +0 -80
- package/dist/agents/bug-fixer/ai.d.ts.map +0 -1
- package/dist/agents/bug-fixer/ai.js +0 -466
- package/dist/agents/bug-fixer/ai.js.map +0 -1
- package/dist/agents/bug-fixer/bot.d.ts +0 -92
- package/dist/agents/bug-fixer/bot.d.ts.map +0 -1
- package/dist/agents/bug-fixer/bot.js +0 -687
- package/dist/agents/bug-fixer/bot.js.map +0 -1
- package/dist/agents/bug-fixer/config.d.ts +0 -21
- package/dist/agents/bug-fixer/config.d.ts.map +0 -1
- package/dist/agents/bug-fixer/config.js +0 -218
- package/dist/agents/bug-fixer/config.js.map +0 -1
- package/dist/agents/bug-fixer/files.d.ts +0 -67
- package/dist/agents/bug-fixer/files.d.ts.map +0 -1
- package/dist/agents/bug-fixer/files.js +0 -386
- package/dist/agents/bug-fixer/files.js.map +0 -1
- package/dist/agents/bug-fixer/git.d.ts +0 -48
- package/dist/agents/bug-fixer/git.d.ts.map +0 -1
- package/dist/agents/bug-fixer/git.js +0 -298
- package/dist/agents/bug-fixer/git.js.map +0 -1
- package/dist/agents/bug-fixer/index.d.ts +0 -103
- package/dist/agents/bug-fixer/index.d.ts.map +0 -1
- package/dist/agents/bug-fixer/index.js +0 -262
- package/dist/agents/bug-fixer/index.js.map +0 -1
- package/dist/agents/bug-fixer/lsp.d.ts +0 -113
- package/dist/agents/bug-fixer/lsp.d.ts.map +0 -1
- package/dist/agents/bug-fixer/lsp.js +0 -485
- package/dist/agents/bug-fixer/lsp.js.map +0 -1
- package/dist/agents/bug-fixer/monitor.d.ts +0 -123
- package/dist/agents/bug-fixer/monitor.d.ts.map +0 -1
- package/dist/agents/bug-fixer/monitor.js +0 -629
- package/dist/agents/bug-fixer/monitor.js.map +0 -1
- package/dist/agents/bug-fixer/prompt.d.ts +0 -5
- package/dist/agents/bug-fixer/prompt.d.ts.map +0 -1
- package/dist/agents/bug-fixer/prompt.js +0 -94
- package/dist/agents/bug-fixer/prompt.js.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-classification.d.ts +0 -28
- package/dist/agents/bug-fixer/registries/pending-classification.d.ts.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-classification.js +0 -50
- package/dist/agents/bug-fixer/registries/pending-classification.js.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-fix.d.ts +0 -33
- package/dist/agents/bug-fixer/registries/pending-fix.d.ts.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-fix.js +0 -64
- package/dist/agents/bug-fixer/registries/pending-fix.js.map +0 -1
- package/dist/agents/bug-fixer/registries/pending.d.ts +0 -27
- package/dist/agents/bug-fixer/registries/pending.d.ts.map +0 -1
- package/dist/agents/bug-fixer/registries/pending.js +0 -49
- package/dist/agents/bug-fixer/registries/pending.js.map +0 -1
- package/dist/agents/bug-fixer/specialist-daemon.d.ts +0 -88
- package/dist/agents/bug-fixer/specialist-daemon.d.ts.map +0 -1
- package/dist/agents/bug-fixer/specialist-daemon.js +0 -431
- package/dist/agents/bug-fixer/specialist-daemon.js.map +0 -1
- package/dist/agents/bug-fixer/specialist.d.ts +0 -47
- package/dist/agents/bug-fixer/specialist.d.ts.map +0 -1
- package/dist/agents/bug-fixer/specialist.js +0 -327
- package/dist/agents/bug-fixer/specialist.js.map +0 -1
- package/dist/agents/bug-fixer/types.d.ts +0 -123
- package/dist/agents/bug-fixer/types.d.ts.map +0 -1
- package/dist/agents/bug-fixer/types.js +0 -9
- package/dist/agents/bug-fixer/types.js.map +0 -1
- package/dist/agents/factory.d.ts +0 -172
- package/dist/agents/factory.d.ts.map +0 -1
- package/dist/agents/factory.js +0 -706
- package/dist/agents/factory.js.map +0 -1
- package/dist/agents/hailer-expert/index.d.ts +0 -8
- package/dist/agents/hailer-expert/index.d.ts.map +0 -1
- package/dist/agents/hailer-expert/index.js +0 -14
- package/dist/agents/hailer-expert/index.js.map +0 -1
- package/dist/agents/hal/daemon.d.ts +0 -174
- package/dist/agents/hal/daemon.d.ts.map +0 -1
- package/dist/agents/hal/daemon.js +0 -1385
- package/dist/agents/hal/daemon.js.map +0 -1
- package/dist/agents/hal/definitions.d.ts +0 -42
- package/dist/agents/hal/definitions.d.ts.map +0 -1
- package/dist/agents/hal/definitions.js +0 -300
- package/dist/agents/hal/definitions.js.map +0 -1
- package/dist/agents/hal/index.d.ts +0 -3
- package/dist/agents/hal/index.d.ts.map +0 -1
- package/dist/agents/hal/index.js +0 -8
- package/dist/agents/hal/index.js.map +0 -1
- package/dist/agents/index.d.ts +0 -18
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/index.js +0 -48
- package/dist/agents/index.js.map +0 -1
- package/dist/agents/shared/base.d.ts +0 -253
- package/dist/agents/shared/base.d.ts.map +0 -1
- package/dist/agents/shared/base.js +0 -1122
- package/dist/agents/shared/base.js.map +0 -1
- package/dist/agents/shared/schemas/action-schema.d.ts +0 -62
- package/dist/agents/shared/schemas/action-schema.d.ts.map +0 -1
- package/dist/agents/shared/schemas/action-schema.js +0 -483
- package/dist/agents/shared/schemas/action-schema.js.map +0 -1
- package/dist/agents/shared/services/agent-registry.d.ts +0 -108
- package/dist/agents/shared/services/agent-registry.d.ts.map +0 -1
- package/dist/agents/shared/services/agent-registry.js +0 -469
- package/dist/agents/shared/services/agent-registry.js.map +0 -1
- package/dist/agents/shared/services/conversation-manager.d.ts +0 -57
- package/dist/agents/shared/services/conversation-manager.d.ts.map +0 -1
- package/dist/agents/shared/services/conversation-manager.js +0 -168
- package/dist/agents/shared/services/conversation-manager.js.map +0 -1
- package/dist/agents/shared/services/mcp-client.d.ts +0 -56
- package/dist/agents/shared/services/mcp-client.d.ts.map +0 -1
- package/dist/agents/shared/services/mcp-client.js +0 -124
- package/dist/agents/shared/services/mcp-client.js.map +0 -1
- package/dist/agents/shared/services/message-classifier.d.ts +0 -37
- package/dist/agents/shared/services/message-classifier.d.ts.map +0 -1
- package/dist/agents/shared/services/message-classifier.js +0 -203
- package/dist/agents/shared/services/message-classifier.js.map +0 -1
- package/dist/agents/shared/services/message-formatter.d.ts +0 -89
- package/dist/agents/shared/services/message-formatter.d.ts.map +0 -1
- package/dist/agents/shared/services/message-formatter.js +0 -390
- package/dist/agents/shared/services/message-formatter.js.map +0 -1
- package/dist/agents/shared/services/session-logger.d.ts +0 -162
- package/dist/agents/shared/services/session-logger.d.ts.map +0 -1
- package/dist/agents/shared/services/session-logger.js +0 -724
- package/dist/agents/shared/services/session-logger.js.map +0 -1
- package/dist/agents/shared/services/structured-output-executor.d.ts +0 -88
- package/dist/agents/shared/services/structured-output-executor.d.ts.map +0 -1
- package/dist/agents/shared/services/structured-output-executor.js +0 -296
- package/dist/agents/shared/services/structured-output-executor.js.map +0 -1
- package/dist/agents/shared/services/token-billing.d.ts +0 -72
- package/dist/agents/shared/services/token-billing.d.ts.map +0 -1
- package/dist/agents/shared/services/token-billing.js +0 -198
- package/dist/agents/shared/services/token-billing.js.map +0 -1
- package/dist/agents/shared/services/tool-executor.d.ts +0 -43
- package/dist/agents/shared/services/tool-executor.d.ts.map +0 -1
- package/dist/agents/shared/services/tool-executor.js +0 -175
- package/dist/agents/shared/services/tool-executor.js.map +0 -1
- package/dist/agents/shared/services/typing-indicator.d.ts +0 -24
- package/dist/agents/shared/services/typing-indicator.d.ts.map +0 -1
- package/dist/agents/shared/services/typing-indicator.js +0 -54
- package/dist/agents/shared/services/typing-indicator.js.map +0 -1
- package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -122
- package/dist/agents/shared/services/workspace-schema-cache.d.ts.map +0 -1
- package/dist/agents/shared/services/workspace-schema-cache.js +0 -507
- package/dist/agents/shared/services/workspace-schema-cache.js.map +0 -1
- package/dist/agents/shared/specialist.d.ts +0 -91
- package/dist/agents/shared/specialist.d.ts.map +0 -1
- package/dist/agents/shared/specialist.js +0 -399
- package/dist/agents/shared/specialist.js.map +0 -1
- package/dist/agents/shared/tool-schema-loader.d.ts +0 -65
- package/dist/agents/shared/tool-schema-loader.d.ts.map +0 -1
- package/dist/agents/shared/tool-schema-loader.js +0 -238
- package/dist/agents/shared/tool-schema-loader.js.map +0 -1
- package/dist/agents/shared/types.d.ts +0 -190
- package/dist/agents/shared/types.d.ts.map +0 -1
- package/dist/agents/shared/types.js +0 -13
- package/dist/agents/shared/types.js.map +0 -1
- package/dist/bot/bot-config.d.ts +0 -37
- package/dist/bot/bot-config.d.ts.map +0 -1
- package/dist/bot/bot-config.js +0 -219
- package/dist/bot/bot-config.js.map +0 -1
- package/dist/bot/services/__tests__/permission-guard.test.d.ts +0 -2
- package/dist/bot/services/__tests__/permission-guard.test.d.ts.map +0 -1
- package/dist/bot/services/__tests__/permission-guard.test.js +0 -357
- package/dist/bot/services/__tests__/permission-guard.test.js.map +0 -1
- package/dist/bot/services/session-logger.d.ts +0 -162
- package/dist/bot/services/session-logger.d.ts.map +0 -1
- package/dist/bot/services/session-logger.js +0 -724
- package/dist/bot/services/session-logger.js.map +0 -1
- package/dist/bot/services/workspace-schema-cache.d.ts +0 -122
- package/dist/bot/services/workspace-schema-cache.d.ts.map +0 -1
- package/dist/bot/services/workspace-schema-cache.js +0 -506
- package/dist/bot/services/workspace-schema-cache.js.map +0 -1
- package/dist/bot-config/tools.d.ts +0 -28
- package/dist/bot-config/tools.d.ts.map +0 -1
- package/dist/bot-config/tools.js +0 -279
- package/dist/bot-config/tools.js.map +0 -1
- package/dist/client/agents/base.d.ts +0 -207
- package/dist/client/agents/base.d.ts.map +0 -1
- package/dist/client/agents/base.js +0 -744
- package/dist/client/agents/base.js.map +0 -1
- package/dist/client/agents/definitions.d.ts +0 -53
- package/dist/client/agents/definitions.d.ts.map +0 -1
- package/dist/client/agents/definitions.js +0 -263
- package/dist/client/agents/definitions.js.map +0 -1
- package/dist/client/agents/orchestrator.d.ts +0 -141
- package/dist/client/agents/orchestrator.d.ts.map +0 -1
- package/dist/client/agents/orchestrator.js +0 -1062
- package/dist/client/agents/orchestrator.js.map +0 -1
- package/dist/client/agents/specialist.d.ts +0 -86
- package/dist/client/agents/specialist.d.ts.map +0 -1
- package/dist/client/agents/specialist.js +0 -340
- package/dist/client/agents/specialist.js.map +0 -1
- package/dist/client/bot-entrypoint.d.ts +0 -7
- package/dist/client/bot-entrypoint.d.ts.map +0 -1
- package/dist/client/bot-entrypoint.js +0 -103
- package/dist/client/bot-entrypoint.js.map +0 -1
- package/dist/client/bot-manager.d.ts +0 -44
- package/dist/client/bot-manager.d.ts.map +0 -1
- package/dist/client/bot-manager.js +0 -173
- package/dist/client/bot-manager.js.map +0 -1
- package/dist/client/bot-runner.d.ts +0 -35
- package/dist/client/bot-runner.d.ts.map +0 -1
- package/dist/client/bot-runner.js +0 -188
- package/dist/client/bot-runner.js.map +0 -1
- package/dist/client/chat-agent-daemon.d.ts +0 -464
- package/dist/client/chat-agent-daemon.d.ts.map +0 -1
- package/dist/client/chat-agent-daemon.js +0 -1774
- package/dist/client/chat-agent-daemon.js.map +0 -1
- package/dist/client/daemon-factory.d.ts +0 -106
- package/dist/client/daemon-factory.d.ts.map +0 -1
- package/dist/client/daemon-factory.js +0 -301
- package/dist/client/daemon-factory.js.map +0 -1
- package/dist/client/factory.d.ts +0 -111
- package/dist/client/factory.d.ts.map +0 -1
- package/dist/client/factory.js +0 -314
- package/dist/client/factory.js.map +0 -1
- package/dist/client/index.d.ts +0 -17
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -38
- package/dist/client/index.js.map +0 -1
- package/dist/client/multi-bot-manager.d.ts +0 -42
- package/dist/client/multi-bot-manager.d.ts.map +0 -1
- package/dist/client/multi-bot-manager.js +0 -161
- package/dist/client/multi-bot-manager.js.map +0 -1
- package/dist/client/orchestrator-daemon.d.ts +0 -87
- package/dist/client/orchestrator-daemon.d.ts.map +0 -1
- package/dist/client/orchestrator-daemon.js +0 -444
- package/dist/client/orchestrator-daemon.js.map +0 -1
- package/dist/client/server.d.ts +0 -8
- package/dist/client/server.d.ts.map +0 -1
- package/dist/client/server.js +0 -251
- package/dist/client/server.js.map +0 -1
- package/dist/client/services/agent-registry.d.ts +0 -108
- package/dist/client/services/agent-registry.d.ts.map +0 -1
- package/dist/client/services/agent-registry.js +0 -630
- package/dist/client/services/agent-registry.js.map +0 -1
- package/dist/client/services/conversation-manager.d.ts +0 -50
- package/dist/client/services/conversation-manager.d.ts.map +0 -1
- package/dist/client/services/conversation-manager.js +0 -136
- package/dist/client/services/conversation-manager.js.map +0 -1
- package/dist/client/services/mcp-client.d.ts +0 -48
- package/dist/client/services/mcp-client.d.ts.map +0 -1
- package/dist/client/services/mcp-client.js +0 -105
- package/dist/client/services/mcp-client.js.map +0 -1
- package/dist/client/services/message-classifier.d.ts +0 -37
- package/dist/client/services/message-classifier.d.ts.map +0 -1
- package/dist/client/services/message-classifier.js +0 -187
- package/dist/client/services/message-classifier.js.map +0 -1
- package/dist/client/services/message-formatter.d.ts +0 -84
- package/dist/client/services/message-formatter.d.ts.map +0 -1
- package/dist/client/services/message-formatter.js +0 -353
- package/dist/client/services/message-formatter.js.map +0 -1
- package/dist/client/services/session-logger.d.ts +0 -106
- package/dist/client/services/session-logger.d.ts.map +0 -1
- package/dist/client/services/session-logger.js +0 -446
- package/dist/client/services/session-logger.js.map +0 -1
- package/dist/client/services/tool-executor.d.ts +0 -41
- package/dist/client/services/tool-executor.d.ts.map +0 -1
- package/dist/client/services/tool-executor.js +0 -169
- package/dist/client/services/tool-executor.js.map +0 -1
- package/dist/client/services/workspace-schema-cache.d.ts +0 -149
- package/dist/client/services/workspace-schema-cache.d.ts.map +0 -1
- package/dist/client/services/workspace-schema-cache.js +0 -732
- package/dist/client/services/workspace-schema-cache.js.map +0 -1
- package/dist/client/specialist-daemon.d.ts +0 -77
- package/dist/client/specialist-daemon.d.ts.map +0 -1
- package/dist/client/specialist-daemon.js +0 -197
- package/dist/client/specialist-daemon.js.map +0 -1
- package/dist/client/specialists.d.ts +0 -53
- package/dist/client/specialists.d.ts.map +0 -1
- package/dist/client/specialists.js +0 -178
- package/dist/client/specialists.js.map +0 -1
- package/dist/client/tool-schema-loader.d.ts +0 -62
- package/dist/client/tool-schema-loader.d.ts.map +0 -1
- package/dist/client/tool-schema-loader.js +0 -232
- package/dist/client/tool-schema-loader.js.map +0 -1
- package/dist/client/types.d.ts +0 -327
- package/dist/client/types.d.ts.map +0 -1
- package/dist/client/types.js +0 -121
- package/dist/client/types.js.map +0 -1
- package/dist/commands/seed-config.d.ts +0 -9
- package/dist/commands/seed-config.d.ts.map +0 -1
- package/dist/commands/seed-config.js +0 -377
- package/dist/commands/seed-config.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -11
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -320
- package/dist/commands/setup.js.map +0 -1
- package/dist/lib/discussion-lock.d.ts +0 -42
- package/dist/lib/discussion-lock.d.ts.map +0 -1
- package/dist/lib/discussion-lock.js +0 -110
- package/dist/lib/discussion-lock.js.map +0 -1
- package/dist/mcp/signal-handler.d.ts +0 -82
- package/dist/mcp/signal-handler.d.ts.map +0 -1
- package/dist/mcp/signal-handler.js +0 -406
- package/dist/mcp/signal-handler.js.map +0 -1
- package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts +0 -2
- package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts.map +0 -1
- package/dist/mcp/tools/__tests__/discussion-forward.test.js +0 -218
- package/dist/mcp/tools/__tests__/discussion-forward.test.js.map +0 -1
- package/dist/mcp/tools/app-member.d.ts +0 -14
- package/dist/mcp/tools/app-member.d.ts.map +0 -1
- package/dist/mcp/tools/app-member.js +0 -195
- package/dist/mcp/tools/app-member.js.map +0 -1
- package/dist/mcp/tools/app-scaffold.d.ts +0 -14
- package/dist/mcp/tools/app-scaffold.d.ts.map +0 -1
- package/dist/mcp/tools/app-scaffold.js +0 -581
- package/dist/mcp/tools/app-scaffold.js.map +0 -1
- package/dist/mcp/tools/bot-config/constants.d.ts +0 -23
- package/dist/mcp/tools/bot-config/constants.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/constants.js +0 -94
- package/dist/mcp/tools/bot-config/constants.js.map +0 -1
- package/dist/mcp/tools/bot-config/core.d.ts +0 -253
- package/dist/mcp/tools/bot-config/core.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/core.js +0 -2456
- package/dist/mcp/tools/bot-config/core.js.map +0 -1
- package/dist/mcp/tools/bot-config/index.d.ts +0 -10
- package/dist/mcp/tools/bot-config/index.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/index.js +0 -59
- package/dist/mcp/tools/bot-config/index.js.map +0 -1
- package/dist/mcp/tools/bot-config/tools.d.ts +0 -7
- package/dist/mcp/tools/bot-config/tools.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/tools.js +0 -15
- package/dist/mcp/tools/bot-config/tools.js.map +0 -1
- package/dist/mcp/tools/bot-config/types.d.ts +0 -50
- package/dist/mcp/tools/bot-config/types.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/types.js +0 -6
- package/dist/mcp/tools/bot-config/types.js.map +0 -1
- package/dist/mcp/tools/bug-fixer-tools.d.ts +0 -45
- package/dist/mcp/tools/bug-fixer-tools.d.ts.map +0 -1
- package/dist/mcp/tools/bug-fixer-tools.js +0 -1096
- package/dist/mcp/tools/bug-fixer-tools.js.map +0 -1
- package/dist/mcp/tools/document.d.ts +0 -11
- package/dist/mcp/tools/document.d.ts.map +0 -1
- package/dist/mcp/tools/document.js +0 -741
- package/dist/mcp/tools/document.js.map +0 -1
- package/dist/mcp/tools/investigate.d.ts +0 -9
- package/dist/mcp/tools/investigate.d.ts.map +0 -1
- package/dist/mcp/tools/investigate.js +0 -254
- package/dist/mcp/tools/investigate.js.map +0 -1
- package/dist/mcp/utils/pagination.d.ts +0 -40
- package/dist/mcp/utils/pagination.d.ts.map +0 -1
- package/dist/mcp/utils/pagination.js +0 -55
- package/dist/mcp/utils/pagination.js.map +0 -1
- package/dist/modules/bug-reports/bug-config.d.ts +0 -25
- package/dist/modules/bug-reports/bug-config.d.ts.map +0 -1
- package/dist/modules/bug-reports/bug-config.js +0 -187
- package/dist/modules/bug-reports/bug-config.js.map +0 -1
- package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
- package/dist/modules/bug-reports/bug-monitor.d.ts.map +0 -1
- package/dist/modules/bug-reports/bug-monitor.js +0 -510
- package/dist/modules/bug-reports/bug-monitor.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
- package/dist/modules/bug-reports/giuseppe-agent.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
- package/dist/modules/bug-reports/giuseppe-agent.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
- package/dist/modules/bug-reports/giuseppe-ai.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
- package/dist/modules/bug-reports/giuseppe-ai.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
- package/dist/modules/bug-reports/giuseppe-bot.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
- package/dist/modules/bug-reports/giuseppe-bot.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
- package/dist/modules/bug-reports/giuseppe-daemon.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
- package/dist/modules/bug-reports/giuseppe-files.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-files.js +0 -375
- package/dist/modules/bug-reports/giuseppe-files.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
- package/dist/modules/bug-reports/giuseppe-git.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-git.js +0 -298
- package/dist/modules/bug-reports/giuseppe-git.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
- package/dist/modules/bug-reports/giuseppe-lsp.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
- package/dist/modules/bug-reports/giuseppe-prompt.js.map +0 -1
- package/dist/modules/bug-reports/index.d.ts +0 -77
- package/dist/modules/bug-reports/index.d.ts.map +0 -1
- package/dist/modules/bug-reports/index.js +0 -215
- package/dist/modules/bug-reports/index.js.map +0 -1
- package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
- package/dist/modules/bug-reports/pending-classification-registry.d.ts.map +0 -1
- package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
- package/dist/modules/bug-reports/pending-classification-registry.js.map +0 -1
- package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
- package/dist/modules/bug-reports/pending-fix-registry.d.ts.map +0 -1
- package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
- package/dist/modules/bug-reports/pending-fix-registry.js.map +0 -1
- package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
- package/dist/modules/bug-reports/pending-registry.d.ts.map +0 -1
- package/dist/modules/bug-reports/pending-registry.js +0 -49
- package/dist/modules/bug-reports/pending-registry.js.map +0 -1
- package/dist/modules/bug-reports/types.d.ts +0 -123
- package/dist/modules/bug-reports/types.d.ts.map +0 -1
- package/dist/modules/bug-reports/types.js +0 -9
- package/dist/modules/bug-reports/types.js.map +0 -1
- package/dist/plugins/bug-fixer/index.d.ts +0 -2
- package/dist/plugins/bug-fixer/index.d.ts.map +0 -1
- package/dist/plugins/bug-fixer/index.js +0 -18
- package/dist/plugins/bug-fixer/index.js.map +0 -1
- package/dist/plugins/bug-fixer/tools.d.ts +0 -45
- package/dist/plugins/bug-fixer/tools.d.ts.map +0 -1
- package/dist/plugins/bug-fixer/tools.js +0 -1096
- package/dist/plugins/bug-fixer/tools.js.map +0 -1
- package/dist/plugins/vipunen/__tests__/tools.test.d.ts +0 -10
- package/dist/plugins/vipunen/__tests__/tools.test.d.ts.map +0 -1
- package/dist/plugins/vipunen/__tests__/tools.test.js +0 -646
- package/dist/plugins/vipunen/__tests__/tools.test.js.map +0 -1
- package/dist/routes/agents.d.ts +0 -44
- package/dist/routes/agents.d.ts.map +0 -1
- package/dist/routes/agents.js +0 -311
- package/dist/routes/agents.js.map +0 -1
- package/dist/services/agent-credential-store.d.ts +0 -73
- package/dist/services/agent-credential-store.d.ts.map +0 -1
- package/dist/services/agent-credential-store.js +0 -212
- package/dist/services/agent-credential-store.js.map +0 -1
- package/dist/stdio-server.d.ts +0 -14
- package/dist/stdio-server.d.ts.map +0 -1
- package/dist/stdio-server.js +0 -101
- package/dist/stdio-server.js.map +0 -1
- package/dist/workspace/context.d.ts +0 -148
- package/dist/workspace/context.d.ts.map +0 -1
- package/dist/workspace/context.js +0 -339
- package/dist/workspace/context.js.map +0 -1
- package/dist/workspace/credentials.d.ts +0 -55
- package/dist/workspace/credentials.d.ts.map +0 -1
- package/dist/workspace/credentials.js +0 -239
- package/dist/workspace/credentials.js.map +0 -1
- package/dist/workspace/index.d.ts +0 -21
- package/dist/workspace/index.d.ts.map +0 -1
- package/dist/workspace/index.js +0 -45
- package/dist/workspace/index.js.map +0 -1
- package/dist/workspace/loader.d.ts +0 -27
- package/dist/workspace/loader.d.ts.map +0 -1
- package/dist/workspace/loader.js +0 -222
- package/dist/workspace/loader.js.map +0 -1
- package/dist/workspace/schema.d.ts +0 -37
- package/dist/workspace/schema.d.ts.map +0 -1
- package/dist/workspace/schema.js +0 -192
- package/dist/workspace/schema.js.map +0 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* These are PLAYGROUND tools requiring workspace administrator permissions.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.workflowTools = exports.autoSetKeysTool = exports.
|
|
9
|
+
exports.workflowTools = exports.autoSetKeysTool = exports.coreInitTool = exports.testFunctionFieldTool = exports.updateWorkflowStructureTool = exports.removeWorkflowTool = exports.installWorkflowTool = exports.describeWorkflowsTool = void 0;
|
|
10
10
|
const zod_1 = require("zod");
|
|
11
11
|
const tool_registry_1 = require("../tool-registry");
|
|
12
12
|
const logger_1 = require("../../lib/logger");
|
|
@@ -34,7 +34,7 @@ function isSdkProject() {
|
|
|
34
34
|
function sdkRedirect(tool, sdkCommand, sdkFile) {
|
|
35
35
|
return {
|
|
36
36
|
content: [{
|
|
37
|
-
type:
|
|
37
|
+
type: 'text',
|
|
38
38
|
text: `⚠️ **SDK project detected — use the SDK instead of \`${tool}\`**\n\n` +
|
|
39
39
|
`This project has a \`workspace/\` directory, which means workflow configuration should be managed through SDK files.\n\n` +
|
|
40
40
|
`**Instead, do this:**\n` +
|
|
@@ -96,17 +96,20 @@ function generateKey(name, existingKeys) {
|
|
|
96
96
|
.replace(/[^a-zA-Z0-9\s-_]/g, '')
|
|
97
97
|
.split(/[\s\-_]+/)
|
|
98
98
|
.filter(w => w.length > 0);
|
|
99
|
-
if (words.length === 0)
|
|
99
|
+
if (words.length === 0) {
|
|
100
100
|
return 'unnamed';
|
|
101
|
+
}
|
|
101
102
|
const base = words[0].toLowerCase() + words.slice(1).map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
|
|
102
103
|
const key = base.slice(0, 64);
|
|
103
|
-
if (!existingKeys || !existingKeys.has(key))
|
|
104
|
+
if (!existingKeys || !existingKeys.has(key)) {
|
|
104
105
|
return key;
|
|
106
|
+
}
|
|
105
107
|
// Dedup: append incrementing suffix
|
|
106
108
|
for (let i = 2; i <= 99; i++) {
|
|
107
109
|
const candidate = `${key}${i}`.slice(0, 64);
|
|
108
|
-
if (!existingKeys.has(candidate))
|
|
110
|
+
if (!existingKeys.has(candidate)) {
|
|
109
111
|
return candidate;
|
|
112
|
+
}
|
|
110
113
|
}
|
|
111
114
|
return `${key}${Date.now()}`.slice(0, 64);
|
|
112
115
|
}
|
|
@@ -125,13 +128,15 @@ async function autoSetKeys(workflowId, context) {
|
|
|
125
128
|
// Collect existing keys to avoid duplicates
|
|
126
129
|
const existingPhaseKeys = new Set();
|
|
127
130
|
for (const phase of Object.values(workflow.phases || {})) {
|
|
128
|
-
if (phase.key)
|
|
131
|
+
if (phase.key) {
|
|
129
132
|
existingPhaseKeys.add(phase.key);
|
|
133
|
+
}
|
|
130
134
|
}
|
|
131
135
|
const existingFieldKeys = new Set();
|
|
132
136
|
for (const field of Object.values(workflow.fields || {})) {
|
|
133
|
-
if (field.key)
|
|
137
|
+
if (field.key) {
|
|
134
138
|
existingFieldKeys.add(field.key);
|
|
139
|
+
}
|
|
135
140
|
}
|
|
136
141
|
// Set workflow key (unique per workspace — no local dedup needed, API rejects duplicates)
|
|
137
142
|
if (!workflow.key && workflow.name) {
|
|
@@ -177,335 +182,299 @@ async function autoSetKeys(workflowId, context) {
|
|
|
177
182
|
return result;
|
|
178
183
|
}
|
|
179
184
|
// ============================================================================
|
|
180
|
-
// READ TOOLS - Workflow
|
|
185
|
+
// READ TOOLS - Workflow Discovery (describe_workflows)
|
|
181
186
|
// ============================================================================
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
responseText += `**Available Fields (${fieldsOrder.length} total):**\n\n`;
|
|
249
|
-
fieldsOrder.forEach((fieldId, index) => {
|
|
250
|
-
const field = workflowFields[fieldId];
|
|
251
|
-
if (!field)
|
|
252
|
-
return;
|
|
253
|
-
responseText += `${index + 1}. **${field.label || 'Unnamed Field'}**\n`;
|
|
254
|
-
responseText += ` - Field ID: \`${fieldId}\`\n`;
|
|
255
|
-
if (field.key)
|
|
256
|
-
responseText += ` - Key: \`${field.key}\`\n`;
|
|
257
|
-
responseText += ` - Type: ${field.type}`;
|
|
258
|
-
if (field.subtype)
|
|
259
|
-
responseText += ` (${field.subtype})`;
|
|
260
|
-
responseText += `\n`;
|
|
261
|
-
if (field.required)
|
|
262
|
-
responseText += ` - Required: Yes\n`;
|
|
263
|
-
if (field.description)
|
|
264
|
-
responseText += ` - Description: ${field.description}\n`;
|
|
265
|
-
if (field.placeholder)
|
|
266
|
-
responseText += ` - Placeholder: "${field.placeholder}"\n`;
|
|
267
|
-
if (field.data && field.data.length > 0) {
|
|
268
|
-
responseText += ` - Options: ${field.data.slice(0, 3).join(', ')}`;
|
|
269
|
-
if (field.data.length > 3)
|
|
270
|
-
responseText += ` (and ${field.data.length - 3} more)`;
|
|
271
|
-
responseText += `\n`;
|
|
272
|
-
}
|
|
273
|
-
responseText += `\n`;
|
|
187
|
+
/** Render the minimal workflow list — former list_workflows_minimal output */
|
|
188
|
+
function renderWorkflowListMinimal(context) {
|
|
189
|
+
const workflows = context.init.processes || [];
|
|
190
|
+
let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📋 **Workflows Found**\n\n`;
|
|
191
|
+
responseText += `Total: ${workflows.length}\n\n`;
|
|
192
|
+
workflows.forEach((wf) => {
|
|
193
|
+
const star = wf.isStarred ? '⭐ ' : '';
|
|
194
|
+
responseText += `${star}**${wf.name}**\n`;
|
|
195
|
+
responseText += ` ID: \`${wf._id}\`\n`;
|
|
196
|
+
responseText += ` Activities: ${wf.createdActivities || 0}\n\n`;
|
|
197
|
+
});
|
|
198
|
+
responseText += `\n💡 **Next Steps:**\n`;
|
|
199
|
+
responseText += `- Use \`describe_workflows\` with a workflowId and include: ['schema'] to see fields\n`;
|
|
200
|
+
responseText += `- Use \`describe_workflows\` with a workflowId and include: ['phases'] to see phases\n`;
|
|
201
|
+
return responseText;
|
|
202
|
+
}
|
|
203
|
+
/** Render the full workflow list with ActivityLink relationships — former list_workflows output */
|
|
204
|
+
function renderWorkflowListFull(context) {
|
|
205
|
+
const workflows = context.init.processes || [];
|
|
206
|
+
const workflowSummary = workflows.map((workflow) => {
|
|
207
|
+
const activityLinkFields = Object.entries(workflow.fields ?? {})
|
|
208
|
+
.filter(([, field]) => field.type === 'activitylink');
|
|
209
|
+
const initialPhases = Object.values(workflow.phases || {})
|
|
210
|
+
.filter(phase => phase.isInitial)
|
|
211
|
+
.map(phase => ({
|
|
212
|
+
id: phase._id,
|
|
213
|
+
name: phase.name
|
|
214
|
+
}));
|
|
215
|
+
// Calculate linksTo from activitylink fields
|
|
216
|
+
const linksTo = activityLinkFields.flatMap(([, field]) => field.data || []);
|
|
217
|
+
return {
|
|
218
|
+
id: workflow._id,
|
|
219
|
+
name: workflow.name,
|
|
220
|
+
workspaceId: workflow.cid,
|
|
221
|
+
activityCount: workflow.createdActivities || 0,
|
|
222
|
+
isStarred: workflow.isStarred || false,
|
|
223
|
+
hasActivityLinks: activityLinkFields.length > 0,
|
|
224
|
+
linksTo,
|
|
225
|
+
linkedFrom: [], // Would need to scan all workflows - skip for now
|
|
226
|
+
initialPhases: initialPhases,
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
let responseText = `📋 **${workflows.length} Workflows Found**\n\n`;
|
|
230
|
+
responseText += JSON.stringify(workflowSummary, null, 2);
|
|
231
|
+
const relationships = [];
|
|
232
|
+
for (const workflow of workflows) {
|
|
233
|
+
const activityLinkFields = Object.entries(workflow.fields ?? {})
|
|
234
|
+
.filter(([, field]) => field.type === 'activitylink')
|
|
235
|
+
.map(([fieldId, field]) => ({
|
|
236
|
+
id: fieldId,
|
|
237
|
+
label: field.label,
|
|
238
|
+
key: field.key,
|
|
239
|
+
targetWorkflowIds: field.data || [],
|
|
240
|
+
required: field.required || false,
|
|
241
|
+
}));
|
|
242
|
+
for (const field of activityLinkFields) {
|
|
243
|
+
for (const targetWorkflowId of field.targetWorkflowIds) {
|
|
244
|
+
const targetWorkflow = workflows.find((wf) => wf._id === targetWorkflowId);
|
|
245
|
+
relationships.push({
|
|
246
|
+
sourceWorkflowId: workflow._id,
|
|
247
|
+
sourceWorkflowName: workflow.name,
|
|
248
|
+
targetWorkflowId,
|
|
249
|
+
targetWorkflowName: targetWorkflow?.name || 'Unknown',
|
|
250
|
+
fieldLabel: field.label,
|
|
251
|
+
fieldKey: field.key,
|
|
252
|
+
required: field.required,
|
|
274
253
|
});
|
|
275
254
|
}
|
|
276
|
-
responseText += `💡 **USAGE:**\n`;
|
|
277
|
-
responseText += `- Use field IDs (or keys if available) in the 'fields' parameter of list_activities\n`;
|
|
278
|
-
responseText += `- **Select ONLY 2-3 essential fields** to minimize token costs\n`;
|
|
279
|
-
const firstFieldId = fieldsOrder[0];
|
|
280
|
-
const secondFieldId = fieldsOrder[1];
|
|
281
|
-
const firstFieldKey = firstFieldId && workflowFields[firstFieldId]?.key;
|
|
282
|
-
const secondFieldKey = secondFieldId && workflowFields[secondFieldId]?.key;
|
|
283
|
-
if (firstFieldId && secondFieldId) {
|
|
284
|
-
responseText += `- Example with IDs: fields: ["${firstFieldId}", "${secondFieldId}"] (just 2 fields)\n`;
|
|
285
|
-
if (firstFieldKey && secondFieldKey) {
|
|
286
|
-
responseText += `- Example with keys: fields: ["${firstFieldKey}", "${secondFieldKey}"] (more readable)\n`;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
responseText += `- For listings: name + key metric (price/status) is usually sufficient\n`;
|
|
290
|
-
responseText += `- Only add description/detail fields when user explicitly needs them`;
|
|
291
|
-
return {
|
|
292
|
-
content: [{
|
|
293
|
-
type: "text",
|
|
294
|
-
text: responseText,
|
|
295
|
-
}],
|
|
296
|
-
};
|
|
297
255
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
256
|
+
}
|
|
257
|
+
if (relationships.length > 0) {
|
|
258
|
+
responseText += `\n\n🔗 **Workflow Relationships:**\n`;
|
|
259
|
+
relationships.forEach(rel => {
|
|
260
|
+
responseText += `• ${rel.sourceWorkflowName} → ${rel.targetWorkflowName} (${rel.fieldLabel})\n`;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
responseText += `\n\n💡 Use describe_workflows with a specific workflowId for detailed information.`;
|
|
264
|
+
return responseText;
|
|
265
|
+
}
|
|
266
|
+
/** Render a single-workflow summary — describe_workflows with workflowId and no includes */
|
|
267
|
+
function renderWorkflowSummary(workflow) {
|
|
268
|
+
const fieldCount = Object.keys(workflow.fields || {}).length;
|
|
269
|
+
const phaseCount = Object.keys(workflow.phases || {}).length;
|
|
270
|
+
let responseText = `📋 **${workflow.name}**\n\n`;
|
|
271
|
+
responseText += `- ID: \`${workflow._id}\`\n`;
|
|
272
|
+
if (workflow.key) {
|
|
273
|
+
responseText += `- Key: \`${workflow.key}\`\n`;
|
|
274
|
+
}
|
|
275
|
+
responseText += `- Workspace: \`${workflow.cid}\`\n`;
|
|
276
|
+
responseText += `- Activities: ${workflow.createdActivities || 0}\n`;
|
|
277
|
+
responseText += `- Fields: ${fieldCount}\n`;
|
|
278
|
+
responseText += `- Phases: ${phaseCount}\n`;
|
|
279
|
+
if (workflow.description) {
|
|
280
|
+
responseText += `- Description: ${workflow.description}\n`;
|
|
281
|
+
}
|
|
282
|
+
responseText += `\n💡 Add include: ['schema'] for field IDs, include: ['phases'] for phase IDs.`;
|
|
283
|
+
return responseText;
|
|
284
|
+
}
|
|
285
|
+
/** Render compact field list — former get_workflow_schema compact mode (default) */
|
|
286
|
+
function renderSchemaCompact(workflow) {
|
|
287
|
+
const workflowFields = workflow.fields || {};
|
|
288
|
+
const fieldsOrder = workflow.fieldsOrder || Object.keys(workflowFields);
|
|
289
|
+
const fieldLines = fieldsOrder.map((fieldId) => {
|
|
290
|
+
const field = workflowFields[fieldId];
|
|
291
|
+
if (!field) {
|
|
292
|
+
return null;
|
|
307
293
|
}
|
|
308
|
-
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
294
|
+
return `- ${field.label || 'Unnamed'} (${field.type}): fieldId="${fieldId}"`;
|
|
295
|
+
}).filter(Boolean);
|
|
296
|
+
return `📋 **${workflow.name}** (workflowId: ${workflow._id})\n\n**Fields:**\n${fieldLines.join('\n')}`;
|
|
297
|
+
}
|
|
298
|
+
/** Render full field details — former get_workflow_schema full mode (detail: 'full') */
|
|
299
|
+
async function renderSchemaFull(workflow, context) {
|
|
300
|
+
// The per-phase schema endpoint supplies name-field metadata; default to the initial phase
|
|
301
|
+
const phaseList = Object.values(workflow.phases || {});
|
|
302
|
+
const schemaPhase = phaseList.find(ph => ph.isInitial) || phaseList[0];
|
|
303
|
+
const schemaData = schemaPhase ? await context.hailer.getWorkflowSchema(workflow._id, schemaPhase._id) : {};
|
|
304
|
+
// Get complete field definitions from workflow (includes keys and all metadata)
|
|
305
|
+
const workflowFields = workflow.fields || {};
|
|
306
|
+
const fieldsOrder = workflow.fieldsOrder || Object.keys(workflowFields);
|
|
307
|
+
let responseText = `📋 **WORKFLOW SCHEMA** for "${workflow.name}":\n\n`;
|
|
308
|
+
if (schemaData.name) {
|
|
309
|
+
responseText += `**Name Field:**\n`;
|
|
310
|
+
responseText += `- Type: ${schemaData.name.type}\n`;
|
|
311
|
+
responseText += `- Required: ${schemaData.name.required || false}\n`;
|
|
312
|
+
responseText += schemaData.name.placeholder ? `- Placeholder: "${schemaData.name.placeholder}"\n` : '';
|
|
313
|
+
responseText += `\n`;
|
|
314
|
+
}
|
|
315
|
+
// Use fieldsOrder to display fields in correct order
|
|
316
|
+
if (fieldsOrder.length > 0) {
|
|
317
|
+
responseText += `**Available Fields (${fieldsOrder.length} total):**\n\n`;
|
|
318
|
+
}
|
|
319
|
+
fieldsOrder.forEach((fieldId, index) => {
|
|
320
|
+
const field = workflowFields[fieldId];
|
|
321
|
+
if (!field) {
|
|
322
|
+
return;
|
|
330
323
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return {
|
|
336
|
-
content: [{
|
|
337
|
-
type: "text",
|
|
338
|
-
text: `❌ Workflow "${args.workflowId}" not found`,
|
|
339
|
-
}],
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
const phases = workflowData.phases || {};
|
|
343
|
-
const phasesOrder = workflowData.phasesOrder || [];
|
|
344
|
-
let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📊 **WORKFLOW PHASES** for "${workflowData.name}":\n\n`;
|
|
345
|
-
if (Object.keys(phases).length === 0) {
|
|
346
|
-
responseText += `❌ No phases found in workflow "${workflowData.name}".`;
|
|
347
|
-
return {
|
|
348
|
-
content: [{ type: "text", text: responseText }],
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
responseText += `Found ${Object.keys(phases).length} phases:\n\n`;
|
|
352
|
-
const orderedPhaseIds = phasesOrder.length > 0 ? phasesOrder : Object.keys(phases);
|
|
353
|
-
orderedPhaseIds.forEach((phaseId, index) => {
|
|
354
|
-
const phase = phases[phaseId];
|
|
355
|
-
if (phase) {
|
|
356
|
-
responseText += `${index + 1}. **${phase.name}**\n`;
|
|
357
|
-
responseText += ` - Phase ID: \`${phase._id}\`\n`;
|
|
358
|
-
if (phase.key) {
|
|
359
|
-
responseText += ` - Key: \`${phase.key}\`\n`;
|
|
360
|
-
}
|
|
361
|
-
if (phase.description) {
|
|
362
|
-
responseText += ` - Description: ${phase.description}\n`;
|
|
363
|
-
}
|
|
364
|
-
if (phase.color) {
|
|
365
|
-
responseText += ` - Color: ${phase.color}\n`;
|
|
366
|
-
}
|
|
367
|
-
if (phase.isInitial) {
|
|
368
|
-
responseText += ` - Initial Phase: Yes\n`;
|
|
369
|
-
}
|
|
370
|
-
if (phase.isEndpoint) {
|
|
371
|
-
responseText += ` - Endpoint Phase: Yes\n`;
|
|
372
|
-
}
|
|
373
|
-
responseText += `\n`;
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
responseText += `💡 **USAGE:** Use any of these Phase IDs with the \`list_activities\` tool to get activities in that phase.\n\n`;
|
|
377
|
-
responseText += `🔍 **FOR COMPREHENSIVE WORKFLOW VIEW:**\n`;
|
|
378
|
-
responseText += `- To see ALL activities across the entire workflow, call \`list_activities\` for each phase ID above\n`;
|
|
379
|
-
responseText += `- Each phase contains different activities at different stages of the workflow\n`;
|
|
380
|
-
responseText += `- Combine results from all phases to get the complete picture of the workflow\n`;
|
|
381
|
-
responseText += `\n**Example workflow:**\n`;
|
|
382
|
-
responseText += `1. First call: \`list_activities\` with first phase ID to see new/pending activities\n`;
|
|
383
|
-
responseText += `2. Second call: \`list_activities\` with second phase ID to see completed activities\n`;
|
|
384
|
-
responseText += `3. Continue for all phases to see the full workflow status`;
|
|
385
|
-
return {
|
|
386
|
-
content: [{
|
|
387
|
-
type: "text",
|
|
388
|
-
text: responseText,
|
|
389
|
-
}],
|
|
390
|
-
};
|
|
324
|
+
responseText += `${index + 1}. **${field.label || 'Unnamed Field'}**\n`;
|
|
325
|
+
responseText += ` - Field ID: \`${fieldId}\`\n`;
|
|
326
|
+
if (field.key) {
|
|
327
|
+
responseText += ` - Key: \`${field.key}\`\n`;
|
|
391
328
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return {
|
|
396
|
-
content: [{
|
|
397
|
-
type: "text",
|
|
398
|
-
text: `❌ Failed to list workflow phases: ${error instanceof Error ? error.message : String(error)}`,
|
|
399
|
-
}],
|
|
400
|
-
};
|
|
329
|
+
responseText += ` - Type: ${field.type}`;
|
|
330
|
+
if (field.subtype) {
|
|
331
|
+
responseText += ` (${field.subtype})`;
|
|
401
332
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
333
|
+
responseText += `\n`;
|
|
334
|
+
if (field.required) {
|
|
335
|
+
responseText += ` - Required: Yes\n`;
|
|
336
|
+
}
|
|
337
|
+
if (field.description) {
|
|
338
|
+
responseText += ` - Description: ${field.description}\n`;
|
|
339
|
+
}
|
|
340
|
+
if (field.placeholder) {
|
|
341
|
+
responseText += ` - Placeholder: "${field.placeholder}"\n`;
|
|
342
|
+
}
|
|
343
|
+
if (field.data && field.data.length > 0) {
|
|
344
|
+
const extraOptions = field.data.length > 3 ? ` (and ${field.data.length - 3} more)` : '';
|
|
345
|
+
responseText += ` - Options: ${field.data.slice(0, 3).join(', ')}${extraOptions}\n`;
|
|
346
|
+
}
|
|
347
|
+
responseText += `\n`;
|
|
348
|
+
});
|
|
349
|
+
responseText += `💡 **USAGE:**\n`;
|
|
350
|
+
responseText += `- Use field IDs (or keys if available) in the 'fields' parameter of list_activities\n`;
|
|
351
|
+
responseText += `- **Select ONLY 2-3 essential fields** to minimize token costs\n`;
|
|
352
|
+
const firstFieldId = fieldsOrder[0];
|
|
353
|
+
const secondFieldId = fieldsOrder[1];
|
|
354
|
+
const firstFieldKey = firstFieldId && workflowFields[firstFieldId]?.key;
|
|
355
|
+
const secondFieldKey = secondFieldId && workflowFields[secondFieldId]?.key;
|
|
356
|
+
if (firstFieldId && secondFieldId) {
|
|
357
|
+
responseText += `- Example with IDs: fields: ["${firstFieldId}", "${secondFieldId}"] (just 2 fields)\n`;
|
|
358
|
+
}
|
|
359
|
+
if (firstFieldId && secondFieldId && firstFieldKey && secondFieldKey) {
|
|
360
|
+
responseText += `- Example with keys: fields: ["${firstFieldKey}", "${secondFieldKey}"] (more readable)\n`;
|
|
361
|
+
}
|
|
362
|
+
responseText += `- For listings: name + key metric (price/status) is usually sufficient\n`;
|
|
363
|
+
responseText += `- Only add description/detail fields when user explicitly needs them`;
|
|
364
|
+
return responseText;
|
|
365
|
+
}
|
|
366
|
+
/** Render the phase list — former list_workflow_phases output */
|
|
367
|
+
function renderPhasesSection(workflow) {
|
|
368
|
+
const phases = workflow.phases || {};
|
|
369
|
+
const phasesOrder = workflow.phasesOrder || [];
|
|
370
|
+
let responseText = `📊 **WORKFLOW PHASES** for "${workflow.name}":\n\n`;
|
|
371
|
+
if (Object.keys(phases).length === 0) {
|
|
372
|
+
responseText += `❌ No phases found in workflow "${workflow.name}".`;
|
|
373
|
+
return responseText;
|
|
374
|
+
}
|
|
375
|
+
responseText += `Found ${Object.keys(phases).length} phases:\n\n`;
|
|
376
|
+
const orderedPhaseIds = phasesOrder.length > 0 ? phasesOrder : Object.keys(phases);
|
|
377
|
+
orderedPhaseIds.forEach((phaseId, index) => {
|
|
378
|
+
const phase = phases[phaseId];
|
|
379
|
+
if (!phase) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
responseText += `${index + 1}. **${phase.name}**\n`;
|
|
383
|
+
responseText += ` - Phase ID: \`${phase._id}\`\n`;
|
|
384
|
+
if (phase.key) {
|
|
385
|
+
responseText += ` - Key: \`${phase.key}\`\n`;
|
|
386
|
+
}
|
|
387
|
+
if (phase.description) {
|
|
388
|
+
responseText += ` - Description: ${phase.description}\n`;
|
|
389
|
+
}
|
|
390
|
+
if (phase.color) {
|
|
391
|
+
responseText += ` - Color: ${phase.color}\n`;
|
|
392
|
+
}
|
|
393
|
+
if (phase.isInitial) {
|
|
394
|
+
responseText += ` - Initial Phase: Yes\n`;
|
|
395
|
+
}
|
|
396
|
+
if (phase.isEndpoint) {
|
|
397
|
+
responseText += ` - Endpoint Phase: Yes\n`;
|
|
398
|
+
}
|
|
399
|
+
responseText += `\n`;
|
|
400
|
+
});
|
|
401
|
+
responseText += `💡 **USAGE:** Use any of these Phase IDs with the \`list_activities\` tool to get activities in that phase.\n\n`;
|
|
402
|
+
responseText += `🔍 **FOR COMPREHENSIVE WORKFLOW VIEW:**\n`;
|
|
403
|
+
responseText += `- To see ALL activities across the entire workflow, call \`list_activities\` for each phase ID above\n`;
|
|
404
|
+
responseText += `- Each phase contains different activities at different stages of the workflow\n`;
|
|
405
|
+
responseText += `- Combine results from all phases to get the complete picture of the workflow`;
|
|
406
|
+
return responseText;
|
|
407
|
+
}
|
|
408
|
+
const describeWorkflowsDescription = `Discover workflows. Modes: (1) no args → list all workflows (IDs, names, activity counts); detail:'full' adds ActivityLink relationships. (2) workflowId → that workflow's summary. (3) workflowId + include:['schema','phases'] → field IDs/types/options and/or phase IDs/flags; detail:'full' expands schema to full field details. Never guess IDs — call this before create_activity, update_activity, or list_activities.`;
|
|
409
|
+
const describeWorkflowsSchema = zod_1.z.object({
|
|
410
|
+
workflowId: zod_1.z.string().optional().describe('Workflow ID (24-char) or key. Omit to list all workflows'),
|
|
411
|
+
include: zod_1.z
|
|
412
|
+
.array(zod_1.z.enum(['schema', 'phases']))
|
|
413
|
+
.optional()
|
|
414
|
+
.describe("Sections to include when workflowId is given: 'schema' = fields, 'phases' = phases. Both can be combined"),
|
|
415
|
+
detail: zod_1.z
|
|
416
|
+
.enum(['minimal', 'full'])
|
|
417
|
+
.optional()
|
|
418
|
+
.default('minimal')
|
|
419
|
+
.describe("'full' adds relationships to the workflow list and complete field details to the schema (default: 'minimal')"),
|
|
420
|
+
force: zod_1.z.boolean().optional().describe('Override SDK redirect — use API even when workspace/ exists'),
|
|
421
|
+
});
|
|
422
|
+
exports.describeWorkflowsTool = {
|
|
423
|
+
name: 'describe_workflows',
|
|
415
424
|
group: tool_registry_1.ToolGroup.READ,
|
|
416
|
-
description:
|
|
417
|
-
schema:
|
|
418
|
-
workspace: zod_1.z.string().optional().describe("Optional workspace ID or name"),
|
|
419
|
-
includeRelationships: zod_1.z.coerce.boolean().optional().default(true).describe("Show ActivityLink relationships between workflows"),
|
|
420
|
-
}),
|
|
425
|
+
description: describeWorkflowsDescription,
|
|
426
|
+
schema: describeWorkflowsSchema,
|
|
421
427
|
async execute(args, context) {
|
|
422
|
-
logger.debug('
|
|
428
|
+
logger.debug('Describing workflows', {
|
|
429
|
+
workflowId: args.workflowId,
|
|
430
|
+
include: args.include,
|
|
431
|
+
detail: args.detail,
|
|
423
432
|
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
424
433
|
});
|
|
425
434
|
try {
|
|
426
|
-
//
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const workspaceFilter = args.workspace;
|
|
431
|
-
workflows = workflows.filter(w => w.cid === workspaceFilter ||
|
|
432
|
-
w.cid === workspaceFilter // Could add name-based lookup here if needed
|
|
433
|
-
);
|
|
435
|
+
// Mode 1: no workflowId → list all workflows
|
|
436
|
+
if (!args.workflowId) {
|
|
437
|
+
const text = args.detail === 'full' ? renderWorkflowListFull(context) : renderWorkflowListMinimal(context);
|
|
438
|
+
return { content: [{ type: 'text', text }] };
|
|
434
439
|
}
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
.filter(([_, field]) => field.type === 'activitylink');
|
|
438
|
-
const initialPhases = Object.values(workflow.phases || {})
|
|
439
|
-
.filter(phase => phase.isInitial)
|
|
440
|
-
.map(phase => ({
|
|
441
|
-
id: phase._id,
|
|
442
|
-
name: phase.name
|
|
443
|
-
}));
|
|
444
|
-
// Calculate linksTo from activitylink fields
|
|
445
|
-
const linksTo = activityLinkFields.flatMap(([_, field]) => field.data || []);
|
|
440
|
+
const workflow = resolveWorkflow(context.init.processes || [], args.workflowId);
|
|
441
|
+
if (!workflow) {
|
|
446
442
|
return {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
isStarred: workflow.isStarred || false,
|
|
452
|
-
hasActivityLinks: activityLinkFields.length > 0,
|
|
453
|
-
linksTo,
|
|
454
|
-
linkedFrom: [], // Would need to scan all workflows - skip for now
|
|
455
|
-
initialPhases: initialPhases,
|
|
443
|
+
content: [{
|
|
444
|
+
type: 'text',
|
|
445
|
+
text: `❌ Workflow "${args.workflowId}" not found`,
|
|
446
|
+
}],
|
|
456
447
|
};
|
|
457
|
-
});
|
|
458
|
-
let responseText = `📋 **${workflows.length} Workflows Found**\n\n`;
|
|
459
|
-
responseText += JSON.stringify(workflowSummary, null, 2);
|
|
460
|
-
if (args.includeRelationships) {
|
|
461
|
-
const relationships = [];
|
|
462
|
-
for (const workflow of workflows) {
|
|
463
|
-
const activityLinkFields = Object.entries(workflow.fields ?? {})
|
|
464
|
-
.filter(([_, field]) => field.type === 'activitylink')
|
|
465
|
-
.map(([fieldId, field]) => ({
|
|
466
|
-
id: fieldId,
|
|
467
|
-
label: field.label,
|
|
468
|
-
key: field.key,
|
|
469
|
-
targetWorkflowIds: field.data || [],
|
|
470
|
-
required: field.required || false,
|
|
471
|
-
}));
|
|
472
|
-
for (const field of activityLinkFields) {
|
|
473
|
-
for (const targetWorkflowId of field.targetWorkflowIds) {
|
|
474
|
-
const targetWorkflow = workflows.find(w => w._id === targetWorkflowId);
|
|
475
|
-
relationships.push({
|
|
476
|
-
sourceWorkflowId: workflow._id,
|
|
477
|
-
sourceWorkflowName: workflow.name,
|
|
478
|
-
targetWorkflowId,
|
|
479
|
-
targetWorkflowName: targetWorkflow?.name || 'Unknown',
|
|
480
|
-
fieldLabel: field.label,
|
|
481
|
-
fieldKey: field.key,
|
|
482
|
-
required: field.required,
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
if (relationships.length > 0) {
|
|
488
|
-
responseText += `\n\n🔗 **Workflow Relationships:**\n`;
|
|
489
|
-
relationships.forEach(rel => {
|
|
490
|
-
responseText += `• ${rel.sourceWorkflowName} → ${rel.targetWorkflowName} (${rel.fieldLabel})\n`;
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
448
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
449
|
+
const include = args.include || [];
|
|
450
|
+
// Mode 2: workflowId without includes → summary
|
|
451
|
+
if (include.length === 0) {
|
|
452
|
+
const prefix = isSdkProject() ? SDK_DISCOVERY_HINT : '';
|
|
453
|
+
return { content: [{ type: 'text', text: prefix + renderWorkflowSummary(workflow) }] };
|
|
454
|
+
}
|
|
455
|
+
// Mode 3: workflowId + includes → schema and/or phases deep dive
|
|
456
|
+
if (isSdkProject() && !args.force) {
|
|
457
|
+
return sdkRedirect('describe_workflows', 'cat workspace/<WorkflowName>_<id>/fields.ts workspace/<WorkflowName>_<id>/phases.ts', 'workspace/<WorkflowName>_<id>/');
|
|
458
|
+
}
|
|
459
|
+
const sections = [];
|
|
460
|
+
if (include.includes('schema')) {
|
|
461
|
+
const schemaText = args.detail === 'full' ? await renderSchemaFull(workflow, context) : renderSchemaCompact(workflow);
|
|
462
|
+
sections.push(schemaText);
|
|
463
|
+
}
|
|
464
|
+
if (include.includes('phases')) {
|
|
465
|
+
sections.push(renderPhasesSection(workflow));
|
|
466
|
+
}
|
|
467
|
+
const prefix = isSdkProject() ? SDK_DISCOVERY_HINT : '';
|
|
468
|
+
return { content: [{ type: 'text', text: prefix + sections.join('\n\n') }] };
|
|
501
469
|
}
|
|
502
470
|
catch (error) {
|
|
503
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
504
|
-
logger.error(
|
|
471
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
472
|
+
logger.error('Failed to describe workflows', error);
|
|
473
|
+
}
|
|
505
474
|
return {
|
|
506
475
|
content: [{
|
|
507
|
-
type:
|
|
508
|
-
text: `❌
|
|
476
|
+
type: 'text',
|
|
477
|
+
text: `❌ Failed to describe workflows: ${error instanceof Error ? error.message : String(error)}`,
|
|
509
478
|
}],
|
|
510
479
|
};
|
|
511
480
|
}
|
|
@@ -519,60 +488,67 @@ exports.listWorkflowsTool = {
|
|
|
519
488
|
// ============================================================================
|
|
520
489
|
const installWorkflowDescription = `Install workflow from template
|
|
521
490
|
|
|
522
|
-
**Field types:** text, textarea, numeric, numericunit, date, datetime, textpredefinedoptions (for dropdowns - NOT 'select'!), activitylink, users, teams, country, subheader
|
|
491
|
+
**Field types:** text, textarea, numeric, numericunit, date, datetime, textpredefinedoptions (for dropdowns - NOT 'select'!), activitylink, users, teams, country, subheader
|
|
492
|
+
|
|
493
|
+
**Workflow vs dataset — pick the right shape:**
|
|
494
|
+
- A WORKFLOW is for things with a lifecycle (sales pipeline, project tracker, support tickets) — model with multiple phases the activity moves through.
|
|
495
|
+
- A DATASET is for reference data (customer list, product catalog, equipment register, vendor list) — items don't move through stages, they sit in categories. Model with a SINGLE phase (\`isInitial: true\`), or at most two (e.g. Active/Archived). Don't create rich multi-phase workflows for reference data — the user will end up with a kanban they never use.
|
|
496
|
+
- When the user's request is ambiguous ('customer list', 'projects'), ask them once whether they want stages or just a list before committing.
|
|
497
|
+
|
|
498
|
+
**IMPORTANT — do NOT include real Mongo ObjectId-shaped \`_id\` values anywhere in the template (workflow, fields, or phases).** The server assigns those itself. The only \`_id\` values allowed are template-local references like \`_0001\` (workflow), \`_1000\` (fields), \`_2000\` (phases). Including a 24-hex-char ObjectId can crash Hailer's bulk insert with a duplicate-key error; any such values are stripped before send as a safety net.`;
|
|
523
499
|
const installWorkflowSchema = zod_1.z.object({
|
|
524
500
|
workspaceId: zod_1.z
|
|
525
501
|
.string()
|
|
526
502
|
.optional()
|
|
527
|
-
.describe(
|
|
503
|
+
.describe('Optional workspace ID or name - defaults to current workspace'),
|
|
528
504
|
workflowTemplates: zod_1.z
|
|
529
505
|
.array(zod_1.z.object({
|
|
530
506
|
_id: zod_1.z
|
|
531
507
|
.string()
|
|
532
|
-
.regex(/^_\d{4}$/,
|
|
508
|
+
.regex(/^_\d{4}$/, 'Workflow _id must match pattern _0001, _0002, etc. (underscore + 4 digits)')
|
|
533
509
|
.optional()
|
|
534
510
|
.describe("Workflow _id for cross-references in activitylink fields (e.g., '_0001', '_0002')"),
|
|
535
|
-
name: zod_1.z.string().min(1).describe(
|
|
536
|
-
description: zod_1.z.string().optional().describe(
|
|
511
|
+
name: zod_1.z.string().min(1).describe('Workflow name'),
|
|
512
|
+
description: zod_1.z.string().optional().describe('Workflow description'),
|
|
537
513
|
fields: zod_1.z
|
|
538
514
|
.record(zod_1.z.object({
|
|
539
|
-
label: zod_1.z.string().describe(
|
|
515
|
+
label: zod_1.z.string().describe('Field label shown in UI'),
|
|
540
516
|
type: zod_1.z.enum([
|
|
541
517
|
'activitylink', 'country', 'teams', 'text', 'textarea', 'textunit',
|
|
542
518
|
'textpredefinedoptions', 'users', 'numeric', 'numericunit', 'date',
|
|
543
519
|
'time', 'datetime', 'daterange', 'timerange', 'datetimerange', 'subheader'
|
|
544
|
-
]).describe(
|
|
545
|
-
key: zod_1.z.string().optional().describe(
|
|
546
|
-
required: zod_1.z.boolean().optional().describe(
|
|
520
|
+
]).describe('Field type'),
|
|
521
|
+
key: zod_1.z.string().optional().describe('Readable field name (like SQL column name) - RECOMMENDED'),
|
|
522
|
+
required: zod_1.z.boolean().optional().describe('Whether field is required'),
|
|
547
523
|
data: zod_1.z.array(zod_1.z.string()).optional().describe("For textpredefinedoptions: string array like [\"Low\", \"Medium\", \"High\"]. For activitylink: target workflow IDs. NOTE: 'options' also accepted, will be converted to 'data'"),
|
|
548
|
-
placeholder: zod_1.z.string().optional().describe(
|
|
549
|
-
unit: zod_1.z.string().optional().describe(
|
|
550
|
-
description: zod_1.z.string().optional().describe(
|
|
551
|
-
editable: zod_1.z.boolean().optional().describe(
|
|
524
|
+
placeholder: zod_1.z.string().optional().describe('Placeholder text'),
|
|
525
|
+
unit: zod_1.z.string().optional().describe('Unit for numeric/textunit fields'),
|
|
526
|
+
description: zod_1.z.string().optional().describe('Field description'),
|
|
527
|
+
editable: zod_1.z.boolean().optional().describe('Whether field is editable'),
|
|
552
528
|
}).passthrough())
|
|
553
529
|
.optional()
|
|
554
|
-
.refine((fields) => !fields || Object.keys(fields).every(id => /^_\d{4}$/.test(id)), { message:
|
|
555
|
-
.describe(
|
|
530
|
+
.refine((fields) => !fields || Object.keys(fields).every(id => /^_\d{4}$/.test(id)), { message: 'Field IDs must match pattern _1000, _1001, etc. (underscore + 4 digits)' })
|
|
531
|
+
.describe('Field definitions keyed by field ID (_1000, _1001, etc.)'),
|
|
556
532
|
phases: zod_1.z
|
|
557
533
|
.record(zod_1.z.object({
|
|
558
|
-
name: zod_1.z.string().describe(
|
|
559
|
-
isInitial: zod_1.z.boolean().optional().describe(
|
|
560
|
-
fields: zod_1.z.array(zod_1.z.string()).optional().describe(
|
|
561
|
-
description: zod_1.z.string().optional().describe(
|
|
534
|
+
name: zod_1.z.string().describe('Phase name'),
|
|
535
|
+
isInitial: zod_1.z.boolean().optional().describe('Whether activities can be created in this phase'),
|
|
536
|
+
fields: zod_1.z.array(zod_1.z.string()).optional().describe('Field IDs visible in this phase (defaults to all)'),
|
|
537
|
+
description: zod_1.z.string().optional().describe('Phase description'),
|
|
562
538
|
}).passthrough())
|
|
563
539
|
.optional()
|
|
564
|
-
.refine((phases) => !phases || Object.keys(phases).every(id => /^_\d{4}$/.test(id)), { message:
|
|
565
|
-
.describe(
|
|
566
|
-
fieldsOrder: zod_1.z.array(zod_1.z.string()).optional().describe(
|
|
567
|
-
phasesOrder: zod_1.z.array(zod_1.z.string()).optional().describe(
|
|
568
|
-
enableMessenger: zod_1.z.boolean().optional().describe(
|
|
569
|
-
enableLinkedAnnouncements: zod_1.z.boolean().optional().describe(
|
|
570
|
-
defaultView: zod_1.z.enum(['timeline', 'table', 'kanban', 'calendar', 'map']).optional().describe(
|
|
540
|
+
.refine((phases) => !phases || Object.keys(phases).every(id => /^_\d{4}$/.test(id)), { message: 'Phase IDs must match pattern _2000, _2001, etc. (underscore + 4 digits)' })
|
|
541
|
+
.describe('Phase definitions keyed by phase ID (_2000, _2001, etc.)'),
|
|
542
|
+
fieldsOrder: zod_1.z.array(zod_1.z.string()).optional().describe('Order of field IDs (auto-generated if omitted)'),
|
|
543
|
+
phasesOrder: zod_1.z.array(zod_1.z.string()).optional().describe('Order of phase IDs (auto-generated if omitted)'),
|
|
544
|
+
enableMessenger: zod_1.z.boolean().optional().describe('Enable discussion features (defaults to true)'),
|
|
545
|
+
enableLinkedAnnouncements: zod_1.z.boolean().optional().describe('Enable announcements (defaults to true)'),
|
|
546
|
+
defaultView: zod_1.z.enum(['timeline', 'table', 'kanban', 'calendar', 'map']).optional().describe('Default view type'),
|
|
571
547
|
}).passthrough())
|
|
572
|
-
.min(1,
|
|
573
|
-
.max(100,
|
|
574
|
-
.describe(
|
|
575
|
-
force: zod_1.z.boolean().optional().describe(
|
|
548
|
+
.min(1, 'At least one workflow template is required')
|
|
549
|
+
.max(100, 'Maximum 100 workflow templates per installation')
|
|
550
|
+
.describe('Array of workflow template objects to install'),
|
|
551
|
+
force: zod_1.z.boolean().optional().describe('Override SDK redirect — use API directly even when workspace/ exists'),
|
|
576
552
|
});
|
|
577
553
|
exports.installWorkflowTool = {
|
|
578
554
|
name: 'install_workflow',
|
|
@@ -597,14 +573,70 @@ exports.installWorkflowTool = {
|
|
|
597
573
|
if (!workspaceId) {
|
|
598
574
|
return {
|
|
599
575
|
content: [{
|
|
600
|
-
type:
|
|
576
|
+
type: 'text',
|
|
601
577
|
text: `❌ Could not resolve workspace`,
|
|
602
578
|
}],
|
|
603
579
|
};
|
|
604
580
|
}
|
|
581
|
+
// LLMs occasionally invent 24-hex-char ObjectIds that look real
|
|
582
|
+
// and stuff them into `_id` slots. Hailer's server-side install
|
|
583
|
+
// path inserts these verbatim via bulkWrite, and a colliding
|
|
584
|
+
// value crashes the API with `MongoBulkWriteError: E11000
|
|
585
|
+
// duplicate key error`. Strip any `_id` that isn't a
|
|
586
|
+
// template-local reference (`_NNNN`) here as a safety net.
|
|
587
|
+
const TEMPLATE_LOCAL_ID_RE = /^_\d{4}$/;
|
|
588
|
+
const stripBadId = (obj, kind) => {
|
|
589
|
+
if (obj && typeof obj === 'object' && '_id' in obj) {
|
|
590
|
+
const id = obj._id;
|
|
591
|
+
if (typeof id !== 'string' || !TEMPLATE_LOCAL_ID_RE.test(id)) {
|
|
592
|
+
logger.warn(`install_workflow: stripped non-template ${kind} _id from payload`, { strippedId: id });
|
|
593
|
+
delete obj._id;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
// Track template-local workflow `_id`s used in this call so we can
|
|
598
|
+
// hand out a unique one to every workflow that doesn't already have
|
|
599
|
+
// a usable id. Why this exists:
|
|
600
|
+
//
|
|
601
|
+
// hailer-api's `WorkflowV3.prepareProcessTemplate` hardcodes any
|
|
602
|
+
// missing workflow `_id` to the sentinel `'_9999'`, then
|
|
603
|
+
// `Company.instanceFromTemplate` rewrites `_NNNN` value-strings to
|
|
604
|
+
// freshly-generated ObjectIds via an `idsMap` that's SHARED across
|
|
605
|
+
// all processes in one call. Two workflows without an `_id` both
|
|
606
|
+
// get `'_9999'`, both map to the same ObjectId, and the bulk
|
|
607
|
+
// insert crashes with `E11000 duplicate key error` on process._id.
|
|
608
|
+
//
|
|
609
|
+
// Assigning a unique `_0NNN` template-local here side-steps the
|
|
610
|
+
// upstream collision entirely — each workflow ends up with a
|
|
611
|
+
// distinct ObjectId. The result map still returns `_0NNN → real id`
|
|
612
|
+
// so the caller (and the workflow-id extraction below) keep working.
|
|
613
|
+
const usedWorkflowIds = new Set();
|
|
614
|
+
let workflowIdCounter = 0;
|
|
615
|
+
const nextWorkflowId = () => {
|
|
616
|
+
let id;
|
|
617
|
+
do {
|
|
618
|
+
id = '_' + String(workflowIdCounter++).padStart(4, '0');
|
|
619
|
+
} while (usedWorkflowIds.has(id));
|
|
620
|
+
usedWorkflowIds.add(id);
|
|
621
|
+
return id;
|
|
622
|
+
};
|
|
605
623
|
// Transform templates: fix common LLM mistakes
|
|
606
624
|
const transformedTemplates = args.workflowTemplates.map((template) => {
|
|
607
|
-
|
|
625
|
+
const result = { ...template };
|
|
626
|
+
stripBadId(result, 'workflow');
|
|
627
|
+
// Ensure each workflow has a unique template-local `_id` in
|
|
628
|
+
// this call. See block comment above for the hailer-api bug
|
|
629
|
+
// this works around.
|
|
630
|
+
const existingId = result._id;
|
|
631
|
+
if (typeof existingId === 'string' && TEMPLATE_LOCAL_ID_RE.test(existingId) && !usedWorkflowIds.has(existingId)) {
|
|
632
|
+
usedWorkflowIds.add(existingId);
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
if (existingId !== undefined) {
|
|
636
|
+
logger.warn('install_workflow: duplicate or invalid workflow template _id — reassigning', { existingId });
|
|
637
|
+
}
|
|
638
|
+
result._id = nextWorkflowId();
|
|
639
|
+
}
|
|
608
640
|
// Transform fields
|
|
609
641
|
if (template.fields) {
|
|
610
642
|
const transformedFields = {};
|
|
@@ -632,6 +664,7 @@ exports.installWorkflowTool = {
|
|
|
632
664
|
delete f.name; // Only 'label' is allowed
|
|
633
665
|
delete f.sequence; // Not supported
|
|
634
666
|
delete f.order; // Not supported
|
|
667
|
+
stripBadId(f, 'field');
|
|
635
668
|
transformedFields[fieldId] = f;
|
|
636
669
|
}
|
|
637
670
|
result.fields = transformedFields;
|
|
@@ -643,6 +676,7 @@ exports.installWorkflowTool = {
|
|
|
643
676
|
const p = { ...phase };
|
|
644
677
|
delete p.sequence;
|
|
645
678
|
delete p.order;
|
|
679
|
+
stripBadId(p, 'phase');
|
|
646
680
|
transformedPhases[phaseId] = p;
|
|
647
681
|
}
|
|
648
682
|
result.phases = transformedPhases;
|
|
@@ -682,8 +716,9 @@ exports.installWorkflowTool = {
|
|
|
682
716
|
// Fallback: if no _0xxx pattern, take all values that look like workflow IDs
|
|
683
717
|
if (newWorkflowIds.length === 0) {
|
|
684
718
|
for (const [, id] of Object.entries(result)) {
|
|
685
|
-
if (id.length === 24)
|
|
719
|
+
if (id.length === 24) {
|
|
686
720
|
newWorkflowIds.push(id);
|
|
721
|
+
}
|
|
687
722
|
break; // Just take the first one
|
|
688
723
|
}
|
|
689
724
|
}
|
|
@@ -749,12 +784,15 @@ exports.installWorkflowTool = {
|
|
|
749
784
|
if (keyResults.length > 0) {
|
|
750
785
|
const kr = keyResults[0].keys;
|
|
751
786
|
responseText += `**🔑 Auto-generated keys:**\n`;
|
|
752
|
-
if (kr.workflow)
|
|
787
|
+
if (kr.workflow) {
|
|
753
788
|
responseText += `- Workflow: \`${kr.workflow}\`\n`;
|
|
754
|
-
|
|
789
|
+
}
|
|
790
|
+
for (const [, key] of Object.entries(kr.phases)) {
|
|
755
791
|
responseText += `- Phase: \`${key}\`\n`;
|
|
756
|
-
|
|
792
|
+
}
|
|
793
|
+
for (const [, key] of Object.entries(kr.fields)) {
|
|
757
794
|
responseText += `- Field: \`${key}\`\n`;
|
|
795
|
+
}
|
|
758
796
|
if (kr.errors.length > 0) {
|
|
759
797
|
responseText += `- ⚠️ ${kr.errors.length} key(s) failed\n`;
|
|
760
798
|
}
|
|
@@ -770,35 +808,38 @@ exports.installWorkflowTool = {
|
|
|
770
808
|
responseText += `{\n`;
|
|
771
809
|
responseText += ` "workflowId": "${exampleWorkflow}",\n`;
|
|
772
810
|
responseText += ` "name": "New Activity",\n`;
|
|
773
|
-
if (examplePhase)
|
|
811
|
+
if (examplePhase) {
|
|
774
812
|
responseText += ` "phaseId": "${examplePhase}",\n`;
|
|
775
|
-
|
|
813
|
+
}
|
|
814
|
+
if (exampleField) {
|
|
776
815
|
responseText += ` "fields": { "${exampleField}": "value" }\n`;
|
|
816
|
+
}
|
|
777
817
|
responseText += `}\n`;
|
|
778
818
|
responseText += `\`\`\``;
|
|
779
819
|
return {
|
|
780
820
|
content: [{
|
|
781
|
-
type:
|
|
821
|
+
type: 'text',
|
|
782
822
|
text: responseText,
|
|
783
823
|
}],
|
|
784
824
|
};
|
|
785
825
|
}
|
|
786
826
|
catch (error) {
|
|
787
827
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
788
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
789
|
-
logger.error(
|
|
828
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
829
|
+
logger.error('Error installing workflow', new Error(errorMessage));
|
|
830
|
+
}
|
|
790
831
|
// Handle permission errors
|
|
791
832
|
if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied')) {
|
|
792
833
|
return {
|
|
793
834
|
content: [{
|
|
794
|
-
type:
|
|
835
|
+
type: 'text',
|
|
795
836
|
text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to install workflows.\n\n**Error:** ${errorMessage}`,
|
|
796
837
|
}],
|
|
797
838
|
};
|
|
798
839
|
}
|
|
799
840
|
return {
|
|
800
841
|
content: [{
|
|
801
|
-
type:
|
|
842
|
+
type: 'text',
|
|
802
843
|
text: `❌ **Error installing workflow**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Templates must have valid structure (name, fields, phases)\n- Field/Phase IDs must match pattern _0001, _1000, _2000 (underscore + 4 digits)\n- Workspace ID must be valid`,
|
|
803
844
|
}],
|
|
804
845
|
};
|
|
@@ -812,20 +853,20 @@ const removeWorkflowDescription = `Delete workflow permanently`;
|
|
|
812
853
|
const removeWorkflowSchema = zod_1.z.object({
|
|
813
854
|
workflowId: zod_1.z
|
|
814
855
|
.string()
|
|
815
|
-
.min(1,
|
|
816
|
-
.describe(
|
|
856
|
+
.min(1, 'Workflow ID is required')
|
|
857
|
+
.describe('The workflow ID or key to remove (get from list_workflows)'),
|
|
817
858
|
workspaceId: zod_1.z
|
|
818
859
|
.string()
|
|
819
860
|
.optional()
|
|
820
|
-
.describe(
|
|
861
|
+
.describe('Optional workspace ID or name - defaults to current workspace'),
|
|
821
862
|
confirmed: zod_1.z
|
|
822
863
|
.boolean()
|
|
823
864
|
.optional()
|
|
824
|
-
.describe(
|
|
865
|
+
.describe('First confirmation - must be true to proceed'),
|
|
825
866
|
secondConfirmed: zod_1.z
|
|
826
867
|
.boolean()
|
|
827
868
|
.optional()
|
|
828
|
-
.describe(
|
|
869
|
+
.describe('Second confirmation - must be true to proceed (required for double-check safety)'),
|
|
829
870
|
});
|
|
830
871
|
exports.removeWorkflowTool = {
|
|
831
872
|
name: 'remove_workflow',
|
|
@@ -845,7 +886,7 @@ exports.removeWorkflowTool = {
|
|
|
845
886
|
if (!workflow) {
|
|
846
887
|
return {
|
|
847
888
|
content: [{
|
|
848
|
-
type:
|
|
889
|
+
type: 'text',
|
|
849
890
|
text: `❌ Workflow "${args.workflowId}" not found`,
|
|
850
891
|
}],
|
|
851
892
|
};
|
|
@@ -883,7 +924,7 @@ exports.removeWorkflowTool = {
|
|
|
883
924
|
warningText += `- Verify with user that this is intentional`;
|
|
884
925
|
return {
|
|
885
926
|
content: [{
|
|
886
|
-
type:
|
|
927
|
+
type: 'text',
|
|
887
928
|
text: warningText,
|
|
888
929
|
}],
|
|
889
930
|
};
|
|
@@ -911,20 +952,21 @@ exports.removeWorkflowTool = {
|
|
|
911
952
|
responseText += `💡 Use \`list_workflows\` to see remaining workflows in the workspace.`;
|
|
912
953
|
return {
|
|
913
954
|
content: [{
|
|
914
|
-
type:
|
|
955
|
+
type: 'text',
|
|
915
956
|
text: responseText,
|
|
916
957
|
}],
|
|
917
958
|
};
|
|
918
959
|
}
|
|
919
960
|
catch (error) {
|
|
920
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
921
|
-
logger.error(
|
|
961
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
962
|
+
logger.error('Error removing workflow', error);
|
|
963
|
+
}
|
|
922
964
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
923
965
|
// Handle permission errors
|
|
924
966
|
if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
|
|
925
967
|
return {
|
|
926
968
|
content: [{
|
|
927
|
-
type:
|
|
969
|
+
type: 'text',
|
|
928
970
|
text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to remove workflows.\n\n**Error:** ${errorMessage}`,
|
|
929
971
|
}],
|
|
930
972
|
};
|
|
@@ -933,14 +975,14 @@ exports.removeWorkflowTool = {
|
|
|
933
975
|
if (errorMessage.includes('not found') || errorMessage.includes('NotFound')) {
|
|
934
976
|
return {
|
|
935
977
|
content: [{
|
|
936
|
-
type:
|
|
978
|
+
type: 'text',
|
|
937
979
|
text: `❌ **Workflow Not Found**\n\nThe specified workflow does not exist or you don't have access to it.\n\n**Workflow ID:** \`${args.workflowId}\`\n\n**Error:** ${errorMessage}\n\n💡 Use \`list_workflows\` to see available workflows.`,
|
|
938
980
|
}],
|
|
939
981
|
};
|
|
940
982
|
}
|
|
941
983
|
return {
|
|
942
984
|
content: [{
|
|
943
|
-
type:
|
|
985
|
+
type: 'text',
|
|
944
986
|
text: `❌ **Error removing workflow**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID must be valid and exist in the workspace\n- Workflow must not be referenced by other workflows (check ActivityLinks)`,
|
|
945
987
|
}],
|
|
946
988
|
};
|
|
@@ -948,142 +990,400 @@ exports.removeWorkflowTool = {
|
|
|
948
990
|
}
|
|
949
991
|
};
|
|
950
992
|
// ============================================================================
|
|
951
|
-
// TOOL 3: UPDATE WORKFLOW
|
|
993
|
+
// TOOL 3: UPDATE WORKFLOW STRUCTURE (create/update fields and phases)
|
|
952
994
|
// ============================================================================
|
|
953
|
-
const
|
|
954
|
-
const
|
|
995
|
+
const updateWorkflowStructureDescription = `Modify workflow structure. Actions: create_field (field.label + field.type required; type is permanent), update_field (fieldId + field required), create_phase (adds a phase named "New Phase" — rename it via update_phase), update_phase (phaseId + phase required; name/description/color). update_field auto-generates a camelCase key from field.label when no key is given — set autoGenerateKey:false when changing only the label. Field types: text, textarea, numeric, numericunit, date, datetime, textpredefinedoptions (dropdown), activitylink, users, teams.`;
|
|
996
|
+
const updateWorkflowStructureSchema = zod_1.z.object({
|
|
955
997
|
workflowId: zod_1.z
|
|
956
998
|
.string()
|
|
957
|
-
.min(1,
|
|
958
|
-
.describe(
|
|
959
|
-
|
|
960
|
-
.
|
|
961
|
-
.
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
.describe(
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
.
|
|
972
|
-
.
|
|
973
|
-
.optional()
|
|
974
|
-
.describe(
|
|
999
|
+
.min(1, 'Workflow ID is required')
|
|
1000
|
+
.describe('The workflow ID (24-char) or key to modify'),
|
|
1001
|
+
action: zod_1.z
|
|
1002
|
+
.enum(['create_field', 'update_field', 'create_phase', 'update_phase'])
|
|
1003
|
+
.describe('Structure operation to perform'),
|
|
1004
|
+
fieldId: zod_1.z.string().optional().describe('Field ID to update (required for update_field)'),
|
|
1005
|
+
phaseId: zod_1.z.string().optional().describe('Phase ID or key to update (required for update_phase)'),
|
|
1006
|
+
field: zod_1.z.object({
|
|
1007
|
+
label: zod_1.z.string().optional().describe('Field display label (required for create_field)'),
|
|
1008
|
+
type: zod_1.z.enum([
|
|
1009
|
+
'text', 'textarea', 'numeric', 'numericunit',
|
|
1010
|
+
'date', 'datetime', 'daterange', 'datetimerange', 'time', 'timerange',
|
|
1011
|
+
'textpredefinedoptions', 'activitylink', 'users', 'teams',
|
|
1012
|
+
'country', 'linkedfrom', 'subheader'
|
|
1013
|
+
]).optional().describe('Field type (required for create_field; cannot be changed after creation)'),
|
|
1014
|
+
key: zod_1.z.string().optional().describe('Unique field key (for programmatic access)'),
|
|
1015
|
+
unit: zod_1.z.string().optional().describe("Unit for numericunit fields (e.g. '€', 'kg')"),
|
|
1016
|
+
data: zod_1.z.array(zod_1.z.string()).optional().describe('For textpredefinedoptions: option values. For activitylink: target workflow IDs'),
|
|
1017
|
+
required: zod_1.z.boolean().optional().describe('Whether field is required'),
|
|
1018
|
+
description: zod_1.z.string().optional().describe('Field description/help text'),
|
|
1019
|
+
placeholder: zod_1.z.string().optional().describe('Placeholder text'),
|
|
1020
|
+
defaultTo: zod_1.z.boolean().optional().describe('Enable default value'),
|
|
1021
|
+
defaultValue: zod_1.z.string().optional().describe('Default value if defaultTo is enabled'),
|
|
1022
|
+
}).passthrough().optional().describe('Field definition (create_field) or properties to change (update_field)'),
|
|
1023
|
+
phase: zod_1.z.object({
|
|
1024
|
+
name: zod_1.z.string().optional().describe('New phase name'),
|
|
1025
|
+
description: zod_1.z.string().optional().describe('New phase description'),
|
|
1026
|
+
color: zod_1.z.string().optional().describe('Phase color code'),
|
|
1027
|
+
}).passthrough().optional().describe('Phase properties to update (update_phase)'),
|
|
975
1028
|
autoGenerateKey: zod_1.z
|
|
976
1029
|
.boolean()
|
|
977
|
-
.default(true)
|
|
978
1030
|
.optional()
|
|
979
|
-
.
|
|
980
|
-
|
|
1031
|
+
.default(true)
|
|
1032
|
+
.describe('update_field only: auto-generate camelCase key from field.label if key not provided (default: true). Set to false when updating ONLY the label to prevent key regeneration errors.'),
|
|
1033
|
+
force: zod_1.z.boolean().optional().describe('Override SDK redirect — use API directly even when workspace/ exists'),
|
|
981
1034
|
});
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1035
|
+
/** Build a validation error response for update_workflow_structure */
|
|
1036
|
+
function structureValidationError(message) {
|
|
1037
|
+
return {
|
|
1038
|
+
content: [{
|
|
1039
|
+
type: 'text',
|
|
1040
|
+
text: `❌ **Invalid update_workflow_structure call**\n\n${message}`,
|
|
1041
|
+
}],
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
/** create_field action — former create_workflow_field body */
|
|
1045
|
+
async function executeCreateField(workflowId, field, context) {
|
|
1046
|
+
logger.debug('Creating workflow field', {
|
|
1047
|
+
workflowId,
|
|
1048
|
+
fieldLabel: field.label,
|
|
1049
|
+
fieldType: field.type,
|
|
1050
|
+
});
|
|
1051
|
+
try {
|
|
1052
|
+
if (workflowId.length !== 24) {
|
|
1053
|
+
return {
|
|
1054
|
+
content: [{
|
|
1055
|
+
type: 'text',
|
|
1056
|
+
text: `Invalid workflowId "${workflowId}" - must be a 24-character ID.\n\n**How to get valid workflow IDs:**\n\`\`\`\ndescribe_workflows()\n\`\`\``,
|
|
1057
|
+
}],
|
|
1058
|
+
};
|
|
990
1059
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1060
|
+
// Call RPC endpoint process.create_field
|
|
1061
|
+
const newField = await context.hailer.request('process.create_field', [
|
|
1062
|
+
workflowId,
|
|
1063
|
+
field
|
|
1064
|
+
]);
|
|
1065
|
+
logger.debug('Workflow field created', {
|
|
1066
|
+
workflowId,
|
|
1067
|
+
fieldId: newField?._id,
|
|
1068
|
+
fieldLabel: newField?.label,
|
|
995
1069
|
});
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1070
|
+
let responseText = `✅ **Field Created Successfully**\n\n`;
|
|
1071
|
+
responseText += `**Workflow ID:** \`${workflowId}\`\n`;
|
|
1072
|
+
responseText += `**Field ID:** \`${newField._id}\`\n`;
|
|
1073
|
+
responseText += `**Label:** ${newField.label}\n`;
|
|
1074
|
+
responseText += `**Type:** ${newField.type}\n`;
|
|
1075
|
+
if (newField.key) {
|
|
1076
|
+
responseText += `**Key:** ${newField.key}\n`;
|
|
1077
|
+
}
|
|
1078
|
+
if (newField.unit) {
|
|
1079
|
+
responseText += `**Unit:** ${newField.unit}\n`;
|
|
1080
|
+
}
|
|
1081
|
+
if (newField.data?.length) {
|
|
1082
|
+
responseText += `**Options/Links:** ${newField.data.join(', ')}\n`;
|
|
1083
|
+
}
|
|
1084
|
+
responseText += `\n💡 **Next Steps:**\n`;
|
|
1085
|
+
responseText += `- Use this field ID in \`create_activity\` or \`update_activity\` to set values\n`;
|
|
1086
|
+
responseText += `- Use \`describe_workflows\` with include: ['schema'] to verify the field was added\n`;
|
|
1087
|
+
return {
|
|
1088
|
+
content: [{
|
|
1089
|
+
type: 'text',
|
|
1090
|
+
text: responseText,
|
|
1091
|
+
}],
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
catch (error) {
|
|
1095
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1096
|
+
logger.error('Error creating workflow field', error);
|
|
1097
|
+
}
|
|
1098
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1099
|
+
if (errorMessage.includes('Permission') || errorMessage.includes('permission')) {
|
|
1100
|
+
return {
|
|
1101
|
+
content: [{
|
|
1102
|
+
type: 'text',
|
|
1103
|
+
text: `❌ **Permission Denied**\n\nYou must be a workflow administrator to create fields.\n\n**Error:** ${errorMessage}`,
|
|
1104
|
+
}],
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
if (errorMessage.includes('key')) {
|
|
1108
|
+
return {
|
|
1109
|
+
content: [{
|
|
1110
|
+
type: 'text',
|
|
1111
|
+
text: `❌ **Duplicate Key**\n\n${errorMessage}\n\nUse a different \`key\` value or omit it to auto-generate.`,
|
|
1112
|
+
}],
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
return {
|
|
1116
|
+
content: [{
|
|
1117
|
+
type: 'text',
|
|
1118
|
+
text: `❌ **Error creating field**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workflow administrator\n- Workflow ID must be valid (24 characters)\n- Field type must be valid\n- Field key must be unique within workflow`,
|
|
1119
|
+
}],
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
/** update_field action — former update_workflow_field body */
|
|
1124
|
+
async function executeUpdateField(workflowId, fieldId, field, autoGenerateKey, context) {
|
|
1125
|
+
logger.debug('Updating workflow field', {
|
|
1126
|
+
workflowId,
|
|
1127
|
+
fieldId,
|
|
1128
|
+
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
1129
|
+
});
|
|
1130
|
+
try {
|
|
1131
|
+
const workspaceId = context.init.network?._id;
|
|
1132
|
+
// Process field data - auto-generate key from label if requested
|
|
1133
|
+
const fieldData = { ...field };
|
|
1134
|
+
if (autoGenerateKey && fieldData.label && !fieldData.key) {
|
|
1135
|
+
const generatedKey = labelToCamelCase(fieldData.label);
|
|
1136
|
+
fieldData.key = generatedKey;
|
|
1137
|
+
logger.debug('Auto-generated key from label', {
|
|
1138
|
+
label: fieldData.label,
|
|
1139
|
+
key: generatedKey
|
|
1040
1140
|
});
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1141
|
+
}
|
|
1142
|
+
const language = 'en';
|
|
1143
|
+
logger.debug('Calling process.update_field', {
|
|
1144
|
+
workflowId,
|
|
1145
|
+
fieldId,
|
|
1146
|
+
language,
|
|
1147
|
+
fieldData
|
|
1148
|
+
});
|
|
1149
|
+
// Call process.update_field endpoint
|
|
1150
|
+
await context.hailer.request('process.update_field', [
|
|
1151
|
+
workflowId,
|
|
1152
|
+
fieldId,
|
|
1153
|
+
fieldData,
|
|
1154
|
+
language
|
|
1155
|
+
]);
|
|
1156
|
+
logger.debug('Workflow field update successful', {
|
|
1157
|
+
workflowId,
|
|
1158
|
+
fieldId
|
|
1159
|
+
});
|
|
1160
|
+
// Build success response
|
|
1161
|
+
let responseText = `✅ **Workflow Field Updated Successfully**\n\n`;
|
|
1162
|
+
responseText += `**Workflow ID:** \`${workflowId}\`\n`;
|
|
1163
|
+
responseText += `**Field ID:** \`${fieldId}\`\n`;
|
|
1164
|
+
responseText += `**Workspace:** ${workspaceId}\n\n`;
|
|
1165
|
+
responseText += `**Updated Properties:**\n`;
|
|
1166
|
+
Object.entries(fieldData).forEach(([key, value]) => {
|
|
1167
|
+
const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
1168
|
+
responseText += `- ${key}: \`${valueStr}\`\n`;
|
|
1169
|
+
});
|
|
1170
|
+
responseText += `\n💡 **Next Steps:**\n`;
|
|
1171
|
+
responseText += `- Use \`describe_workflows\` with include: ['schema'] to verify the field changes\n`;
|
|
1172
|
+
responseText += `- Use \`list_activities\` with \`returnFlat: true\` to see the key in action\n`;
|
|
1173
|
+
if (fieldData.key) {
|
|
1174
|
+
responseText += `\n**Using the new key:**\n`;
|
|
1175
|
+
responseText += `When creating/updating activities with \`returnFlat: true\`, use:\n`;
|
|
1176
|
+
responseText += `\`\`\`javascript\n`;
|
|
1177
|
+
responseText += `fields: { "${fieldData.key}": "value" }\n`;
|
|
1178
|
+
responseText += `\`\`\``;
|
|
1179
|
+
}
|
|
1180
|
+
return {
|
|
1181
|
+
content: [{
|
|
1182
|
+
type: 'text',
|
|
1183
|
+
text: responseText,
|
|
1184
|
+
}],
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
catch (error) {
|
|
1188
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1189
|
+
logger.error('Error updating workflow field', error);
|
|
1190
|
+
}
|
|
1191
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1192
|
+
// Handle permission errors
|
|
1193
|
+
if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
|
|
1051
1194
|
return {
|
|
1052
1195
|
content: [{
|
|
1053
|
-
type:
|
|
1054
|
-
text:
|
|
1196
|
+
type: 'text',
|
|
1197
|
+
text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow fields.\n\n**Error:** ${errorMessage}`,
|
|
1055
1198
|
}],
|
|
1056
1199
|
};
|
|
1057
1200
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1201
|
+
// Handle not found errors
|
|
1202
|
+
if (errorMessage.includes('not found') || errorMessage.includes('NotFound')) {
|
|
1203
|
+
return {
|
|
1204
|
+
content: [{
|
|
1205
|
+
type: 'text',
|
|
1206
|
+
text: `❌ **Workflow or Field Not Found**\n\nThe specified workflow or field does not exist.\n\n**Workflow ID:** \`${workflowId}\`\n**Field ID:** \`${fieldId}\`\n\n**Error:** ${errorMessage}\n\n💡 Use \`describe_workflows\` to see available workflows and fields.`,
|
|
1207
|
+
}],
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
return {
|
|
1211
|
+
content: [{
|
|
1212
|
+
type: 'text',
|
|
1213
|
+
text: `❌ **Error updating workflow field**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID and Field ID must be valid\n- Field data must match field type requirements\n- Some field types may have restrictions on updates`,
|
|
1214
|
+
}],
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
/** create_phase action — former create_workflow_phase body */
|
|
1219
|
+
async function executeCreatePhase(workflowId, context) {
|
|
1220
|
+
logger.debug('Creating workflow phase', {
|
|
1221
|
+
workflowId,
|
|
1222
|
+
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
1223
|
+
});
|
|
1224
|
+
try {
|
|
1225
|
+
// Validate workflowId format
|
|
1226
|
+
if (workflowId.length !== 24) {
|
|
1227
|
+
return {
|
|
1228
|
+
content: [{
|
|
1229
|
+
type: 'text',
|
|
1230
|
+
text: `Invalid workflowId "${workflowId}" - must be a 24-character ID.\n\n**How to get valid workflow IDs:**\n\`\`\`\ndescribe_workflows()\n\`\`\``,
|
|
1231
|
+
}],
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
// Call RPC endpoint phase.create
|
|
1235
|
+
const newPhase = await context.hailer.request('phase.create', [workflowId]);
|
|
1236
|
+
logger.debug('Workflow phase created', {
|
|
1237
|
+
workflowId,
|
|
1238
|
+
phaseId: newPhase?._id
|
|
1239
|
+
});
|
|
1240
|
+
let responseText = `✅ **Phase Created Successfully**\n\n`;
|
|
1241
|
+
responseText += `**Workflow ID:** \`${workflowId}\`\n`;
|
|
1242
|
+
responseText += `**New Phase ID:** \`${newPhase._id}\`\n`;
|
|
1243
|
+
responseText += `**Name:** ${newPhase.name}\n\n`;
|
|
1244
|
+
responseText += `💡 **Next Steps:**\n`;
|
|
1245
|
+
responseText += `- Rename: \`update_workflow_structure({ workflowId: "${workflowId}", action: "update_phase", ` +
|
|
1246
|
+
`phaseId: "${newPhase._id}", phase: { name: "Your Phase Name" } })\`\n`;
|
|
1247
|
+
responseText += `- Verify: \`describe_workflows({ workflowId: "${workflowId}", include: ["phases"] })\`\n`;
|
|
1248
|
+
return {
|
|
1249
|
+
content: [{
|
|
1250
|
+
type: 'text',
|
|
1251
|
+
text: responseText,
|
|
1252
|
+
}],
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
catch (error) {
|
|
1256
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1257
|
+
logger.error('Error creating workflow phase', error);
|
|
1258
|
+
}
|
|
1259
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1260
|
+
if (errorMessage.includes('Permission') || errorMessage.includes('permission')) {
|
|
1261
|
+
return {
|
|
1262
|
+
content: [{
|
|
1263
|
+
type: 'text',
|
|
1264
|
+
text: `❌ **Permission Denied**\n\nYou must be a workflow administrator to create phases.\n\n**Error:** ${errorMessage}`,
|
|
1265
|
+
}],
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
return {
|
|
1269
|
+
content: [{
|
|
1270
|
+
type: 'text',
|
|
1271
|
+
text: `❌ **Error creating phase**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workflow administrator\n- Workflow ID must be valid (24 characters)\n- Use \`describe_workflows\` to find workflow IDs`,
|
|
1272
|
+
}],
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
/** update_phase action — former update_workflow_phase body */
|
|
1277
|
+
async function executeUpdatePhase(workflowId, phaseId, phase, context) {
|
|
1278
|
+
logger.debug('Updating workflow phase', {
|
|
1279
|
+
workflowId,
|
|
1280
|
+
phaseId,
|
|
1281
|
+
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
1282
|
+
});
|
|
1283
|
+
try {
|
|
1284
|
+
const workspaceId = context.init.network?._id;
|
|
1285
|
+
const phaseData = phase;
|
|
1286
|
+
const language = 'en'; // Default language
|
|
1287
|
+
logger.debug('Calling RPC phase.update', {
|
|
1288
|
+
workflowId,
|
|
1289
|
+
phaseId,
|
|
1290
|
+
phaseData
|
|
1291
|
+
});
|
|
1292
|
+
// Call RPC endpoint phase.update
|
|
1293
|
+
// Args: [processId, phaseId, phaseSettings, language]
|
|
1294
|
+
await context.hailer.request('phase.update', [
|
|
1295
|
+
workflowId,
|
|
1296
|
+
phaseId,
|
|
1297
|
+
phaseData,
|
|
1298
|
+
language
|
|
1299
|
+
]);
|
|
1300
|
+
logger.debug('Workflow phase update successful', {
|
|
1301
|
+
workflowId,
|
|
1302
|
+
phaseId
|
|
1303
|
+
});
|
|
1304
|
+
// Build success response
|
|
1305
|
+
let responseText = `✅ **Workflow Phase Updated Successfully**\n\n`;
|
|
1306
|
+
responseText += `**Workflow ID:** \`${workflowId}\`\n`;
|
|
1307
|
+
responseText += `**Phase ID:** \`${phaseId}\`\n`;
|
|
1308
|
+
responseText += `**Workspace:** ${workspaceId}\n\n`;
|
|
1309
|
+
responseText += `**Updated Properties:**\n`;
|
|
1310
|
+
Object.entries(phaseData).forEach(([key, value]) => {
|
|
1311
|
+
const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
1312
|
+
responseText += `- ${key}: \`${valueStr}\`\n`;
|
|
1313
|
+
});
|
|
1314
|
+
responseText += `\n💡 **Next Steps:**\n`;
|
|
1315
|
+
responseText += `- Use \`describe_workflows\` with include: ['phases'] to verify the phase changes\n`;
|
|
1316
|
+
responseText += `- Phase changes will be immediately visible in the workflow\n`;
|
|
1317
|
+
return {
|
|
1318
|
+
content: [{
|
|
1319
|
+
type: 'text',
|
|
1320
|
+
text: responseText,
|
|
1321
|
+
}],
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
catch (error) {
|
|
1325
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1326
|
+
logger.error('Error updating workflow phase', error);
|
|
1327
|
+
}
|
|
1328
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1329
|
+
// Handle permission errors
|
|
1330
|
+
if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
|
|
1331
|
+
return {
|
|
1332
|
+
content: [{
|
|
1333
|
+
type: 'text',
|
|
1334
|
+
text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow phases.\n\n**Error:** ${errorMessage}`,
|
|
1335
|
+
}],
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
// Handle method not found errors
|
|
1339
|
+
if (errorMessage.includes('Method not found')) {
|
|
1080
1340
|
return {
|
|
1081
1341
|
content: [{
|
|
1082
|
-
type:
|
|
1083
|
-
text: `❌ **
|
|
1342
|
+
type: 'text',
|
|
1343
|
+
text: `❌ **API Method Not Available**\n\nThe \`process.update_phase\` API method may not be available in this Hailer version.\n\n**Alternative:** Use the Hailer web interface to update phase names manually.\n\n**Error:** ${errorMessage}`,
|
|
1084
1344
|
}],
|
|
1085
1345
|
};
|
|
1086
1346
|
}
|
|
1347
|
+
return {
|
|
1348
|
+
content: [{
|
|
1349
|
+
type: 'text',
|
|
1350
|
+
text: `❌ **Error updating workflow phase**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID must be valid (24 characters)\n- Phase ID must exist in the workflow\n- Use \`describe_workflows\` with include: ['phases'] to find phase IDs`,
|
|
1351
|
+
}],
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
exports.updateWorkflowStructureTool = {
|
|
1356
|
+
name: 'update_workflow_structure',
|
|
1357
|
+
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
1358
|
+
description: updateWorkflowStructureDescription,
|
|
1359
|
+
schema: updateWorkflowStructureSchema,
|
|
1360
|
+
async execute(args, context) {
|
|
1361
|
+
// SDK redirect applies to update actions only (create actions never redirected)
|
|
1362
|
+
if (args.action === 'update_field' && isSdkProject() && !args.force) {
|
|
1363
|
+
return sdkRedirect('update_workflow_structure', 'npm run fields-push:force', 'workspace/<WorkflowName>_<id>/fields.ts');
|
|
1364
|
+
}
|
|
1365
|
+
if (args.action === 'update_phase' && isSdkProject() && !args.force) {
|
|
1366
|
+
return sdkRedirect('update_workflow_structure', 'npm run phases-push:force', 'workspace/<WorkflowName>_<id>/phases.ts');
|
|
1367
|
+
}
|
|
1368
|
+
if (args.action === 'create_field' && (!args.field?.label || !args.field?.type)) {
|
|
1369
|
+
return structureValidationError("action 'create_field' requires a `field` object with at least `label` and `type`.");
|
|
1370
|
+
}
|
|
1371
|
+
if (args.action === 'create_field') {
|
|
1372
|
+
return executeCreateField(args.workflowId, args.field, context);
|
|
1373
|
+
}
|
|
1374
|
+
if (args.action === 'update_field' && (!args.fieldId || !args.field)) {
|
|
1375
|
+
return structureValidationError("action 'update_field' requires `fieldId` and a `field` object with the properties to change.");
|
|
1376
|
+
}
|
|
1377
|
+
if (args.action === 'update_field') {
|
|
1378
|
+
return executeUpdateField(args.workflowId, args.fieldId, args.field, args.autoGenerateKey ?? true, context);
|
|
1379
|
+
}
|
|
1380
|
+
if (args.action === 'create_phase') {
|
|
1381
|
+
return executeCreatePhase(args.workflowId, context);
|
|
1382
|
+
}
|
|
1383
|
+
if (!args.phaseId || !args.phase) {
|
|
1384
|
+
return structureValidationError("action 'update_phase' requires `phaseId` and a `phase` object (name/description/color).");
|
|
1385
|
+
}
|
|
1386
|
+
return executeUpdatePhase(args.workflowId, args.phaseId, args.phase, context);
|
|
1087
1387
|
}
|
|
1088
1388
|
};
|
|
1089
1389
|
// ============================================================================
|
|
@@ -1093,23 +1393,23 @@ const testFunctionFieldDescription = `Test function field code against an activi
|
|
|
1093
1393
|
const testFunctionFieldSchema = zod_1.z.object({
|
|
1094
1394
|
activityId: zod_1.z
|
|
1095
1395
|
.string()
|
|
1096
|
-
.min(1,
|
|
1097
|
-
.describe(
|
|
1396
|
+
.min(1, 'Activity ID is required')
|
|
1397
|
+
.describe('Activity ID to test the function against (must have dependency field values)'),
|
|
1098
1398
|
fieldId: zod_1.z
|
|
1099
1399
|
.string()
|
|
1100
|
-
.min(1,
|
|
1101
|
-
.describe(
|
|
1400
|
+
.min(1, 'Field ID is required')
|
|
1401
|
+
.describe('Field ID for context and to get field configuration (label, type, etc.)'),
|
|
1102
1402
|
function: zod_1.z
|
|
1103
1403
|
.string()
|
|
1104
|
-
.min(1,
|
|
1105
|
-
.describe(
|
|
1404
|
+
.min(1, 'Function code is required')
|
|
1405
|
+
.describe('JavaScript function code to test - access dependencies via dep.variableName'),
|
|
1106
1406
|
functionVariables: zod_1.z
|
|
1107
1407
|
.record(zod_1.z.object({
|
|
1108
1408
|
type: zod_1.z.string().describe("Dependency type - use '=' for same-activity field"),
|
|
1109
|
-
data: zod_1.z.array(zod_1.z.string()).describe(
|
|
1409
|
+
data: zod_1.z.array(zod_1.z.string()).describe('Array with field ID to depend on')
|
|
1110
1410
|
}))
|
|
1111
1411
|
.optional()
|
|
1112
|
-
.describe(
|
|
1412
|
+
.describe('Optional function dependencies - if not provided, reads from field definition'),
|
|
1113
1413
|
});
|
|
1114
1414
|
exports.testFunctionFieldTool = {
|
|
1115
1415
|
name: 'test_function_field',
|
|
@@ -1127,7 +1427,7 @@ exports.testFunctionFieldTool = {
|
|
|
1127
1427
|
if (!activity?.process) {
|
|
1128
1428
|
return {
|
|
1129
1429
|
content: [{
|
|
1130
|
-
type:
|
|
1430
|
+
type: 'text',
|
|
1131
1431
|
text: `❌ Could not find activity or workflow for activity ID: ${args.activityId}`
|
|
1132
1432
|
}],
|
|
1133
1433
|
};
|
|
@@ -1143,7 +1443,7 @@ exports.testFunctionFieldTool = {
|
|
|
1143
1443
|
: `Field "${field.label || args.fieldId}" has no function dependencies configured.`;
|
|
1144
1444
|
return {
|
|
1145
1445
|
content: [{
|
|
1146
|
-
type:
|
|
1446
|
+
type: 'text',
|
|
1147
1447
|
text: `❌ No function dependencies available.
|
|
1148
1448
|
|
|
1149
1449
|
${reason}
|
|
@@ -1171,7 +1471,7 @@ functionVariables: {
|
|
|
1171
1471
|
const cleanMessage = errorMessage.replace(/^(SyntaxError|ReferenceError|TypeError):\s*/, '');
|
|
1172
1472
|
return {
|
|
1173
1473
|
content: [{
|
|
1174
|
-
type:
|
|
1474
|
+
type: 'text',
|
|
1175
1475
|
text: `❌ **Function Field Test Failed**
|
|
1176
1476
|
|
|
1177
1477
|
**Error Type:** ${errorType}
|
|
@@ -1216,10 +1516,12 @@ functionVariables: {
|
|
|
1216
1516
|
const iterations = stats['Iterations Used'];
|
|
1217
1517
|
if (executionTime !== undefined || iterations !== undefined) {
|
|
1218
1518
|
text += '\n**⏱️ Execution Statistics:**\n';
|
|
1219
|
-
if (executionTime !== undefined)
|
|
1519
|
+
if (executionTime !== undefined) {
|
|
1220
1520
|
text += `- Execution Time: ${executionTime}ms\n`;
|
|
1221
|
-
|
|
1521
|
+
}
|
|
1522
|
+
if (iterations !== undefined) {
|
|
1222
1523
|
text += `- Iterations: ${iterations}\n`;
|
|
1524
|
+
}
|
|
1223
1525
|
}
|
|
1224
1526
|
text += `
|
|
1225
1527
|
**✅ Next Steps:**
|
|
@@ -1228,18 +1530,19 @@ functionVariables: {
|
|
|
1228
1530
|
- If you need to modify the function, use \`update_workflow_field\` to save changes
|
|
1229
1531
|
- Function is working correctly and ready for production use!`;
|
|
1230
1532
|
return {
|
|
1231
|
-
content: [{ type:
|
|
1533
|
+
content: [{ type: 'text', text }],
|
|
1232
1534
|
};
|
|
1233
1535
|
}
|
|
1234
1536
|
catch (error) {
|
|
1235
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1236
|
-
logger.error(
|
|
1537
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1538
|
+
logger.error('Error testing function field', error);
|
|
1539
|
+
}
|
|
1237
1540
|
const errorMessage = error instanceof Error
|
|
1238
1541
|
? error.message
|
|
1239
1542
|
: JSON.stringify(error, null, 2);
|
|
1240
1543
|
return {
|
|
1241
1544
|
content: [{
|
|
1242
|
-
type:
|
|
1545
|
+
type: 'text',
|
|
1243
1546
|
text: `❌ **Error Testing Function Field**
|
|
1244
1547
|
|
|
1245
1548
|
${errorMessage}
|
|
@@ -1254,243 +1557,6 @@ ${errorMessage}
|
|
|
1254
1557
|
}
|
|
1255
1558
|
};
|
|
1256
1559
|
// ============================================================================
|
|
1257
|
-
// TOOL 5: LIST WORKFLOWS MINIMAL
|
|
1258
|
-
// ============================================================================
|
|
1259
|
-
const listWorkflowsMinimalDescription = `Quick list of all workflows - START HERE to find workflow IDs.
|
|
1260
|
-
|
|
1261
|
-
**Hailer Concept:** Returns all workflows (processes/boards) with their IDs and names. This is usually your FIRST CALL to discover what's available.
|
|
1262
|
-
|
|
1263
|
-
**When to use:** User asks "show my tasks", "what workflows do I have", "find customers" - use this to locate the right workflow ID.
|
|
1264
|
-
|
|
1265
|
-
**Returns:** Workflow name, ID, activity count. Use the ID in subsequent calls.
|
|
1266
|
-
|
|
1267
|
-
**Typical flow:** list_workflows_minimal → list_workflow_phases → get_workflow_schema → list_activities`;
|
|
1268
|
-
const listWorkflowsMinimalSchema = zod_1.z.object({
|
|
1269
|
-
workspace: zod_1.z.string().optional().describe("Optional workspace ID or name"),
|
|
1270
|
-
limit: zod_1.z.coerce.number().optional().describe("Maximum number of workflows to return"),
|
|
1271
|
-
offset: zod_1.z.coerce.number().optional().default(0).describe("Number of workflows to skip (for pagination)"),
|
|
1272
|
-
search: zod_1.z.string().optional().describe("Filter workflows by name (case-insensitive partial match)"),
|
|
1273
|
-
starredOnly: zod_1.z.coerce.boolean().optional().default(false).describe("Only return starred workflows"),
|
|
1274
|
-
});
|
|
1275
|
-
exports.listWorkflowsMinimalTool = {
|
|
1276
|
-
name: 'list_workflows_minimal',
|
|
1277
|
-
group: tool_registry_1.ToolGroup.READ,
|
|
1278
|
-
description: listWorkflowsMinimalDescription,
|
|
1279
|
-
schema: listWorkflowsMinimalSchema,
|
|
1280
|
-
async execute(args, context) {
|
|
1281
|
-
logger.debug('Listing workflows (minimal)', {
|
|
1282
|
-
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
1283
|
-
});
|
|
1284
|
-
try {
|
|
1285
|
-
// Use cached workflows from context.init (already fetched during initialization)
|
|
1286
|
-
let workflows = context.init.processes || [];
|
|
1287
|
-
// Filter by workspace if specified
|
|
1288
|
-
if (args.workspace) {
|
|
1289
|
-
workflows = workflows.filter(w => w.cid === args.workspace);
|
|
1290
|
-
}
|
|
1291
|
-
// Filter by starred if requested
|
|
1292
|
-
if (args.starredOnly) {
|
|
1293
|
-
workflows = workflows.filter(w => w.isStarred);
|
|
1294
|
-
}
|
|
1295
|
-
// Search by name if provided
|
|
1296
|
-
if (args.search) {
|
|
1297
|
-
const searchLower = args.search.toLowerCase();
|
|
1298
|
-
workflows = workflows.filter(w => w.name.toLowerCase().includes(searchLower));
|
|
1299
|
-
}
|
|
1300
|
-
// Apply pagination
|
|
1301
|
-
const offset = args.offset || 0;
|
|
1302
|
-
const limit = args.limit;
|
|
1303
|
-
const totalCount = workflows.length;
|
|
1304
|
-
if (limit) {
|
|
1305
|
-
workflows = workflows.slice(offset, offset + limit);
|
|
1306
|
-
}
|
|
1307
|
-
else if (offset > 0) {
|
|
1308
|
-
workflows = workflows.slice(offset);
|
|
1309
|
-
}
|
|
1310
|
-
// Build minimal response - only id and name
|
|
1311
|
-
const minimalWorkflows = workflows.map(w => ({
|
|
1312
|
-
id: w._id,
|
|
1313
|
-
name: w.name,
|
|
1314
|
-
workspaceId: w.cid,
|
|
1315
|
-
activityCount: w.createdActivities || 0,
|
|
1316
|
-
isStarred: w.isStarred || false
|
|
1317
|
-
}));
|
|
1318
|
-
let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📋 **Workflows Found**\n\n`;
|
|
1319
|
-
responseText += `Total: ${totalCount}\n`;
|
|
1320
|
-
responseText += `Showing: ${workflows.length}\n`;
|
|
1321
|
-
if (offset > 0)
|
|
1322
|
-
responseText += `Offset: ${offset}\n`;
|
|
1323
|
-
responseText += `\n`;
|
|
1324
|
-
minimalWorkflows.forEach(w => {
|
|
1325
|
-
const star = w.isStarred ? '⭐ ' : '';
|
|
1326
|
-
responseText += `${star}**${w.name}**\n`;
|
|
1327
|
-
responseText += ` ID: \`${w.id}\`\n`;
|
|
1328
|
-
responseText += ` Activities: ${w.activityCount}\n\n`;
|
|
1329
|
-
});
|
|
1330
|
-
responseText += `\n💡 **Next Steps:**\n`;
|
|
1331
|
-
responseText += `- Use \`get_workflow_schema\` with workflow ID to see fields\n`;
|
|
1332
|
-
responseText += `- Use \`list_workflow_phases\` to see available phases\n`;
|
|
1333
|
-
if (limit && (offset + limit) < totalCount) {
|
|
1334
|
-
responseText += `- Use \`offset: ${offset + limit}\` to see next page\n`;
|
|
1335
|
-
}
|
|
1336
|
-
return {
|
|
1337
|
-
content: [{
|
|
1338
|
-
type: "text",
|
|
1339
|
-
text: responseText,
|
|
1340
|
-
}],
|
|
1341
|
-
};
|
|
1342
|
-
}
|
|
1343
|
-
catch (error) {
|
|
1344
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1345
|
-
logger.error("Error listing workflows (minimal)", error);
|
|
1346
|
-
return {
|
|
1347
|
-
content: [{
|
|
1348
|
-
type: "text",
|
|
1349
|
-
text: `❌ Error listing workflows: ${error instanceof Error ? error.message : String(error)}`,
|
|
1350
|
-
}],
|
|
1351
|
-
};
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
};
|
|
1355
|
-
// ============================================================================
|
|
1356
|
-
// COUNT ACTIVITIES TOOL
|
|
1357
|
-
// ============================================================================
|
|
1358
|
-
const countActivitiesDescription = `🔢 Count Activities - Get total count of activities in a workflow
|
|
1359
|
-
|
|
1360
|
-
**Purpose**: Returns the total number of activities in a specific workflow. Useful for analytics, reporting, and understanding workflow size.
|
|
1361
|
-
|
|
1362
|
-
**⚠️ PERFORMANCE NOTICE:**
|
|
1363
|
-
- This makes a separate API call per workflow (v3.activity.count)
|
|
1364
|
-
- Use \`list_workflows_minimal\` instead for bulk workflow counts (uses cached data from init, zero extra API calls)
|
|
1365
|
-
- Only use \`count_activities\` when you need phase-level breakdown or real-time count
|
|
1366
|
-
|
|
1367
|
-
**Example**:
|
|
1368
|
-
\`\`\`javascript
|
|
1369
|
-
count_activities({
|
|
1370
|
-
workflowId: "691b136906e6923eac972902"
|
|
1371
|
-
})
|
|
1372
|
-
\`\`\`
|
|
1373
|
-
|
|
1374
|
-
**Response**: Returns count in details object
|
|
1375
|
-
|
|
1376
|
-
**Use Cases**:
|
|
1377
|
-
- Single workflow activity count
|
|
1378
|
-
- Phase-by-phase breakdown (returned data shows counts per phase)
|
|
1379
|
-
- Real-time activity count (bypasses cache)
|
|
1380
|
-
|
|
1381
|
-
**Tips**:
|
|
1382
|
-
- For bulk counts of ALL workflows, use \`list_workflows_minimal\` (free, no API calls)
|
|
1383
|
-
- This tool makes 1 API call per workflow
|
|
1384
|
-
- Use list_workflows to get workflow IDs`;
|
|
1385
|
-
const countActivitiesSchema = zod_1.z.object({
|
|
1386
|
-
workflowId: zod_1.z.string().describe("Workflow ID or key"),
|
|
1387
|
-
});
|
|
1388
|
-
exports.countActivitiesTool = {
|
|
1389
|
-
name: 'count_activities',
|
|
1390
|
-
group: tool_registry_1.ToolGroup.READ,
|
|
1391
|
-
description: countActivitiesDescription,
|
|
1392
|
-
schema: countActivitiesSchema,
|
|
1393
|
-
async execute(args, context) {
|
|
1394
|
-
logger.debug('Counting activities', {
|
|
1395
|
-
workflowId: args.workflowId,
|
|
1396
|
-
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
1397
|
-
});
|
|
1398
|
-
try {
|
|
1399
|
-
// Get workflow name from cached data
|
|
1400
|
-
const workflow = resolveWorkflow(context.init.processes || [], args.workflowId);
|
|
1401
|
-
if (!workflow) {
|
|
1402
|
-
return {
|
|
1403
|
-
content: [{
|
|
1404
|
-
type: "text",
|
|
1405
|
-
text: `❌ Workflow "${args.workflowId}" not found`,
|
|
1406
|
-
}],
|
|
1407
|
-
};
|
|
1408
|
-
}
|
|
1409
|
-
logger.debug('Calling v3.activity.count', {
|
|
1410
|
-
workflowId: args.workflowId,
|
|
1411
|
-
workflowName: workflow.name
|
|
1412
|
-
});
|
|
1413
|
-
// Call v3.activity.count endpoint
|
|
1414
|
-
// Returns object with phase IDs as keys and counts as values
|
|
1415
|
-
const result = await context.hailer.request('v3.activity.count', [args.workflowId]);
|
|
1416
|
-
logger.debug('Activity count retrieved', {
|
|
1417
|
-
result: JSON.stringify(result)
|
|
1418
|
-
});
|
|
1419
|
-
// Sum all counts across phases
|
|
1420
|
-
const count = Object.values(result).reduce((sum, phaseCount) => sum + phaseCount, 0);
|
|
1421
|
-
// Build success response
|
|
1422
|
-
let responseText = `🔢 **Activity Count for "${workflow.name}"**\n\n`;
|
|
1423
|
-
responseText += `**Workflow ID:** \`${args.workflowId}\`\n`;
|
|
1424
|
-
responseText += `**Total Activities:** ${count}\n\n`;
|
|
1425
|
-
if (count === 0) {
|
|
1426
|
-
responseText += `💡 This workflow has no activities yet. Use \`create_activity\` to add one.\n`;
|
|
1427
|
-
}
|
|
1428
|
-
else {
|
|
1429
|
-
responseText += `💡 **Next Steps:**\n`;
|
|
1430
|
-
responseText += `- Use \`list_activities\` to see the activities\n`;
|
|
1431
|
-
responseText += `- Use \`get_workflow_schema\` to see workflow structure\n`;
|
|
1432
|
-
}
|
|
1433
|
-
return {
|
|
1434
|
-
content: [{
|
|
1435
|
-
type: "text",
|
|
1436
|
-
text: responseText,
|
|
1437
|
-
}],
|
|
1438
|
-
};
|
|
1439
|
-
}
|
|
1440
|
-
catch (error) {
|
|
1441
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1442
|
-
logger.error("Error counting activities", error);
|
|
1443
|
-
return {
|
|
1444
|
-
content: [{
|
|
1445
|
-
type: "text",
|
|
1446
|
-
text: `❌ Error counting activities: ${error instanceof Error ? error.message : String(error)}\n\n**Tips:**\n- Check that workflow ID is valid (24 characters)\n- Use \`list_workflows\` to find workflow IDs`,
|
|
1447
|
-
}],
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
};
|
|
1452
|
-
// ============================================================================
|
|
1453
|
-
// UPDATE WORKFLOW PHASE
|
|
1454
|
-
// ============================================================================
|
|
1455
|
-
const updateWorkflowPhaseDescription = `🏷️ Update Workflow Phase - Modify phase name and properties
|
|
1456
|
-
|
|
1457
|
-
**What does this do?**
|
|
1458
|
-
Updates an existing workflow phase's properties like name, description, and settings.
|
|
1459
|
-
|
|
1460
|
-
**Required Parameters**:
|
|
1461
|
-
- workflowId: Workflow ID containing the phase
|
|
1462
|
-
- phaseId: Phase ID to update
|
|
1463
|
-
- phaseData: Properties to update (name, description, etc.)
|
|
1464
|
-
|
|
1465
|
-
**Example - Rename phase**:
|
|
1466
|
-
\`\`\`javascript
|
|
1467
|
-
update_workflow_phase({
|
|
1468
|
-
workflowId: "68446dc05b30685f67c6fcd4",
|
|
1469
|
-
phaseId: "181",
|
|
1470
|
-
phaseData: { name: "Injured" }
|
|
1471
|
-
})
|
|
1472
|
-
\`\`\`
|
|
1473
|
-
|
|
1474
|
-
**Updatable Properties**:
|
|
1475
|
-
- name - Phase display name
|
|
1476
|
-
- description - Phase description
|
|
1477
|
-
- color - Phase color code
|
|
1478
|
-
|
|
1479
|
-
**Requirements**:
|
|
1480
|
-
- User must be workspace administrator
|
|
1481
|
-
`;
|
|
1482
|
-
const updateWorkflowPhaseSchema = zod_1.z.object({
|
|
1483
|
-
workflowId: zod_1.z.string().describe("The workflow ID or key containing the phase"),
|
|
1484
|
-
phaseId: zod_1.z.string().describe("The phase ID or key to update"),
|
|
1485
|
-
phaseData: zod_1.z.object({
|
|
1486
|
-
name: zod_1.z.string().optional().describe("New phase name"),
|
|
1487
|
-
description: zod_1.z.string().optional().describe("New phase description"),
|
|
1488
|
-
color: zod_1.z.string().optional().describe("Phase color code"),
|
|
1489
|
-
}).passthrough().describe("Phase properties to update"),
|
|
1490
|
-
workspaceId: zod_1.z.string().optional().describe("Optional workspace ID - defaults to current workspace"),
|
|
1491
|
-
force: zod_1.z.boolean().optional().describe("Override SDK redirect — use API directly even when workspace/ exists"),
|
|
1492
|
-
});
|
|
1493
|
-
// ============================================================================
|
|
1494
1560
|
// CORE INIT TOOL - Workspace overview for terminal Claude Code sessions
|
|
1495
1561
|
// ============================================================================
|
|
1496
1562
|
const coreInitDescription = `🚀 START HERE - Load workspace context and learn how to use Hailer tools.
|
|
@@ -1542,118 +1608,24 @@ exports.coreInitTool = {
|
|
|
1542
1608
|
}
|
|
1543
1609
|
return {
|
|
1544
1610
|
content: [{
|
|
1545
|
-
type:
|
|
1611
|
+
type: 'text',
|
|
1546
1612
|
text: prefix + overview,
|
|
1547
1613
|
}],
|
|
1548
1614
|
};
|
|
1549
1615
|
}
|
|
1550
1616
|
catch (error) {
|
|
1551
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1552
|
-
logger.error(
|
|
1617
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1618
|
+
logger.error('Failed to generate workspace overview', error);
|
|
1619
|
+
}
|
|
1553
1620
|
return {
|
|
1554
1621
|
content: [{
|
|
1555
|
-
type:
|
|
1622
|
+
type: 'text',
|
|
1556
1623
|
text: `❌ Failed to load workspace context: ${error instanceof Error ? error.message : String(error)}`,
|
|
1557
1624
|
}],
|
|
1558
1625
|
};
|
|
1559
1626
|
}
|
|
1560
1627
|
},
|
|
1561
1628
|
};
|
|
1562
|
-
exports.updateWorkflowPhaseTool = {
|
|
1563
|
-
name: 'update_workflow_phase',
|
|
1564
|
-
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
1565
|
-
description: updateWorkflowPhaseDescription,
|
|
1566
|
-
schema: updateWorkflowPhaseSchema,
|
|
1567
|
-
async execute(args, context) {
|
|
1568
|
-
if (isSdkProject() && !args.force) {
|
|
1569
|
-
return sdkRedirect('update_workflow_phase', 'npm run phases-push:force', 'workspace/<WorkflowName>_<id>/phases.ts');
|
|
1570
|
-
}
|
|
1571
|
-
logger.debug('Updating workflow phase', {
|
|
1572
|
-
workflowId: args.workflowId,
|
|
1573
|
-
phaseId: args.phaseId,
|
|
1574
|
-
apiKey: context.apiKey.substring(0, 8) + '...'
|
|
1575
|
-
});
|
|
1576
|
-
try {
|
|
1577
|
-
// Get current workspace from cached init data
|
|
1578
|
-
let workspaceId = args.workspaceId;
|
|
1579
|
-
if (!workspaceId) {
|
|
1580
|
-
workspaceId = context.init.network?._id;
|
|
1581
|
-
}
|
|
1582
|
-
const phaseData = args.phaseData;
|
|
1583
|
-
const language = 'en'; // Default language
|
|
1584
|
-
logger.debug('Calling REST /phase/update', {
|
|
1585
|
-
workflowId: args.workflowId,
|
|
1586
|
-
phaseId: args.phaseId,
|
|
1587
|
-
phaseData
|
|
1588
|
-
});
|
|
1589
|
-
// Call REST endpoint /api/phase/update
|
|
1590
|
-
// API format: {"0": workflowId, "1": phaseId, "2": phaseSettings, "3": language}
|
|
1591
|
-
await context.hailer.callRest({
|
|
1592
|
-
operation: 'update_workflow_phase',
|
|
1593
|
-
endpoint: '/api/phase/update',
|
|
1594
|
-
method: 'POST',
|
|
1595
|
-
body: {
|
|
1596
|
-
"0": args.workflowId,
|
|
1597
|
-
"1": args.phaseId,
|
|
1598
|
-
"2": phaseData,
|
|
1599
|
-
"3": language
|
|
1600
|
-
}
|
|
1601
|
-
});
|
|
1602
|
-
logger.debug('Workflow phase update successful', {
|
|
1603
|
-
workflowId: args.workflowId,
|
|
1604
|
-
phaseId: args.phaseId
|
|
1605
|
-
});
|
|
1606
|
-
// Build success response
|
|
1607
|
-
let responseText = `✅ **Workflow Phase Updated Successfully**\n\n`;
|
|
1608
|
-
responseText += `**Workflow ID:** \`${args.workflowId}\`\n`;
|
|
1609
|
-
responseText += `**Phase ID:** \`${args.phaseId}\`\n`;
|
|
1610
|
-
responseText += `**Workspace:** ${workspaceId}\n\n`;
|
|
1611
|
-
responseText += `**Updated Properties:**\n`;
|
|
1612
|
-
Object.entries(phaseData).forEach(([key, value]) => {
|
|
1613
|
-
const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
1614
|
-
responseText += `- ${key}: \`${valueStr}\`\n`;
|
|
1615
|
-
});
|
|
1616
|
-
responseText += `\n💡 **Next Steps:**\n`;
|
|
1617
|
-
responseText += `- Use \`list_workflow_phases\` to verify the phase changes\n`;
|
|
1618
|
-
responseText += `- Phase changes will be immediately visible in the workflow\n`;
|
|
1619
|
-
return {
|
|
1620
|
-
content: [{
|
|
1621
|
-
type: "text",
|
|
1622
|
-
text: responseText,
|
|
1623
|
-
}],
|
|
1624
|
-
};
|
|
1625
|
-
}
|
|
1626
|
-
catch (error) {
|
|
1627
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1628
|
-
logger.error("Error updating workflow phase", error);
|
|
1629
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1630
|
-
// Handle permission errors
|
|
1631
|
-
if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
|
|
1632
|
-
return {
|
|
1633
|
-
content: [{
|
|
1634
|
-
type: "text",
|
|
1635
|
-
text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow phases.\n\n**Error:** ${errorMessage}`,
|
|
1636
|
-
}],
|
|
1637
|
-
};
|
|
1638
|
-
}
|
|
1639
|
-
// Handle method not found errors
|
|
1640
|
-
if (errorMessage.includes('Method not found')) {
|
|
1641
|
-
return {
|
|
1642
|
-
content: [{
|
|
1643
|
-
type: "text",
|
|
1644
|
-
text: `❌ **API Method Not Available**\n\nThe \`process.update_phase\` API method may not be available in this Hailer version.\n\n**Alternative:** Use the Hailer web interface to update phase names manually.\n\n**Error:** ${errorMessage}`,
|
|
1645
|
-
}],
|
|
1646
|
-
};
|
|
1647
|
-
}
|
|
1648
|
-
return {
|
|
1649
|
-
content: [{
|
|
1650
|
-
type: "text",
|
|
1651
|
-
text: `❌ **Error updating workflow phase**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID must be valid (24 characters)\n- Phase ID must exist in the workflow\n- Use \`list_workflow_phases\` to find phase IDs`,
|
|
1652
|
-
}],
|
|
1653
|
-
};
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
};
|
|
1657
1629
|
// ============================================================================
|
|
1658
1630
|
// AUTO SET KEYS TOOL
|
|
1659
1631
|
// ============================================================================
|
|
@@ -1663,7 +1635,7 @@ exports.autoSetKeysTool = {
|
|
|
1663
1635
|
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
1664
1636
|
description: autoSetKeysDescription,
|
|
1665
1637
|
schema: zod_1.z.object({
|
|
1666
|
-
workflowId: zod_1.z.string().describe(
|
|
1638
|
+
workflowId: zod_1.z.string().describe('Workflow ID or key to set keys on'),
|
|
1667
1639
|
}),
|
|
1668
1640
|
async execute(args, context) {
|
|
1669
1641
|
try {
|
|
@@ -1704,28 +1676,23 @@ exports.autoSetKeysTool = {
|
|
|
1704
1676
|
}
|
|
1705
1677
|
}
|
|
1706
1678
|
responseText += `\n💡 You can now use these keys instead of hex IDs in all tools.`;
|
|
1707
|
-
return { content: [{ type:
|
|
1679
|
+
return { content: [{ type: 'text', text: responseText }] };
|
|
1708
1680
|
}
|
|
1709
1681
|
catch (error) {
|
|
1710
1682
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1711
1683
|
return {
|
|
1712
|
-
content: [{ type:
|
|
1684
|
+
content: [{ type: 'text', text: `❌ **Error setting keys:** ${errorMessage}` }],
|
|
1713
1685
|
};
|
|
1714
1686
|
}
|
|
1715
1687
|
}
|
|
1716
1688
|
};
|
|
1717
1689
|
/** All workflow tools */
|
|
1718
1690
|
exports.workflowTools = [
|
|
1719
|
-
exports.
|
|
1720
|
-
exports.listWorkflowPhasesTool,
|
|
1721
|
-
exports.listWorkflowsTool,
|
|
1691
|
+
exports.describeWorkflowsTool,
|
|
1722
1692
|
exports.installWorkflowTool,
|
|
1723
1693
|
exports.removeWorkflowTool,
|
|
1724
|
-
exports.
|
|
1725
|
-
exports.updateWorkflowPhaseTool,
|
|
1694
|
+
exports.updateWorkflowStructureTool,
|
|
1726
1695
|
exports.testFunctionFieldTool,
|
|
1727
|
-
exports.listWorkflowsMinimalTool,
|
|
1728
|
-
exports.countActivitiesTool,
|
|
1729
1696
|
exports.coreInitTool,
|
|
1730
1697
|
exports.autoSetKeysTool,
|
|
1731
1698
|
];
|