@hailer/mcp 1.2.1 ā 1.3.10
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/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 +133 -143
- package/.claude/skills/hailer-app-builder/SKILL.md +29 -2
- package/.claude/skills/hailer-ui-guide/SKILL.md +265 -0
- package/.env.example +50 -1
- package/CLAUDE.md +141 -10
- package/dist/app-prep.d.ts +27 -0
- package/dist/app-prep.d.ts.map +1 -0
- package/dist/app-prep.js +94 -0
- package/dist/app-prep.js.map +1 -0
- 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 +61 -16
- package/dist/bot/bot.d.ts.map +1 -1
- package/dist/bot/bot.js +927 -151
- 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 +37 -5
- package/dist/bot/services/bot-permissions.d.ts.map +1 -1
- package/dist/bot/services/bot-permissions.js +159 -35
- 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 +47 -38
- package/dist/bot/services/message-formatter.d.ts.map +1 -1
- package/dist/bot/services/message-formatter.js +99 -80
- 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 +181 -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 +4 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +92 -11
- 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 +83 -34
- 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/publish-auth-injector.d.ts +22 -0
- package/dist/mcp/publish-auth-injector.d.ts.map +1 -0
- package/dist/mcp/publish-auth-injector.js +100 -0
- package/dist/mcp/publish-auth-injector.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 +184 -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 +2 -0
- package/dist/mcp/tools/activity.d.ts.map +1 -1
- package/dist/mcp/tools/activity.js +575 -218
- 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 +182 -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 +12 -16
- package/dist/mcp/tools/app-marketplace.d.ts.map +1 -1
- package/dist/mcp/tools/app-marketplace.js +748 -856
- 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 +29 -3
- package/dist/mcp/tools/discussion.d.ts.map +1 -1
- package/dist/mcp/tools/discussion.js +419 -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 +24 -5
- package/dist/mcp/tools/insight.d.ts.map +1 -1
- package/dist/mcp/tools/insight.js +513 -480
- 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 +9 -7
- package/dist/mcp/tools/workflow.d.ts.map +1 -1
- package/dist/mcp/tools/workflow.js +852 -860
- 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 +0 -3
- package/dist/mcp/utils/data-transformers.d.ts.map +1 -1
- package/dist/mcp/utils/data-transformers.js +32 -5
- 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 +113 -103
- 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 +2 -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 +367 -48
- 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 +183 -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 +1340 -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 +435 -0
- package/dist/public-chat/system-prompt.js.map +1 -0
- package/package.json +13 -7
- package/scripts/build-public-chat-knowledge.py +101 -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/app-squad.md +0 -131
- 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
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.activityTools = exports.updateActivityTool = exports.createActivityTool = exports.showActivityByIdTool = exports.listActivitiesTool = void 0;
|
|
13
|
+
exports.mergeBulkPage = mergeBulkPage;
|
|
13
14
|
const zod_1 = require("zod");
|
|
14
15
|
const tool_registry_1 = require("../tool-registry");
|
|
15
16
|
const index_1 = require("../utils/index");
|
|
@@ -32,7 +33,7 @@ function validateAndGetWorkflow(workflowId, init) {
|
|
|
32
33
|
*/
|
|
33
34
|
async function resolvePhaseForListing(workflow, args, _init) {
|
|
34
35
|
if (!args.phaseId) {
|
|
35
|
-
throw new Error(`Phase ID is required. Use
|
|
36
|
+
throw new Error(`Phase ID is required. Use describe_workflows with include: ['phases'] to get available phase IDs for workflow "${workflow.name}".`);
|
|
36
37
|
}
|
|
37
38
|
return args.phaseId;
|
|
38
39
|
}
|
|
@@ -98,7 +99,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
98
99
|
let malformatFilterErrorMessage = undefined;
|
|
99
100
|
for (const [fieldId, filterConfig] of Object.entries(mcpToolActivityListFilters)) {
|
|
100
101
|
switch (filterConfig.operator) {
|
|
101
|
-
case
|
|
102
|
+
case 'text_search':
|
|
102
103
|
if (filterConfig.value !== undefined) {
|
|
103
104
|
apiActivityFilters.and.push({ [fieldId]: { textSearch: filterConfig.value } });
|
|
104
105
|
}
|
|
@@ -106,7 +107,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
106
107
|
malformatFilterErrorMessage = 'text_search filter requires a value';
|
|
107
108
|
}
|
|
108
109
|
break;
|
|
109
|
-
case
|
|
110
|
+
case 'equals':
|
|
110
111
|
if (filterConfig.value !== undefined) {
|
|
111
112
|
apiActivityFilters.and.push({ [fieldId]: { equalTo: filterConfig.value } });
|
|
112
113
|
}
|
|
@@ -114,7 +115,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
114
115
|
malformatFilterErrorMessage = 'equals filter requires a value';
|
|
115
116
|
}
|
|
116
117
|
break;
|
|
117
|
-
case
|
|
118
|
+
case 'not_equals':
|
|
118
119
|
if (filterConfig.value !== undefined) {
|
|
119
120
|
apiActivityFilters.and.push({ [fieldId]: { notEqualTo: filterConfig.value } });
|
|
120
121
|
}
|
|
@@ -122,7 +123,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
122
123
|
malformatFilterErrorMessage = 'not_equals filter requires a value';
|
|
123
124
|
}
|
|
124
125
|
break;
|
|
125
|
-
case
|
|
126
|
+
case 'contains':
|
|
126
127
|
if (filterConfig.value !== undefined) {
|
|
127
128
|
apiActivityFilters.and.push({ [fieldId]: { contains: filterConfig.value } });
|
|
128
129
|
}
|
|
@@ -130,7 +131,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
130
131
|
malformatFilterErrorMessage = 'contains filter requires a value';
|
|
131
132
|
}
|
|
132
133
|
break;
|
|
133
|
-
case
|
|
134
|
+
case 'greater_than':
|
|
134
135
|
if (filterConfig.value !== undefined && typeof filterConfig.value === 'number') {
|
|
135
136
|
apiActivityFilters.and.push({ [fieldId]: { greaterThan: filterConfig.value } });
|
|
136
137
|
}
|
|
@@ -138,7 +139,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
138
139
|
malformatFilterErrorMessage = 'greater_than filter requires a numeric value';
|
|
139
140
|
}
|
|
140
141
|
break;
|
|
141
|
-
case
|
|
142
|
+
case 'greater_than_or_equal':
|
|
142
143
|
if (filterConfig.value !== undefined && typeof filterConfig.value === 'number') {
|
|
143
144
|
apiActivityFilters.and.push({ [fieldId]: { greaterThanOrEqual: filterConfig.value } });
|
|
144
145
|
}
|
|
@@ -146,7 +147,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
146
147
|
malformatFilterErrorMessage = 'greater_than_or_equal filter requires a numeric value';
|
|
147
148
|
}
|
|
148
149
|
break;
|
|
149
|
-
case
|
|
150
|
+
case 'less_than':
|
|
150
151
|
if (filterConfig.value !== undefined && typeof filterConfig.value === 'number') {
|
|
151
152
|
apiActivityFilters.and.push({ [fieldId]: { lessThan: filterConfig.value } });
|
|
152
153
|
}
|
|
@@ -154,7 +155,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
154
155
|
malformatFilterErrorMessage = 'less_than filter requires a numeric value';
|
|
155
156
|
}
|
|
156
157
|
break;
|
|
157
|
-
case
|
|
158
|
+
case 'less_than_or_equal':
|
|
158
159
|
if (filterConfig.value !== undefined && typeof filterConfig.value === 'number') {
|
|
159
160
|
apiActivityFilters.and.push({ [fieldId]: { lessThanOrEqual: filterConfig.value } });
|
|
160
161
|
}
|
|
@@ -162,7 +163,7 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
162
163
|
malformatFilterErrorMessage = 'less_than_or_equal filter requires a numeric value';
|
|
163
164
|
}
|
|
164
165
|
break;
|
|
165
|
-
case
|
|
166
|
+
case 'range':
|
|
166
167
|
if (!filterConfig.start || !filterConfig.end) {
|
|
167
168
|
malformatFilterErrorMessage = 'Incorrect filter format, either start or end not provided for range';
|
|
168
169
|
break;
|
|
@@ -181,19 +182,27 @@ function convertActivityFilters(mcpToolActivityListFilters) {
|
|
|
181
182
|
*/
|
|
182
183
|
function formatActivityListResponseWithPagination(activityData, workflow, init, phaseName, args) {
|
|
183
184
|
const activities = Array.isArray(activityData) ? activityData : (activityData.activities || activityData || []);
|
|
185
|
+
const metadata = (!Array.isArray(activityData) && activityData.metadata) || {};
|
|
184
186
|
const cleanedActivities = (0, index_1.transformActivities)(activities, workflow, init.users);
|
|
185
187
|
const filteredActivities = args?.fields
|
|
186
188
|
? filterFieldsAndValues(cleanedActivities, args.fields, workflow.fields)
|
|
187
189
|
: cleanedActivities;
|
|
188
190
|
const currentPage = args?.page || 0;
|
|
189
191
|
const limit = args?.limit || 50;
|
|
190
|
-
|
|
192
|
+
// The server always returns metadata.totalCount ā use it for exact page math
|
|
193
|
+
// instead of the old length === limit guess (0 means the count query failed).
|
|
194
|
+
const reportedTotal = typeof metadata.totalCount === 'number' && metadata.totalCount > 0 ? metadata.totalCount : 0;
|
|
195
|
+
const totalPages = reportedTotal > 0 ? Math.ceil(reportedTotal / limit) : undefined;
|
|
196
|
+
const hasMorePages = reportedTotal > 0 ? (currentPage + 1) * limit < reportedTotal : activities.length === limit;
|
|
191
197
|
let responseText = `š **PAGINATION INFO:**\n`;
|
|
192
|
-
responseText += `- Current page: ${currentPage + 1}\n`;
|
|
198
|
+
responseText += `- Current page: ${currentPage + 1}${totalPages ? ` of ${totalPages}` : ''}\n`;
|
|
199
|
+
if (reportedTotal > 0) {
|
|
200
|
+
responseText += `- Total matching activities: ${reportedTotal}\n`;
|
|
201
|
+
}
|
|
193
202
|
responseText += `- Activities on this page: ${activities.length}\n`;
|
|
194
203
|
responseText += `- Limit per page: ${limit}\n`;
|
|
195
204
|
if (hasMorePages) {
|
|
196
|
-
responseText += `- ā ļø **MORE DATA AVAILABLE**: Use page=${currentPage + 1} to get next ${limit} activities\n`;
|
|
205
|
+
responseText += `- ā ļø **MORE DATA AVAILABLE**: Use page=${currentPage + 1} to get the next ${limit} activities\n`;
|
|
197
206
|
}
|
|
198
207
|
if (activities.length === limit && currentPage === 0) {
|
|
199
208
|
responseText += `\nš” **TIP**: This shows the first ${limit} activities.\n`;
|
|
@@ -205,7 +214,7 @@ function formatActivityListResponseWithPagination(activityData, workflow, init,
|
|
|
205
214
|
return {
|
|
206
215
|
content: [
|
|
207
216
|
{
|
|
208
|
-
type:
|
|
217
|
+
type: 'text',
|
|
209
218
|
text: responseText,
|
|
210
219
|
},
|
|
211
220
|
],
|
|
@@ -221,22 +230,27 @@ function formatFilteredActivityListResponse(activityData, workflow, init, args)
|
|
|
221
230
|
const filteredActivities = args.fields
|
|
222
231
|
? filterFieldsAndValues(cleanedActivities, args.fields, workflow.fields)
|
|
223
232
|
: cleanedActivities;
|
|
224
|
-
const totalCount = metadata.totalCount || activities.length;
|
|
225
233
|
const currentPage = args?.page || 0;
|
|
226
234
|
const limit = args?.limit || 50;
|
|
227
|
-
|
|
228
|
-
|
|
235
|
+
// 0 means the count query failed ā fall back to the full-page heuristic
|
|
236
|
+
// instead of declaring a full page complete.
|
|
237
|
+
const reportedTotal = typeof metadata.totalCount === 'number' && metadata.totalCount > 0 ? metadata.totalCount : 0;
|
|
238
|
+
const totalCount = reportedTotal || activities.length;
|
|
239
|
+
const hasMorePages = reportedTotal > 0 ? (currentPage + 1) * limit < reportedTotal : activities.length === limit;
|
|
240
|
+
const totalPages = Math.max(1, Math.ceil(totalCount / limit));
|
|
229
241
|
let responseText = `šÆ **FILTERED ACTIVITIES** in "${workflow.name}":\n\n`;
|
|
230
242
|
const filterCount = Object.keys(args.filters || {}).length;
|
|
231
243
|
responseText += `**Applied Filters:** ${filterCount} field filter(s)\n`;
|
|
232
244
|
for (const [fieldId, filter] of Object.entries(args.filters || {})) {
|
|
233
245
|
const filterConfig = filter;
|
|
234
246
|
responseText += `- Field \`${fieldId}\`: ${filterConfig.operator}`;
|
|
235
|
-
if (filterConfig.value !== undefined)
|
|
247
|
+
if (filterConfig.value !== undefined) {
|
|
236
248
|
responseText += ` = "${filterConfig.value}"`;
|
|
237
|
-
|
|
249
|
+
}
|
|
250
|
+
if (filterConfig.start !== undefined) {
|
|
238
251
|
responseText += ` from ${filterConfig.start} to ${filterConfig.end}`;
|
|
239
|
-
|
|
252
|
+
}
|
|
253
|
+
responseText += '\n';
|
|
240
254
|
}
|
|
241
255
|
if (args.search) {
|
|
242
256
|
responseText += `- Text search: "${args.search}"\n`;
|
|
@@ -254,10 +268,10 @@ function formatFilteredActivityListResponse(activityData, workflow, init, args)
|
|
|
254
268
|
responseText += `š” **TROUBLESHOOTING:**\n`;
|
|
255
269
|
responseText += `- Try broader filter criteria\n`;
|
|
256
270
|
responseText += `- Remove some filters to see if data exists\n`;
|
|
257
|
-
responseText += `- Call
|
|
271
|
+
responseText += `- Call describe_workflows with include: ['schema'] to verify field IDs are correct\n`;
|
|
258
272
|
responseText += `- Use list_activities without filters to see all activities`;
|
|
259
273
|
return {
|
|
260
|
-
content: [{ type:
|
|
274
|
+
content: [{ type: 'text', text: responseText }],
|
|
261
275
|
};
|
|
262
276
|
}
|
|
263
277
|
responseText += `\n` + (0, index_1.formatActivityListResponse)(filteredActivities, workflow, undefined);
|
|
@@ -266,23 +280,273 @@ function formatFilteredActivityListResponse(activityData, workflow, init, args)
|
|
|
266
280
|
responseText += `- Use 'range' operator for date/number ranges (created/updated timestamps)\n`;
|
|
267
281
|
responseText += `- Use 'contains' or 'text_search' for partial text matching\n`;
|
|
268
282
|
responseText += `- Combine multiple filters for precise results\n`;
|
|
269
|
-
responseText += `- Call
|
|
283
|
+
responseText += `- Call describe_workflows with include: ['schema'] to discover available fields and their types`;
|
|
270
284
|
return {
|
|
271
285
|
content: [
|
|
272
286
|
{
|
|
273
|
-
type:
|
|
287
|
+
type: 'text',
|
|
274
288
|
text: responseText,
|
|
275
289
|
},
|
|
276
290
|
],
|
|
277
291
|
};
|
|
278
292
|
}
|
|
293
|
+
// Bulk reads: the backend reliably serves at most ~200 activities per call
|
|
294
|
+
// (larger limits fail silently as []), so "a lot of data at once" means many
|
|
295
|
+
// skip-pages ā fetched in parallel inside ONE tool call instead of one model
|
|
296
|
+
// turn per page.
|
|
297
|
+
const BULK_PAGE_SIZE = 200;
|
|
298
|
+
const BULK_CONCURRENCY = 5;
|
|
299
|
+
const BULK_MAX_RECORDS = 5000;
|
|
300
|
+
/** Merges one page response into the accumulator; returns the page's row count. */
|
|
301
|
+
function mergeBulkPage(pageResult, byId) {
|
|
302
|
+
const activities = Array.isArray(pageResult) ? pageResult : (pageResult?.activities || []);
|
|
303
|
+
for (const activity of activities) {
|
|
304
|
+
byId.set(activity._id, activity);
|
|
305
|
+
}
|
|
306
|
+
return activities.length;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Bulk-read body of list_activities (maxRecords). Pages are fetched sorted
|
|
310
|
+
* created asc: skip pagination over the default updated-desc ordering shifts
|
|
311
|
+
* rows across page boundaries mid-fetch (duplicates/gaps); created order is
|
|
312
|
+
* append-only. Page one runs alone to learn totalCount, the rest run in
|
|
313
|
+
* parallel batches. An empty non-final page means the backend query failed
|
|
314
|
+
* (it reports errors as empty results) ā surfaced loudly, never as "no data".
|
|
315
|
+
*/
|
|
316
|
+
async function executeBulkRead(args, workflow, phaseId, apiFilters, context) {
|
|
317
|
+
const fetchPage = (pageIndex) => context.hailer.fetchActivityList(args.workflowId, phaseId, BULK_PAGE_SIZE, {
|
|
318
|
+
page: pageIndex,
|
|
319
|
+
search: args.search,
|
|
320
|
+
sortBy: 'created',
|
|
321
|
+
sortOrder: 'asc',
|
|
322
|
+
filters: apiFilters,
|
|
323
|
+
returnFlat: true,
|
|
324
|
+
});
|
|
325
|
+
const firstPage = await fetchPage(0);
|
|
326
|
+
const byId = new Map();
|
|
327
|
+
const firstPageCount = mergeBulkPage(firstPage, byId);
|
|
328
|
+
const totalCount = typeof firstPage?.metadata?.totalCount === 'number' ? firstPage.metadata.totalCount : 0;
|
|
329
|
+
const requested = Math.min(args.maxRecords || BULK_PAGE_SIZE, BULK_MAX_RECORDS);
|
|
330
|
+
let failedPages = 0;
|
|
331
|
+
let maybeMore = false;
|
|
332
|
+
if (totalCount === 0 && firstPageCount === BULK_PAGE_SIZE) {
|
|
333
|
+
// Count query failed (0) but the first page is full ā the total is
|
|
334
|
+
// unknown. Walk pages sequentially until a short page so a 200-row cap
|
|
335
|
+
// is never silently presented as the complete dataset.
|
|
336
|
+
let pageIndex = 1;
|
|
337
|
+
let lastCount = firstPageCount;
|
|
338
|
+
while (lastCount === BULK_PAGE_SIZE && byId.size < requested) {
|
|
339
|
+
const result = await fetchPage(pageIndex).catch(() => null);
|
|
340
|
+
if (!result) {
|
|
341
|
+
failedPages += 1;
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
lastCount = mergeBulkPage(result, byId);
|
|
345
|
+
pageIndex += 1;
|
|
346
|
+
}
|
|
347
|
+
maybeMore = lastCount === BULK_PAGE_SIZE && byId.size >= requested;
|
|
348
|
+
}
|
|
349
|
+
const target = Math.min(requested, Math.max(totalCount, byId.size));
|
|
350
|
+
const pageCount = Math.max(1, Math.ceil(target / BULK_PAGE_SIZE));
|
|
351
|
+
for (let start = 1; start < pageCount && totalCount > 0; start += BULK_CONCURRENCY) {
|
|
352
|
+
const end = Math.min(start + BULK_CONCURRENCY, pageCount);
|
|
353
|
+
const batch = [];
|
|
354
|
+
for (let pageIndex = start; pageIndex < end; pageIndex += 1) {
|
|
355
|
+
batch.push(fetchPage(pageIndex).catch(() => null));
|
|
356
|
+
}
|
|
357
|
+
const results = await Promise.all(batch);
|
|
358
|
+
for (const result of results) {
|
|
359
|
+
const merged = result ? mergeBulkPage(result, byId) : 0;
|
|
360
|
+
if (merged === 0) {
|
|
361
|
+
failedPages += 1;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const allActivities = Array.from(byId.values()).slice(0, target);
|
|
366
|
+
const displayTotal = Math.max(totalCount, allActivities.length);
|
|
367
|
+
const cleanedActivities = (0, index_1.transformActivities)(allActivities, workflow, context.init.users);
|
|
368
|
+
const projectedActivities = args.fields
|
|
369
|
+
? filterFieldsAndValues(cleanedActivities, args.fields, workflow.fields)
|
|
370
|
+
: cleanedActivities;
|
|
371
|
+
let responseText = `š¦ **BULK FETCH:**\n`;
|
|
372
|
+
responseText += `- Retrieved: ${allActivities.length} of ${displayTotal} matching activities (${pageCount} page(s) in parallel)\n`;
|
|
373
|
+
if (displayTotal > requested) {
|
|
374
|
+
responseText += `- ā¹ļø Only the first ${requested} were fetched (maxRecords). ` +
|
|
375
|
+
`${displayTotal - requested} more match ā raise maxRecords (max ${BULK_MAX_RECORDS}) or narrow with filters\n`;
|
|
376
|
+
}
|
|
377
|
+
if (allActivities.length < target || failedPages > 0) {
|
|
378
|
+
responseText += `- ā ļø **INCOMPLETE**: expected ${target} but got ${allActivities.length}` +
|
|
379
|
+
`${failedPages ? ` (${failedPages} page(s) returned empty/failed)` : ''}. ` +
|
|
380
|
+
`Retry, or narrow with filters ā do NOT treat this as the full dataset\n`;
|
|
381
|
+
}
|
|
382
|
+
if (maybeMore) {
|
|
383
|
+
responseText += `- ā ļø The server's total count was unavailable and the last page was full ā ` +
|
|
384
|
+
`more activities likely exist beyond maxRecords. Raise maxRecords or narrow with filters\n`;
|
|
385
|
+
}
|
|
386
|
+
responseText += `\n` + (0, index_1.formatActivityListResponse)(projectedActivities, workflow);
|
|
387
|
+
return {
|
|
388
|
+
content: [{ type: 'text', text: responseText }],
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* countOnly fast path for list_activities ā preserved verbatim from the retired
|
|
393
|
+
* count_activities tool. O(1): calls v3.activity.count, never fetches activities.
|
|
394
|
+
*/
|
|
395
|
+
async function executeActivityCount(workflowId, context) {
|
|
396
|
+
logger.debug('Counting activities', {
|
|
397
|
+
workflowId,
|
|
398
|
+
apiKey: context.apiKey.substring(0, 8) + '...',
|
|
399
|
+
});
|
|
400
|
+
try {
|
|
401
|
+
// Get workflow name from cached data (matches by _id or key)
|
|
402
|
+
const workflow = (context.init.processes || []).find((proc) => proc._id === workflowId || proc.key === workflowId);
|
|
403
|
+
if (!workflow) {
|
|
404
|
+
return {
|
|
405
|
+
content: [{
|
|
406
|
+
type: 'text',
|
|
407
|
+
text: `ā Workflow "${workflowId}" not found`,
|
|
408
|
+
}],
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
logger.debug('Calling v3.activity.count', {
|
|
412
|
+
workflowId,
|
|
413
|
+
workflowName: workflow.name,
|
|
414
|
+
});
|
|
415
|
+
// Call v3.activity.count endpoint
|
|
416
|
+
// Returns object with phase IDs as keys and counts as values
|
|
417
|
+
const result = await context.hailer.request('v3.activity.count', [workflowId]);
|
|
418
|
+
logger.debug('Activity count retrieved', {
|
|
419
|
+
result: JSON.stringify(result),
|
|
420
|
+
});
|
|
421
|
+
// Sum all counts across phases
|
|
422
|
+
const count = Object.values(result).reduce((sum, phaseCount) => sum + phaseCount, 0);
|
|
423
|
+
let responseText = `š¢ **Activity Count for "${workflow.name}"**\n\n`;
|
|
424
|
+
responseText += `**Workflow ID:** \`${workflowId}\`\n`;
|
|
425
|
+
responseText += `**Total Activities:** ${count}\n\n`;
|
|
426
|
+
if (count === 0) {
|
|
427
|
+
responseText += `š” This workflow has no activities yet. Use \`create_activity\` to add one.\n`;
|
|
428
|
+
return {
|
|
429
|
+
content: [{ type: 'text', text: responseText }],
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
responseText += `š” **Next Steps:**\n`;
|
|
433
|
+
responseText += `- Use \`list_activities\` to see the activities\n`;
|
|
434
|
+
responseText += `- Use \`describe_workflows\` with include: ['schema'] to see workflow structure\n`;
|
|
435
|
+
return {
|
|
436
|
+
content: [{ type: 'text', text: responseText }],
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
441
|
+
logger.error('Error counting activities', error);
|
|
442
|
+
}
|
|
443
|
+
return {
|
|
444
|
+
content: [{
|
|
445
|
+
type: 'text',
|
|
446
|
+
text: `ā Error counting activities: ${error instanceof Error ? error.message : String(error)}\n\n**Tips:**\n` +
|
|
447
|
+
'- Check that workflow ID is valid (24 characters)\n- Use `describe_workflows` to find workflow IDs',
|
|
448
|
+
}],
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Validate the keys of a fields object against a workflow's field definitions.
|
|
454
|
+
* The server silently ignores unknown keys (e.g. field NAMES instead of IDs) and
|
|
455
|
+
* reports success ā the #1 documented footgun ā so we error out before the API call.
|
|
456
|
+
*
|
|
457
|
+
* ORDERING: in both create_activity and update_activity this runs AFTER the
|
|
458
|
+
* date/activitylink auto-fixups and immediately before the API call. The fixups
|
|
459
|
+
* rewrite values only, never keys, so the validated key set is identical either way.
|
|
460
|
+
*
|
|
461
|
+
* Accepts field IDs and field keys (the API resolves both).
|
|
462
|
+
* Returns error text for unknown keys, or undefined when all keys are known.
|
|
463
|
+
*/
|
|
464
|
+
function validateFieldKeys(fields, workflowFields) {
|
|
465
|
+
const knownKeys = new Set();
|
|
466
|
+
const labelToId = new Map();
|
|
467
|
+
for (const [fieldId, fieldDef] of Object.entries(workflowFields)) {
|
|
468
|
+
const def = fieldDef;
|
|
469
|
+
knownKeys.add(fieldId);
|
|
470
|
+
if (def.key) {
|
|
471
|
+
knownKeys.add(def.key);
|
|
472
|
+
}
|
|
473
|
+
if (def.label) {
|
|
474
|
+
labelToId.set(String(def.label).toLowerCase(), fieldId);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const unknownKeys = Object.keys(fields).filter((key) => !knownKeys.has(key));
|
|
478
|
+
if (unknownKeys.length === 0) {
|
|
479
|
+
return undefined;
|
|
480
|
+
}
|
|
481
|
+
const lines = [];
|
|
482
|
+
let needsFieldList = false;
|
|
483
|
+
for (const key of unknownKeys) {
|
|
484
|
+
const labelMatchId = labelToId.get(key.toLowerCase());
|
|
485
|
+
if (labelMatchId) {
|
|
486
|
+
const label = workflowFields[labelMatchId].label;
|
|
487
|
+
lines.push(`Field "${key}" must be referenced by ID: use "${labelMatchId}" (label: "${label}")`);
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
lines.push(`Unknown field key "${key}".`);
|
|
491
|
+
needsFieldList = true;
|
|
492
|
+
}
|
|
493
|
+
if (needsFieldList) {
|
|
494
|
+
const available = Object.entries(workflowFields)
|
|
495
|
+
.slice(0, 20)
|
|
496
|
+
.map(([fid, def]) => `- "${fid}" (label: "${def.label || def.key || fid}")`);
|
|
497
|
+
lines.push('', 'Available field IDs:', ...available);
|
|
498
|
+
}
|
|
499
|
+
return lines.join('\n');
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* update_activity field-key validation: resolves the activity's workflow (the
|
|
503
|
+
* workflowId is not a tool param) via fetchActivityById ā activity.process, then
|
|
504
|
+
* validates the fields object's keys. Fail-open on resolution problems (broken
|
|
505
|
+
* function fields, deleted activity, workflow missing from init) ā those must not
|
|
506
|
+
* block updates; unknown keys in a resolved workflow still hard-error.
|
|
507
|
+
* Returns formatted error text, or undefined when valid or unresolvable.
|
|
508
|
+
*/
|
|
509
|
+
async function validateUpdateFieldKeys(activityId, fields, context, knownWorkflowFields) {
|
|
510
|
+
if (Object.keys(fields).length === 0) {
|
|
511
|
+
return undefined;
|
|
512
|
+
}
|
|
513
|
+
let workflowFields = knownWorkflowFields;
|
|
514
|
+
if (!workflowFields) {
|
|
515
|
+
try {
|
|
516
|
+
const activity = await context.hailer.fetchActivityById(activityId);
|
|
517
|
+
const workflow = context.init.processes?.find((proc) => proc._id === activity?.process);
|
|
518
|
+
workflowFields = workflow?.fields;
|
|
519
|
+
}
|
|
520
|
+
catch (error) {
|
|
521
|
+
logger.warn('Skipping field-key validation - could not resolve workflow for activity', {
|
|
522
|
+
activityId,
|
|
523
|
+
error: (0, tool_helpers_1.extractErrorMessage)(error),
|
|
524
|
+
});
|
|
525
|
+
return undefined;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
if (!workflowFields) {
|
|
529
|
+
return undefined;
|
|
530
|
+
}
|
|
531
|
+
const keyError = validateFieldKeys(fields, workflowFields);
|
|
532
|
+
if (!keyError) {
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
if (knownWorkflowFields) {
|
|
536
|
+
// The caller-supplied workflowId may simply be wrong for this activity ā
|
|
537
|
+
// re-resolve the workflow from the activity itself before rejecting.
|
|
538
|
+
return validateUpdateFieldKeys(activityId, fields, context);
|
|
539
|
+
}
|
|
540
|
+
return `ā Invalid field keys for activity ${activityId} ā nothing was updated.\n\n${keyError}`;
|
|
541
|
+
}
|
|
279
542
|
/** Auto-fix date fields: convert ISO date strings to Unix timestamps (ms).
|
|
280
543
|
* If workspaceCache is available, only converts confirmed date/datetime/time fields.
|
|
281
544
|
* If not available, converts any value matching ISO date format (safe ā non-date fields won't have date strings). */
|
|
282
545
|
function autoFixDateFields(fields, context) {
|
|
283
546
|
for (const [fieldId, fieldValue] of Object.entries(fields)) {
|
|
284
|
-
if (typeof fieldValue !== 'string' || !/^\d{4}-\d{2}-\d{2}/.test(fieldValue))
|
|
547
|
+
if (typeof fieldValue !== 'string' || !/^\d{4}-\d{2}-\d{2}/.test(fieldValue)) {
|
|
285
548
|
continue;
|
|
549
|
+
}
|
|
286
550
|
// Try to confirm field type from cache
|
|
287
551
|
let fieldType;
|
|
288
552
|
if (context.workspaceCache) {
|
|
@@ -297,15 +561,16 @@ function autoFixDateFields(fields, context) {
|
|
|
297
561
|
// Convert if confirmed date type, OR if no cache (assume date ā non-date fields won't have ISO date strings)
|
|
298
562
|
if (!fieldType || fieldType === 'date' || fieldType === 'datetime' || fieldType === 'time') {
|
|
299
563
|
const parsed = new Date(fieldValue.length === 10 ? fieldValue + 'T12:00:00' : fieldValue).getTime();
|
|
300
|
-
if (!isNaN(parsed))
|
|
564
|
+
if (!isNaN(parsed)) {
|
|
301
565
|
fields[fieldId] = parsed;
|
|
566
|
+
}
|
|
302
567
|
}
|
|
303
568
|
}
|
|
304
569
|
}
|
|
305
570
|
/** Build activity update object */
|
|
306
571
|
function buildActivityUpdate(args, context) {
|
|
307
572
|
let parsedFields = args.fields;
|
|
308
|
-
if (typeof args.fields ===
|
|
573
|
+
if (typeof args.fields === 'string') {
|
|
309
574
|
try {
|
|
310
575
|
parsedFields = JSON.parse(args.fields);
|
|
311
576
|
}
|
|
@@ -314,25 +579,25 @@ function buildActivityUpdate(args, context) {
|
|
|
314
579
|
}
|
|
315
580
|
}
|
|
316
581
|
// Auto-fix activitylink fields: if LLM passes an object instead of just the ID string
|
|
317
|
-
if (parsedFields && typeof parsedFields ===
|
|
582
|
+
if (parsedFields && typeof parsedFields === 'object') {
|
|
318
583
|
for (const [fieldId, fieldValue] of Object.entries(parsedFields)) {
|
|
319
|
-
if (fieldValue && typeof fieldValue ===
|
|
584
|
+
if (fieldValue && typeof fieldValue === 'object' && !Array.isArray(fieldValue)) {
|
|
320
585
|
const obj = fieldValue;
|
|
321
586
|
let extractedId = null;
|
|
322
587
|
// Case 1: {type: "activitylink", value: {_id: "...", name: "..."}}
|
|
323
|
-
if (obj.type && obj.value && typeof obj.value ===
|
|
588
|
+
if (obj.type && obj.value && typeof obj.value === 'object' && obj.value._id) {
|
|
324
589
|
extractedId = obj.value._id;
|
|
325
590
|
}
|
|
326
591
|
// Case 2: {_id: "...", name: "..."}
|
|
327
|
-
|
|
592
|
+
if (!extractedId && obj._id && typeof obj._id === 'string') {
|
|
328
593
|
extractedId = obj._id;
|
|
329
594
|
}
|
|
330
595
|
// Case 3: {value: "..."} where value is the ID string
|
|
331
|
-
|
|
596
|
+
if (!extractedId && obj.value && typeof obj.value === 'string' && /^[a-f0-9]{24}$/i.test(obj.value)) {
|
|
332
597
|
extractedId = obj.value;
|
|
333
598
|
}
|
|
334
599
|
if (extractedId) {
|
|
335
|
-
logger.warn(
|
|
600
|
+
logger.warn('Auto-fixing activitylink field - extracting ID from object', {
|
|
336
601
|
fieldId,
|
|
337
602
|
original: JSON.stringify(fieldValue),
|
|
338
603
|
extracted: extractedId,
|
|
@@ -343,20 +608,21 @@ function buildActivityUpdate(args, context) {
|
|
|
343
608
|
}
|
|
344
609
|
}
|
|
345
610
|
// Field-type aware validation and auto-fix
|
|
346
|
-
if (parsedFields && typeof parsedFields ===
|
|
611
|
+
if (parsedFields && typeof parsedFields === 'object' && context.workspaceCache) {
|
|
347
612
|
autoFixDateFields(parsedFields, context);
|
|
348
613
|
const invalidUsers = [];
|
|
349
614
|
for (const [fieldId, fieldValue] of Object.entries(parsedFields)) {
|
|
350
615
|
// Only check string values that look like IDs
|
|
351
|
-
if (typeof fieldValue !==
|
|
616
|
+
if (typeof fieldValue !== 'string' || !/^[a-f0-9]{24}$/i.test(fieldValue)) {
|
|
352
617
|
continue;
|
|
353
618
|
}
|
|
354
619
|
// Find the field definition to check its type
|
|
355
620
|
let fieldType;
|
|
356
621
|
for (const workflow of context.workspaceCache.rawInit.processes) {
|
|
357
622
|
const workflowFields = workflow.fields;
|
|
358
|
-
if (!workflowFields)
|
|
623
|
+
if (!workflowFields) {
|
|
359
624
|
continue;
|
|
625
|
+
}
|
|
360
626
|
const field = workflowFields[fieldId];
|
|
361
627
|
if (field) {
|
|
362
628
|
fieldType = field.type;
|
|
@@ -373,14 +639,14 @@ function buildActivityUpdate(args, context) {
|
|
|
373
639
|
// Skip validation for 'activitylink' and other field types
|
|
374
640
|
}
|
|
375
641
|
if (invalidUsers.length > 0) {
|
|
376
|
-
throw new Error(`Invalid user IDs in user fields: ${invalidUsers.join(
|
|
642
|
+
throw new Error(`Invalid user IDs in user fields: ${invalidUsers.join(', ')}. Use search_workspace_users to find valid user IDs.`);
|
|
377
643
|
}
|
|
378
644
|
}
|
|
379
645
|
return {
|
|
380
646
|
_id: args.activityId,
|
|
381
647
|
...(args.name && { name: args.name }),
|
|
382
648
|
...(parsedFields &&
|
|
383
|
-
typeof parsedFields ===
|
|
649
|
+
typeof parsedFields === 'object' && {
|
|
384
650
|
fields: parsedFields,
|
|
385
651
|
}),
|
|
386
652
|
...(args.phaseId && { phaseId: args.phaseId }),
|
|
@@ -391,43 +657,165 @@ function buildActivityUpdate(args, context) {
|
|
|
391
657
|
*/
|
|
392
658
|
function formatUpdateActivityResponse(args, result) {
|
|
393
659
|
const changesText = [
|
|
394
|
-
args.name ? `- Name: "${args.name}"` :
|
|
395
|
-
args.fields ? `- Fields: ${JSON.stringify(args.fields, null, 2)}` :
|
|
396
|
-
args.phaseId ? `- Moved to phase: ${args.phaseId}` :
|
|
660
|
+
args.name ? `- Name: "${args.name}"` : '',
|
|
661
|
+
args.fields ? `- Fields: ${JSON.stringify(args.fields, null, 2)}` : '',
|
|
662
|
+
args.phaseId ? `- Moved to phase: ${args.phaseId}` : '',
|
|
397
663
|
]
|
|
398
664
|
.filter(Boolean)
|
|
399
|
-
.join(
|
|
665
|
+
.join('\n');
|
|
400
666
|
const responseText = `ā
Successfully updated activity ${args.activityId}!\n\nš Changes applied:\n${changesText}\n\nš” The activity has been updated in your Hailer workspace.\n\nAPI Response:\n${JSON.stringify(result, null, 2)}`;
|
|
401
667
|
return {
|
|
402
668
|
content: [
|
|
403
669
|
{
|
|
404
|
-
type:
|
|
670
|
+
type: 'text',
|
|
405
671
|
text: responseText,
|
|
406
672
|
},
|
|
407
673
|
],
|
|
408
674
|
};
|
|
409
675
|
}
|
|
676
|
+
/**
|
|
677
|
+
* Resolves a workflow's field definitions from the cached core.init. Lets
|
|
678
|
+
* update_activity validate field keys with zero per-activity server reads
|
|
679
|
+
* when the caller supplies workflowId.
|
|
680
|
+
*/
|
|
681
|
+
function resolveKnownWorkflowFields(workflowId, context) {
|
|
682
|
+
if (!workflowId) {
|
|
683
|
+
return undefined;
|
|
684
|
+
}
|
|
685
|
+
const workflow = context.init.processes?.find((proc) => proc._id === workflowId || proc.key === workflowId);
|
|
686
|
+
return workflow?.fields;
|
|
687
|
+
}
|
|
688
|
+
/** Bulk-mode body of update_activity ā extracted so the per-item field-key validation keeps flat control flow. */
|
|
689
|
+
async function executeBulkUpdate(activities, context, workflowId) {
|
|
690
|
+
logger.debug('Bulk update mode', {
|
|
691
|
+
activityCount: activities.length,
|
|
692
|
+
activities: JSON.stringify(activities, null, 2)
|
|
693
|
+
});
|
|
694
|
+
// Auto-fix common parameter name mistakes
|
|
695
|
+
for (const activity of activities) {
|
|
696
|
+
// Fix activityId -> _id
|
|
697
|
+
if (!activity._id && activity.activityId) {
|
|
698
|
+
logger.warn('Auto-fixing: activityId -> _id', { activityId: activity.activityId });
|
|
699
|
+
activity._id = activity.activityId;
|
|
700
|
+
delete activity.activityId;
|
|
701
|
+
}
|
|
702
|
+
// Fix fieldsAndValues -> fields
|
|
703
|
+
if (!activity.fields && activity.fieldsAndValues) {
|
|
704
|
+
logger.warn('Auto-fixing: fieldsAndValues -> fields', { activityId: activity._id });
|
|
705
|
+
activity.fields = activity.fieldsAndValues;
|
|
706
|
+
delete activity.fieldsAndValues;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
// Validate that all activities have _id
|
|
710
|
+
const invalidActivities = activities.filter((act) => !act._id || typeof act._id !== 'string' || act._id.length < 24);
|
|
711
|
+
if (invalidActivities.length > 0) {
|
|
712
|
+
return {
|
|
713
|
+
content: [{
|
|
714
|
+
type: 'text',
|
|
715
|
+
text: `ā **Error: Invalid bulk update request**\n\nEach activity in the "activities" array MUST have a valid "_id" field (24-character activity ID).\n\n**What you sent:** ${JSON.stringify(activities, null, 2)}\n\n**Correct format:**\n\`\`\`json\n{\n "activities": [\n { "_id": "691ffe654217e9e8434e577c", "fields": { "fieldId": "value" } },\n { "_id": "691ffe654217e9e8434e5774", "name": "New Name" }\n ]\n}\n\`\`\`\n\n**Tip:** First use list_activities to get the activity IDs, then pass them in the _id field.`,
|
|
716
|
+
}],
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
// Build updates for each activity
|
|
720
|
+
const updates = activities.map((activity) => {
|
|
721
|
+
const activityUpdate = { _id: activity._id };
|
|
722
|
+
if (activity.name) {
|
|
723
|
+
activityUpdate.name = activity.name;
|
|
724
|
+
}
|
|
725
|
+
if (activity.fields) {
|
|
726
|
+
// Parse fields if string
|
|
727
|
+
const parsedFields = typeof activity.fields === 'string'
|
|
728
|
+
? JSON.parse(activity.fields)
|
|
729
|
+
: activity.fields;
|
|
730
|
+
// Auto-fix activitylink fields: if LLM passes object with _id, extract just the ID
|
|
731
|
+
const linkFixEntries = parsedFields && typeof parsedFields === 'object'
|
|
732
|
+
? Object.entries(parsedFields)
|
|
733
|
+
: [];
|
|
734
|
+
for (const [fieldId, fieldValue] of linkFixEntries) {
|
|
735
|
+
const isLinkObject = Boolean(fieldValue) &&
|
|
736
|
+
typeof fieldValue === 'object' &&
|
|
737
|
+
!Array.isArray(fieldValue) &&
|
|
738
|
+
'_id' in fieldValue &&
|
|
739
|
+
typeof fieldValue._id === 'string';
|
|
740
|
+
if (!isLinkObject) {
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
logger.warn('Auto-fixing activitylink field in bulk mode', {
|
|
744
|
+
activityId: activity._id,
|
|
745
|
+
fieldId,
|
|
746
|
+
extracted: fieldValue._id,
|
|
747
|
+
});
|
|
748
|
+
parsedFields[fieldId] = fieldValue._id;
|
|
749
|
+
}
|
|
750
|
+
autoFixDateFields(parsedFields, context);
|
|
751
|
+
activityUpdate.fields = parsedFields;
|
|
752
|
+
}
|
|
753
|
+
return activityUpdate;
|
|
754
|
+
});
|
|
755
|
+
// Per-item field-key validation ā runs AFTER the auto-fixups above
|
|
756
|
+
// (values only, keys unchanged; see validateFieldKeys). Unknown keys silently
|
|
757
|
+
// no-op server-side, so this is the only guard against lost updates. With
|
|
758
|
+
// workflowId the field defs come from the cached init (zero server reads);
|
|
759
|
+
// without it the per-activity workflow lookups run in parallel ā the old
|
|
760
|
+
// sequential awaits made bulk updates cost one round trip per activity.
|
|
761
|
+
const knownWorkflowFields = resolveKnownWorkflowFields(workflowId, context);
|
|
762
|
+
// Without workflowId each validation fetches its activity ā bound the fan-out
|
|
763
|
+
// so a 2000-item bulk update can't fire 2000 concurrent backend reads. With
|
|
764
|
+
// workflowId the validation is pure CPU and runs in one batch.
|
|
765
|
+
const validationConcurrency = knownWorkflowFields ? updates.length : BULK_CONCURRENCY;
|
|
766
|
+
let keyError;
|
|
767
|
+
for (let start = 0; start < updates.length && !keyError; start += validationConcurrency) {
|
|
768
|
+
const chunk = updates.slice(start, start + validationConcurrency);
|
|
769
|
+
const chunkErrors = await Promise.all(chunk.map((update) => update.fields
|
|
770
|
+
? validateUpdateFieldKeys(update._id, update.fields, context, knownWorkflowFields)
|
|
771
|
+
: undefined));
|
|
772
|
+
keyError = chunkErrors.find(Boolean);
|
|
773
|
+
}
|
|
774
|
+
if (keyError) {
|
|
775
|
+
return {
|
|
776
|
+
content: [{ type: 'text', text: keyError }],
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
// Collect unique phase IDs (most activities will have the same phase)
|
|
780
|
+
const phaseIds = activities
|
|
781
|
+
.map((act) => act.phaseId)
|
|
782
|
+
.filter((pid) => pid);
|
|
783
|
+
const commonPhaseId = phaseIds.length > 0 ? phaseIds[0] : undefined;
|
|
784
|
+
// Call API with all updates
|
|
785
|
+
const options = commonPhaseId ? { phaseId: commonPhaseId } : undefined;
|
|
786
|
+
await context.hailer.updateActivities(updates, options);
|
|
787
|
+
// Format bulk response
|
|
788
|
+
return {
|
|
789
|
+
content: [
|
|
790
|
+
{
|
|
791
|
+
type: 'text',
|
|
792
|
+
text: `š Successfully updated ${activities.length} activities!\n\nš **Bulk Update Summary:**\n- **Total Updated**: ${activities.length} activities\n- **Status**: All activities updated successfully\n\nā
All activities have been updated in your Hailer workspace!`,
|
|
793
|
+
},
|
|
794
|
+
],
|
|
795
|
+
};
|
|
796
|
+
}
|
|
410
797
|
const listActivitiesDescription = `List activities (items/records/tasks) from a workflow phase.
|
|
411
798
|
|
|
412
799
|
**Prerequisites:** You need workflowId, phaseId, and field IDs. Get them via:
|
|
413
|
-
1. \`
|
|
414
|
-
2. \`
|
|
415
|
-
3. \`
|
|
800
|
+
1. \`describe_workflows\` ā workflowId
|
|
801
|
+
2. \`describe_workflows\` with include: ['phases'] ā phaseId
|
|
802
|
+
3. \`describe_workflows\` with include: ['schema'] ā field IDs for the \`fields\` parameter
|
|
416
803
|
|
|
417
804
|
**Required params:** workflowId, phaseId, fields[] (array of field IDs to return)
|
|
418
805
|
|
|
419
|
-
**
|
|
420
|
-
|
|
421
|
-
2.
|
|
422
|
-
3. get_workflow_schema ā get field IDs
|
|
423
|
-
4. list_activities with those IDs`;
|
|
806
|
+
**Fast path:** \`countOnly: true\` returns only the workflow's total activity count (O(1), needs just workflowId ā no phaseId/fields).
|
|
807
|
+
|
|
808
|
+
**Large reads:** \`maxRecords\` (ā¤5000) fetches the whole result set in ONE call ā pages are pulled in parallel server-side. Use 2-3 \`fields\` to stay under the response size cap. For counts, sums, group-bys, or cross-workflow joins prefer \`run_insight\` (SQL) where available ā aggregates beat raw rows.`;
|
|
424
809
|
exports.listActivitiesTool = {
|
|
425
810
|
name: 'list_activities',
|
|
426
811
|
group: tool_registry_1.ToolGroup.READ,
|
|
427
812
|
description: listActivitiesDescription,
|
|
428
813
|
schema: zod_1.z.object({
|
|
429
|
-
workflowId: zod_1.z.string().describe(
|
|
430
|
-
phaseId: zod_1.z.string().
|
|
814
|
+
workflowId: zod_1.z.string().describe('Workflow ID or key to list activities from'),
|
|
815
|
+
phaseId: zod_1.z.string().optional()
|
|
816
|
+
.describe("Phase ID or key to filter activities. Required unless countOnly=true. Use describe_workflows with include: ['phases'] for phases"),
|
|
817
|
+
countOnly: zod_1.z.coerce.boolean().optional().default(false).describe('Fast path: return only the total activity count for the workflow (O(1) v3.activity.count). ' +
|
|
818
|
+
'Needs just workflowId; phaseId/fields/filters are ignored.'),
|
|
431
819
|
fields: zod_1.z.preprocess((val) => {
|
|
432
820
|
if (typeof val === 'string') {
|
|
433
821
|
try {
|
|
@@ -440,31 +828,37 @@ exports.listActivitiesTool = {
|
|
|
440
828
|
}
|
|
441
829
|
}
|
|
442
830
|
return val;
|
|
443
|
-
}, zod_1.z.array(zod_1.z.string()).optional()).describe("Array of field IDs or keys to return (use
|
|
831
|
+
}, zod_1.z.array(zod_1.z.string()).optional()).describe("Array of field IDs or keys to return (use describe_workflows with include: ['schema'] to see available fields). Select the fields needed for the task - use fewer fields for listings (name, status, etc.) and more fields when detailed information is required."),
|
|
444
832
|
filters: zod_1.z.record(zod_1.z.object({
|
|
445
833
|
operator: zod_1.z.enum([
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
]).describe(
|
|
456
|
-
value: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional().describe(
|
|
834
|
+
'text_search',
|
|
835
|
+
'equals',
|
|
836
|
+
'not_equals',
|
|
837
|
+
'contains',
|
|
838
|
+
'greater_than',
|
|
839
|
+
'greater_than_or_equal',
|
|
840
|
+
'less_than',
|
|
841
|
+
'less_than_or_equal',
|
|
842
|
+
'range',
|
|
843
|
+
]).describe('Filter operator: text_search for partial text match in field (BEST for filtering by text in relationship fields when you only have a name), equals for exact match (requires activity ID), range for date/number ranges, contains for partial text, comparison operators for numbers/dates'),
|
|
844
|
+
value: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional().describe('Value to filter by - REQUIRED for text_search, equals, not_equals, contains, greater_than, less_than operators. NOT USED for range operator (use start/end instead). For text_search: use the text/name to search for. For equals: use the entity ID.'),
|
|
457
845
|
start: zod_1.z.coerce.number().optional().describe("Start value - ONLY for range operator (NOT in 'value' field). Unix timestamp in milliseconds for date ranges. NOT nested in 'value'."),
|
|
458
846
|
end: zod_1.z.coerce.number().optional().describe("End value - ONLY for range operator (NOT in 'value' field). Unix timestamp in milliseconds for date ranges. Example: for June 2025 date range, use end=1719791999000 directly here, NOT nested in 'value'."),
|
|
459
847
|
})).optional().describe("Filter by field values. STRUCTURE: {\"fieldId\": {\"operator\": \"...\", \"value\": \"...\"}}. EXAMPLE: To find player named 'Harry Kane', use: {\"691ffdf84217e9e8434e5694\": {\"operator\": \"text_search\", \"value\": \"Harry Kane\"}}. WRONG: {\"playerName\": \"Harry Kane\"} or {\"fieldId\": \"Harry Kane\"}. Operators: text_search (partial text match), equals (exact ID match), range (use start/end instead of value)."),
|
|
460
|
-
search: zod_1.z.string().optional().describe(
|
|
461
|
-
limit: zod_1.z.coerce.number().optional().default(50).describe(
|
|
462
|
-
page: zod_1.z.coerce.number().optional().default(0).describe(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
848
|
+
search: zod_1.z.string().optional().describe('Text search across activity content - USE FILTERS INSTEAD when possible for reliable results. Only use search for truly exploratory queries.'),
|
|
849
|
+
limit: zod_1.z.coerce.number().int().min(1).max(200).optional().default(50).describe('Activities per page (default: 50, max: 200 ā the server silently returns empty results for larger values; paginate with `page` instead)'),
|
|
850
|
+
page: zod_1.z.coerce.number().int().min(0).optional().default(0).describe('Page number for pagination (0-based). The response reports the total page count'),
|
|
851
|
+
maxRecords: zod_1.z.coerce.number().int().min(1).max(5000).optional().describe('BULK READ: fetch up to this many matching activities in ONE call ā pages are pulled in parallel server-side ' +
|
|
852
|
+
'(sorted created asc). Overrides limit/page. Keep fields minimal (2-3): the response size cap still applies'),
|
|
853
|
+
sortBy: zod_1.z.enum(['name', 'created', 'updated', 'priority']).optional().default('updated').describe('Field to sort by'),
|
|
854
|
+
sortOrder: zod_1.z.enum(['asc', 'desc']).optional().default('desc').describe('Sort direction'),
|
|
855
|
+
includeStats: zod_1.z.coerce.boolean().optional().default(false).describe('Include schedule/value stats metadata (the total count is always returned regardless)'),
|
|
466
856
|
}),
|
|
467
857
|
async execute(args, context) {
|
|
858
|
+
// countOnly fast path ā dispatches to the retired count_activities body (own error handling)
|
|
859
|
+
if (args.countOnly) {
|
|
860
|
+
return executeActivityCount(args.workflowId, context);
|
|
861
|
+
}
|
|
468
862
|
try {
|
|
469
863
|
const workflow = validateAndGetWorkflow(args.workflowId, context.init);
|
|
470
864
|
const phaseId = await resolvePhaseForListing(workflow, args, context.init);
|
|
@@ -472,10 +866,10 @@ exports.listActivitiesTool = {
|
|
|
472
866
|
return {
|
|
473
867
|
content: [
|
|
474
868
|
{
|
|
475
|
-
type:
|
|
869
|
+
type: 'text',
|
|
476
870
|
text: `ā **Fields parameter required**: You must specify which fields to return to avoid huge responses.\n\n` +
|
|
477
871
|
`š **Next steps:**\n` +
|
|
478
|
-
`1. Call \`
|
|
872
|
+
`1. Call \`describe_workflows\` with workflowId: "${args.workflowId}" and include: ['schema'] to see available fields\n` +
|
|
479
873
|
`2. Then call \`list_activities\` again with 2-3 essential field IDs\n\n` +
|
|
480
874
|
`š” **Best practices:**\n` +
|
|
481
875
|
`- For product listings: ["name", "price", "stock"] (3 fields)\n` +
|
|
@@ -502,10 +896,10 @@ exports.listActivitiesTool = {
|
|
|
502
896
|
return {
|
|
503
897
|
content: [
|
|
504
898
|
{
|
|
505
|
-
type:
|
|
899
|
+
type: 'text',
|
|
506
900
|
text: `ā **Filter Error:** ${filterErrorMessage}\n\n` +
|
|
507
901
|
`š” **Valid operators:** equals, not_equals, contains, text_search, greater_than, less_than, range\n` +
|
|
508
|
-
`š Call \`
|
|
902
|
+
`š Call \`describe_workflows\` with include: ['schema'] to see available field IDs and types`,
|
|
509
903
|
}
|
|
510
904
|
],
|
|
511
905
|
};
|
|
@@ -515,6 +909,9 @@ exports.listActivitiesTool = {
|
|
|
515
909
|
apiFilters: JSON.stringify(apiFilters)
|
|
516
910
|
});
|
|
517
911
|
}
|
|
912
|
+
if (args.maxRecords) {
|
|
913
|
+
return await executeBulkRead(args, workflow, phaseId, apiFilters, context);
|
|
914
|
+
}
|
|
518
915
|
const options = {
|
|
519
916
|
page: args.page,
|
|
520
917
|
search: args.search,
|
|
@@ -542,12 +939,13 @@ exports.listActivitiesTool = {
|
|
|
542
939
|
return response;
|
|
543
940
|
}
|
|
544
941
|
catch (error) {
|
|
545
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
546
|
-
logger.error(
|
|
942
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
943
|
+
logger.error('Failed to list activities', error);
|
|
944
|
+
}
|
|
547
945
|
return {
|
|
548
946
|
content: [
|
|
549
947
|
{
|
|
550
|
-
type:
|
|
948
|
+
type: 'text',
|
|
551
949
|
text: `ā Failed to list activities: ${(0, tool_helpers_1.extractErrorMessage)(error)}`,
|
|
552
950
|
},
|
|
553
951
|
],
|
|
@@ -567,37 +965,38 @@ exports.showActivityByIdTool = {
|
|
|
567
965
|
group: tool_registry_1.ToolGroup.READ,
|
|
568
966
|
description: showActivityByIdDescription,
|
|
569
967
|
schema: zod_1.z.object({
|
|
570
|
-
activityId: zod_1.z.string().describe(
|
|
968
|
+
activityId: zod_1.z.string().describe('Activity ID to load'),
|
|
571
969
|
}),
|
|
572
970
|
async execute(args, context) {
|
|
573
971
|
// Validate: reject known non-activity ID patterns
|
|
574
972
|
const id = args.activityId;
|
|
575
973
|
if (!id || typeof id !== 'string' || id.length < 24) {
|
|
576
974
|
return {
|
|
577
|
-
content: [{ type:
|
|
975
|
+
content: [{ type: 'text', text: `ā Invalid activity ID: "${id}". Activity IDs are 24-character hex strings from list_activities results. Do NOT use workflow IDs, field IDs, phase IDs, or discussion IDs.` }],
|
|
578
976
|
};
|
|
579
977
|
}
|
|
580
978
|
try {
|
|
581
979
|
const activity = await context.hailer.fetchActivityById(args.activityId);
|
|
582
|
-
|
|
980
|
+
const responseText = `ā
Loaded activity with ID "${activity._id}":\n\n${JSON.stringify(activity, null, 2)}`;
|
|
583
981
|
return {
|
|
584
982
|
content: [
|
|
585
983
|
{
|
|
586
|
-
type:
|
|
984
|
+
type: 'text',
|
|
587
985
|
text: responseText,
|
|
588
986
|
},
|
|
589
987
|
],
|
|
590
988
|
};
|
|
591
989
|
}
|
|
592
990
|
catch (error) {
|
|
593
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
594
|
-
logger.error(
|
|
991
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
992
|
+
logger.error('Failed to load activity', error, {
|
|
595
993
|
activityId: args.activityId,
|
|
596
994
|
});
|
|
995
|
+
}
|
|
597
996
|
return {
|
|
598
997
|
content: [
|
|
599
998
|
{
|
|
600
|
-
type:
|
|
999
|
+
type: 'text',
|
|
601
1000
|
text: `ā Failed to load activity "${args.activityId}": ${(0, tool_helpers_1.extractErrorMessage)(error)}\n\nā ļø Make sure this is an ACTIVITY ID (from list_activities or activity._id), NOT a workflow ID, field ID, phase ID, or discussion ID.`,
|
|
602
1001
|
},
|
|
603
1002
|
],
|
|
@@ -610,10 +1009,10 @@ exports.showActivityByIdTool = {
|
|
|
610
1009
|
// ============================================================================
|
|
611
1010
|
const createActivityDescription = `Create a new activity (item/record/task) in a workflow.
|
|
612
1011
|
|
|
613
|
-
**Prerequisites:** Get IDs first via
|
|
614
|
-
1.
|
|
615
|
-
2.
|
|
616
|
-
3.
|
|
1012
|
+
**Prerequisites:** Get IDs first via \`describe_workflows\`:
|
|
1013
|
+
1. No args ā workflowId
|
|
1014
|
+
2. include: ['phases'] ā phaseId (use isInitial=true phase)
|
|
1015
|
+
3. include: ['schema'] ā field IDs for the fields parameter
|
|
617
1016
|
|
|
618
1017
|
**Required:** workflowId + (name OR activities[])
|
|
619
1018
|
**Recommended:** phaseId (defaults to initial phase if omitted)
|
|
@@ -633,38 +1032,38 @@ exports.createActivityTool = {
|
|
|
633
1032
|
schema: zod_1.z.object({
|
|
634
1033
|
workflowId: zod_1.z
|
|
635
1034
|
.string()
|
|
636
|
-
.describe(
|
|
1035
|
+
.describe('The workflow ID or key where to create the activity/activities. Find this in any list_* tool results'),
|
|
637
1036
|
// BULK CREATION (optional - takes precedence over single parameters)
|
|
638
1037
|
activities: zod_1.z
|
|
639
1038
|
.array(zod_1.z.object({
|
|
640
|
-
name: zod_1.z.string().min(1,
|
|
641
|
-
fields: zod_1.z.union([zod_1.z.record(zod_1.z.any()), zod_1.z.string()]).optional().describe(
|
|
642
|
-
phaseId: zod_1.z.string().optional().describe(
|
|
643
|
-
teamId: zod_1.z.string().optional().describe(
|
|
644
|
-
discussionId: zod_1.z.string().optional().describe(
|
|
645
|
-
followerIds: zod_1.z.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()]).optional().describe(
|
|
646
|
-
fileIds: zod_1.z.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()]).optional().describe(
|
|
1039
|
+
name: zod_1.z.string().min(1, 'Activity name cannot be empty').describe('Activity name/title'),
|
|
1040
|
+
fields: zod_1.z.union([zod_1.z.record(zod_1.z.any()), zod_1.z.string()]).optional().describe('Custom field values (field keys or IDs)'),
|
|
1041
|
+
phaseId: zod_1.z.string().optional().describe('Phase ID or key for this activity'),
|
|
1042
|
+
teamId: zod_1.z.string().optional().describe('Team ID for this activity'),
|
|
1043
|
+
discussionId: zod_1.z.string().optional().describe('Link to existing discussion'),
|
|
1044
|
+
followerIds: zod_1.z.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()]).optional().describe('User IDs to invite'),
|
|
1045
|
+
fileIds: zod_1.z.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()]).optional().describe('File IDs to attach'),
|
|
647
1046
|
}))
|
|
648
1047
|
.optional()
|
|
649
|
-
.describe(
|
|
1048
|
+
.describe('BULK: Array of activities. Example: [{"name": "Task 1", "fields": {...}}, {"name": "Task 2"}]. If provided, single parameters are ignored.'),
|
|
650
1049
|
// SINGLE CREATION (used when 'activities' is not provided)
|
|
651
1050
|
name: zod_1.z
|
|
652
1051
|
.string()
|
|
653
|
-
.min(1,
|
|
1052
|
+
.min(1, 'Activity name cannot be empty')
|
|
654
1053
|
.optional()
|
|
655
1054
|
.describe("SINGLE: The activity name/title (e.g. 'š¤ AI Analysis Bot', 'Customer Research Task')"),
|
|
656
1055
|
description: zod_1.z
|
|
657
1056
|
.string()
|
|
658
1057
|
.optional()
|
|
659
|
-
.describe(
|
|
1058
|
+
.describe('SINGLE: Optional detailed description'),
|
|
660
1059
|
phaseId: zod_1.z
|
|
661
1060
|
.string()
|
|
662
1061
|
.optional()
|
|
663
|
-
.describe(
|
|
1062
|
+
.describe('SINGLE: Optional phase/category ID or key. If not specified, uses the default phase'),
|
|
664
1063
|
teamId: zod_1.z
|
|
665
1064
|
.string()
|
|
666
1065
|
.optional()
|
|
667
|
-
.describe(
|
|
1066
|
+
.describe('SINGLE: Optional team ID for team-specific activities'),
|
|
668
1067
|
fields: zod_1.z
|
|
669
1068
|
.union([zod_1.z.record(zod_1.z.any()), zod_1.z.string()])
|
|
670
1069
|
.optional()
|
|
@@ -672,20 +1071,20 @@ exports.createActivityTool = {
|
|
|
672
1071
|
discussionId: zod_1.z
|
|
673
1072
|
.string()
|
|
674
1073
|
.optional()
|
|
675
|
-
.describe(
|
|
1074
|
+
.describe('SINGLE: Optional discussion ID to link to existing conversation'),
|
|
676
1075
|
followerIds: zod_1.z
|
|
677
1076
|
.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()])
|
|
678
1077
|
.optional()
|
|
679
|
-
.describe(
|
|
1078
|
+
.describe('SINGLE: Optional array of user IDs to invite'),
|
|
680
1079
|
fileIds: zod_1.z
|
|
681
1080
|
.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()])
|
|
682
1081
|
.optional()
|
|
683
|
-
.describe(
|
|
1082
|
+
.describe('SINGLE: Optional array of file IDs to attach'),
|
|
684
1083
|
}),
|
|
685
1084
|
async execute(args, context) {
|
|
686
1085
|
try {
|
|
687
1086
|
// DEBUG: Log raw input to diagnose LLM tool calling issues
|
|
688
|
-
logger.debug(
|
|
1087
|
+
logger.debug('create_activity called', {
|
|
689
1088
|
hasName: !!args.name,
|
|
690
1089
|
hasActivities: !!args.activities,
|
|
691
1090
|
activitiesType: typeof args.activities,
|
|
@@ -701,7 +1100,7 @@ exports.createActivityTool = {
|
|
|
701
1100
|
};
|
|
702
1101
|
if (activityData.fields) {
|
|
703
1102
|
let parsedFields = activityData.fields;
|
|
704
|
-
if (typeof activityData.fields ===
|
|
1103
|
+
if (typeof activityData.fields === 'string' && activityData.fields.trim() !== '') {
|
|
705
1104
|
try {
|
|
706
1105
|
parsedFields = JSON.parse(activityData.fields);
|
|
707
1106
|
}
|
|
@@ -710,22 +1109,22 @@ exports.createActivityTool = {
|
|
|
710
1109
|
}
|
|
711
1110
|
}
|
|
712
1111
|
if (parsedFields &&
|
|
713
|
-
typeof parsedFields ===
|
|
1112
|
+
typeof parsedFields === 'object' &&
|
|
714
1113
|
Object.keys(parsedFields).length > 0) {
|
|
715
1114
|
autoFixDateFields(parsedFields, context);
|
|
716
1115
|
activity.fields = parsedFields;
|
|
717
1116
|
}
|
|
718
1117
|
}
|
|
719
|
-
if (activityData.phaseId && activityData.phaseId.trim() !==
|
|
1118
|
+
if (activityData.phaseId && activityData.phaseId.trim() !== '') {
|
|
720
1119
|
activity.phaseId = activityData.phaseId;
|
|
721
1120
|
}
|
|
722
|
-
if (activityData.teamId && activityData.teamId.trim() !==
|
|
1121
|
+
if (activityData.teamId && activityData.teamId.trim() !== '') {
|
|
723
1122
|
activity.teamId = activityData.teamId;
|
|
724
1123
|
}
|
|
725
1124
|
if (activityData.followerIds) {
|
|
726
1125
|
let parsedFollowerIds = activityData.followerIds;
|
|
727
|
-
if (typeof activityData.followerIds ===
|
|
728
|
-
activityData.followerIds.trim() !==
|
|
1126
|
+
if (typeof activityData.followerIds === 'string' &&
|
|
1127
|
+
activityData.followerIds.trim() !== '') {
|
|
729
1128
|
try {
|
|
730
1129
|
parsedFollowerIds = JSON.parse(activityData.followerIds);
|
|
731
1130
|
}
|
|
@@ -744,7 +1143,7 @@ exports.createActivityTool = {
|
|
|
744
1143
|
}
|
|
745
1144
|
}
|
|
746
1145
|
if (invalidUsers.length > 0) {
|
|
747
|
-
throw new Error(`Invalid user IDs in followerIds: ${invalidUsers.join(
|
|
1146
|
+
throw new Error(`Invalid user IDs in followerIds: ${invalidUsers.join(', ')}. Use search_workspace_users to find valid user IDs.`);
|
|
748
1147
|
}
|
|
749
1148
|
}
|
|
750
1149
|
activity.followerIds = parsedFollowerIds;
|
|
@@ -752,8 +1151,8 @@ exports.createActivityTool = {
|
|
|
752
1151
|
}
|
|
753
1152
|
if (activityData.fileIds) {
|
|
754
1153
|
let parsedFileIds = activityData.fileIds;
|
|
755
|
-
if (typeof activityData.fileIds ===
|
|
756
|
-
activityData.fileIds.trim() !==
|
|
1154
|
+
if (typeof activityData.fileIds === 'string' &&
|
|
1155
|
+
activityData.fileIds.trim() !== '') {
|
|
757
1156
|
try {
|
|
758
1157
|
parsedFileIds = JSON.parse(activityData.fileIds);
|
|
759
1158
|
}
|
|
@@ -791,7 +1190,7 @@ exports.createActivityTool = {
|
|
|
791
1190
|
}
|
|
792
1191
|
}
|
|
793
1192
|
let activitiesToCreate;
|
|
794
|
-
|
|
1193
|
+
const options = {
|
|
795
1194
|
returnDocument: true,
|
|
796
1195
|
};
|
|
797
1196
|
if (isBulk) {
|
|
@@ -810,7 +1209,7 @@ exports.createActivityTool = {
|
|
|
810
1209
|
return activity;
|
|
811
1210
|
});
|
|
812
1211
|
// Check for common discussionId in bulk
|
|
813
|
-
if (args.discussionId && args.discussionId.trim() !==
|
|
1212
|
+
if (args.discussionId && args.discussionId.trim() !== '') {
|
|
814
1213
|
options.discussionId = args.discussionId;
|
|
815
1214
|
}
|
|
816
1215
|
}
|
|
@@ -819,7 +1218,7 @@ exports.createActivityTool = {
|
|
|
819
1218
|
if (!args.name) {
|
|
820
1219
|
throw new Error("Either 'activities' array or 'name' parameter is required");
|
|
821
1220
|
}
|
|
822
|
-
logger.debug(
|
|
1221
|
+
logger.debug('Creating single activity', {
|
|
823
1222
|
workflowId: args.workflowId,
|
|
824
1223
|
name: args.name,
|
|
825
1224
|
defaultTeamId: defaultTeamId,
|
|
@@ -830,12 +1229,29 @@ exports.createActivityTool = {
|
|
|
830
1229
|
activity.teamId = defaultTeamId;
|
|
831
1230
|
}
|
|
832
1231
|
activitiesToCreate = [activity];
|
|
833
|
-
if (args.discussionId && args.discussionId.trim() !==
|
|
1232
|
+
if (args.discussionId && args.discussionId.trim() !== '') {
|
|
834
1233
|
options.discussionId = args.discussionId;
|
|
835
1234
|
}
|
|
836
1235
|
}
|
|
1236
|
+
// Pre-validate field keys before API call ā runs AFTER processActivity's
|
|
1237
|
+
// auto-fixups (values only, keys unchanged; see validateFieldKeys).
|
|
1238
|
+
// Unknown keys (e.g. field NAMES) silently no-op server-side.
|
|
1239
|
+
const workflow = context.init.processes?.find((proc) => proc._id === args.workflowId);
|
|
1240
|
+
const workflowFieldDefs = workflow?.fields;
|
|
1241
|
+
for (let i = 0; i < activitiesToCreate.length; i++) {
|
|
1242
|
+
const item = activitiesToCreate[i];
|
|
1243
|
+
const keyError = workflowFieldDefs && item.fields ? validateFieldKeys(item.fields, workflowFieldDefs) : undefined;
|
|
1244
|
+
if (keyError) {
|
|
1245
|
+
const itemName = item.name || `Activity ${i + 1}`;
|
|
1246
|
+
return {
|
|
1247
|
+
content: [{
|
|
1248
|
+
type: 'text',
|
|
1249
|
+
text: `ā Invalid field keys in "${itemName}" ā nothing was created.\n\n${keyError}`,
|
|
1250
|
+
}],
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
837
1254
|
// Pre-validate required fields before API call
|
|
838
|
-
const workflow = context.init.processes?.find((p) => p._id === args.workflowId);
|
|
839
1255
|
if (workflow?.fields) {
|
|
840
1256
|
const requiredFields = [];
|
|
841
1257
|
for (const [fieldId, field] of Object.entries(workflow.fields)) {
|
|
@@ -864,7 +1280,7 @@ exports.createActivityTool = {
|
|
|
864
1280
|
const fieldList = requiredFields.map(f => `- ${f.label} (key: ${f.key}, id: ${f.id})`).join('\n');
|
|
865
1281
|
return {
|
|
866
1282
|
content: [{
|
|
867
|
-
type:
|
|
1283
|
+
type: 'text',
|
|
868
1284
|
text: `ā Missing required fields - cannot create activities.\n\n**Required fields for this workflow:**\n${fieldList}\n\n**Activities with missing fields:**\n${missingByActivity.map(m => `- ${m}`).join('\n')}\n\nš” Add the missing fields to each activity's \`fields\` object using either the field key or ID.`,
|
|
869
1285
|
}],
|
|
870
1286
|
};
|
|
@@ -891,7 +1307,7 @@ exports.createActivityTool = {
|
|
|
891
1307
|
return {
|
|
892
1308
|
content: [
|
|
893
1309
|
{
|
|
894
|
-
type:
|
|
1310
|
+
type: 'text',
|
|
895
1311
|
text: responseText,
|
|
896
1312
|
},
|
|
897
1313
|
],
|
|
@@ -922,7 +1338,7 @@ exports.createActivityTool = {
|
|
|
922
1338
|
return {
|
|
923
1339
|
content: [
|
|
924
1340
|
{
|
|
925
|
-
type:
|
|
1341
|
+
type: 'text',
|
|
926
1342
|
text: responseText,
|
|
927
1343
|
},
|
|
928
1344
|
],
|
|
@@ -930,11 +1346,12 @@ exports.createActivityTool = {
|
|
|
930
1346
|
}
|
|
931
1347
|
}
|
|
932
1348
|
catch (error) {
|
|
933
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
934
|
-
logger.error(
|
|
1349
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1350
|
+
logger.error('Failed to create activity/activities', error, {
|
|
935
1351
|
workflowId: args.workflowId,
|
|
936
1352
|
isBulk: !!(args.activities && args.activities.length > 0),
|
|
937
1353
|
});
|
|
1354
|
+
}
|
|
938
1355
|
const errorMessage = error instanceof Error
|
|
939
1356
|
? error.message
|
|
940
1357
|
: (typeof error === 'object' && error !== null)
|
|
@@ -943,7 +1360,7 @@ exports.createActivityTool = {
|
|
|
943
1360
|
return {
|
|
944
1361
|
content: [
|
|
945
1362
|
{
|
|
946
|
-
type:
|
|
1363
|
+
type: 'text',
|
|
947
1364
|
text: `ā Error creating activity: ${errorMessage}\n\nš” Troubleshooting Tips:\n- Verify the workflowId exists and is accessible\n- Check that you have permission to create activities in this workflow\n- Ensure field IDs in the fields object match the workflow's field definitions\n- Use search_workspace_users to find valid user IDs for assignment\n- Verify user IDs in followerIds exist and are accessible`,
|
|
948
1365
|
},
|
|
949
1366
|
],
|
|
@@ -956,10 +1373,11 @@ exports.createActivityTool = {
|
|
|
956
1373
|
// ============================================================================
|
|
957
1374
|
const updateActivityDescription = `Update an existing activity - change fields or move to different phase.
|
|
958
1375
|
|
|
959
|
-
**To update fields:** Get field IDs from \`
|
|
960
|
-
**To change phase:** Get phase IDs from \`
|
|
1376
|
+
**To update fields:** Get field IDs from \`describe_workflows\` (include: ['schema']) first, then pass them in the fields object.
|
|
1377
|
+
**To change phase:** Get phase IDs from \`describe_workflows\` (include: ['phases']), pass target phaseId.
|
|
961
1378
|
|
|
962
1379
|
**Required:** activityId (for single) OR activities[] array (for bulk)
|
|
1380
|
+
**Performance:** Pass \`workflowId\` whenever you know it (you usually do ā it came from list_activities). It skips a per-activity server read used for field-key validation; on bulk updates that is one read per activity saved.
|
|
963
1381
|
|
|
964
1382
|
**Field value formats:**
|
|
965
1383
|
- Text: \`"value"\`
|
|
@@ -976,9 +1394,9 @@ exports.updateActivityTool = {
|
|
|
976
1394
|
schema: zod_1.z.object({
|
|
977
1395
|
// BULK: Array of activities to update
|
|
978
1396
|
activities: zod_1.z
|
|
979
|
-
.preprocess((val) => (typeof val ===
|
|
1397
|
+
.preprocess((val) => (typeof val === 'string' ? JSON.parse(val) : val), zod_1.z
|
|
980
1398
|
.array(zod_1.z.object({
|
|
981
|
-
_id: zod_1.z.string().min(24,
|
|
1399
|
+
_id: zod_1.z.string().min(24, 'Activity ID must be at least 24 characters'),
|
|
982
1400
|
name: zod_1.z.string().optional(),
|
|
983
1401
|
fields: zod_1.z.record(zod_1.z.any()).optional(),
|
|
984
1402
|
phaseId: zod_1.z.string().optional(),
|
|
@@ -989,10 +1407,10 @@ exports.updateActivityTool = {
|
|
|
989
1407
|
// SINGLE: Individual activity parameters
|
|
990
1408
|
activityId: zod_1.z
|
|
991
1409
|
.string()
|
|
992
|
-
.min(24,
|
|
1410
|
+
.min(24, 'Activity ID must be at least 24 characters')
|
|
993
1411
|
.optional()
|
|
994
|
-
.describe(
|
|
995
|
-
name: zod_1.z.string().optional().describe(
|
|
1412
|
+
.describe('SINGLE: The unique ID of the activity to update (works for any workflow)'),
|
|
1413
|
+
name: zod_1.z.string().optional().describe('SINGLE: New activity title/name'),
|
|
996
1414
|
fields: zod_1.z
|
|
997
1415
|
.union([zod_1.z.record(zod_1.z.any()), zod_1.z.string()])
|
|
998
1416
|
.optional()
|
|
@@ -1000,97 +1418,24 @@ exports.updateActivityTool = {
|
|
|
1000
1418
|
phaseId: zod_1.z
|
|
1001
1419
|
.string()
|
|
1002
1420
|
.optional()
|
|
1003
|
-
.describe(
|
|
1421
|
+
.describe('SINGLE: Optional phase ID or key to move the activity to'),
|
|
1422
|
+
workflowId: zod_1.z
|
|
1423
|
+
.string()
|
|
1424
|
+
.optional()
|
|
1425
|
+
.describe('Workflow ID or key the activities belong to (single AND bulk). Strongly recommended when known: skips one validation read per activity'),
|
|
1004
1426
|
}),
|
|
1005
1427
|
async execute(args, context) {
|
|
1006
1428
|
try {
|
|
1007
1429
|
// BULK MODE: Update multiple activities
|
|
1008
1430
|
if (args.activities && Array.isArray(args.activities)) {
|
|
1009
|
-
|
|
1010
|
-
activityCount: args.activities.length,
|
|
1011
|
-
activities: JSON.stringify(args.activities, null, 2)
|
|
1012
|
-
});
|
|
1013
|
-
// Auto-fix common parameter name mistakes
|
|
1014
|
-
for (const activity of args.activities) {
|
|
1015
|
-
// Fix activityId -> _id
|
|
1016
|
-
if (!activity._id && activity.activityId) {
|
|
1017
|
-
logger.warn("Auto-fixing: activityId -> _id", { activityId: activity.activityId });
|
|
1018
|
-
activity._id = activity.activityId;
|
|
1019
|
-
delete activity.activityId;
|
|
1020
|
-
}
|
|
1021
|
-
// Fix fieldsAndValues -> fields
|
|
1022
|
-
if (!activity.fields && activity.fieldsAndValues) {
|
|
1023
|
-
logger.warn("Auto-fixing: fieldsAndValues -> fields", { activityId: activity._id });
|
|
1024
|
-
activity.fields = activity.fieldsAndValues;
|
|
1025
|
-
delete activity.fieldsAndValues;
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
// Validate that all activities have _id
|
|
1029
|
-
const invalidActivities = args.activities.filter((a) => !a._id || typeof a._id !== 'string' || a._id.length < 24);
|
|
1030
|
-
if (invalidActivities.length > 0) {
|
|
1031
|
-
return {
|
|
1032
|
-
content: [{
|
|
1033
|
-
type: "text",
|
|
1034
|
-
text: `ā **Error: Invalid bulk update request**\n\nEach activity in the "activities" array MUST have a valid "_id" field (24-character activity ID).\n\n**What you sent:** ${JSON.stringify(args.activities, null, 2)}\n\n**Correct format:**\n\`\`\`json\n{\n "activities": [\n { "_id": "691ffe654217e9e8434e577c", "fields": { "fieldId": "value" } },\n { "_id": "691ffe654217e9e8434e5774", "name": "New Name" }\n ]\n}\n\`\`\`\n\n**Tip:** First use list_activities to get the activity IDs, then pass them in the _id field.`,
|
|
1035
|
-
}],
|
|
1036
|
-
};
|
|
1037
|
-
}
|
|
1038
|
-
// Build updates for each activity
|
|
1039
|
-
const updates = args.activities.map((activity) => {
|
|
1040
|
-
const activityUpdate = { _id: activity._id };
|
|
1041
|
-
if (activity.name)
|
|
1042
|
-
activityUpdate.name = activity.name;
|
|
1043
|
-
if (activity.fields) {
|
|
1044
|
-
// Parse fields if string
|
|
1045
|
-
let parsedFields = typeof activity.fields === 'string'
|
|
1046
|
-
? JSON.parse(activity.fields)
|
|
1047
|
-
: activity.fields;
|
|
1048
|
-
// Auto-fix activitylink fields: if LLM passes object with _id, extract just the ID
|
|
1049
|
-
if (parsedFields && typeof parsedFields === "object") {
|
|
1050
|
-
for (const [fieldId, fieldValue] of Object.entries(parsedFields)) {
|
|
1051
|
-
if (fieldValue &&
|
|
1052
|
-
typeof fieldValue === "object" &&
|
|
1053
|
-
!Array.isArray(fieldValue) &&
|
|
1054
|
-
"_id" in fieldValue &&
|
|
1055
|
-
typeof fieldValue._id === "string") {
|
|
1056
|
-
logger.warn("Auto-fixing activitylink field in bulk mode", {
|
|
1057
|
-
activityId: activity._id,
|
|
1058
|
-
fieldId,
|
|
1059
|
-
extracted: fieldValue._id,
|
|
1060
|
-
});
|
|
1061
|
-
parsedFields[fieldId] = fieldValue._id;
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
autoFixDateFields(parsedFields, context);
|
|
1066
|
-
activityUpdate.fields = parsedFields;
|
|
1067
|
-
}
|
|
1068
|
-
return activityUpdate;
|
|
1069
|
-
});
|
|
1070
|
-
// Collect unique phase IDs (most activities will have the same phase)
|
|
1071
|
-
const phaseIds = args.activities
|
|
1072
|
-
.map((a) => a.phaseId)
|
|
1073
|
-
.filter((p) => p);
|
|
1074
|
-
const commonPhaseId = phaseIds.length > 0 ? phaseIds[0] : undefined;
|
|
1075
|
-
// Call API with all updates
|
|
1076
|
-
const options = commonPhaseId ? { phaseId: commonPhaseId } : undefined;
|
|
1077
|
-
await context.hailer.updateActivities(updates, options);
|
|
1078
|
-
// Format bulk response
|
|
1079
|
-
return {
|
|
1080
|
-
content: [
|
|
1081
|
-
{
|
|
1082
|
-
type: "text",
|
|
1083
|
-
text: `š Successfully updated ${args.activities.length} activities!\n\nš **Bulk Update Summary:**\n- **Total Updated**: ${args.activities.length} activities\n- **Status**: All activities updated successfully\n\nā
All activities have been updated in your Hailer workspace!`,
|
|
1084
|
-
},
|
|
1085
|
-
],
|
|
1086
|
-
};
|
|
1431
|
+
return await executeBulkUpdate(args.activities, context, args.workflowId);
|
|
1087
1432
|
}
|
|
1088
1433
|
// SINGLE MODE: Update one activity
|
|
1089
1434
|
// Validate activityId is provided for single mode
|
|
1090
1435
|
if (!args.activityId || typeof args.activityId !== 'string' || args.activityId.length < 24) {
|
|
1091
1436
|
return {
|
|
1092
1437
|
content: [{
|
|
1093
|
-
type:
|
|
1438
|
+
type: 'text',
|
|
1094
1439
|
text: `ā **Error: Missing or invalid activityId**\n\nFor single activity updates, you must provide a valid "activityId" (24-character hex string).\n\n**What you sent:** activityId = ${JSON.stringify(args.activityId)}\n\n**Correct format:**\n\`\`\`json\n{\n "activityId": "691ffe654217e9e8434e577c",\n "name": "New Name",\n "fields": { "fieldId": "value" }\n}\n\`\`\`\n\n**For bulk updates (3+ activities), use:**\n\`\`\`json\n{\n "activities": [\n { "_id": "activity-id-1", "fields": {...} },\n { "_id": "activity-id-2", "name": "New Name" }\n ]\n}\n\`\`\`\n\n**Tip:** Use list_activities or show_activity_by_id to find activity IDs first.`,
|
|
1095
1440
|
}],
|
|
1096
1441
|
};
|
|
@@ -1099,32 +1444,44 @@ exports.updateActivityTool = {
|
|
|
1099
1444
|
if (!args.name && !args.fields && !args.phaseId) {
|
|
1100
1445
|
return {
|
|
1101
1446
|
content: [{
|
|
1102
|
-
type:
|
|
1447
|
+
type: 'text',
|
|
1103
1448
|
text: `ā **Error: No update data provided**\n\nYou called update_activity with activityId="${args.activityId}" but didn't provide any data to update.\n\n**You must provide at least one of:**\n- "name" - to update the activity name\n- "fields" - to update field values\n- "phaseId" - to move to a different phase\n\n**Example:**\n\`\`\`json\n{\n "activityId": "${args.activityId}",\n "fields": {\n "fieldId123": "new value"\n }\n}\n\`\`\``,
|
|
1104
1449
|
}],
|
|
1105
1450
|
};
|
|
1106
1451
|
}
|
|
1107
|
-
logger.debug(
|
|
1452
|
+
logger.debug('Single update mode', {
|
|
1108
1453
|
activityId: args.activityId,
|
|
1109
1454
|
name: args.name,
|
|
1110
1455
|
fields: JSON.stringify(args.fields, null, 2),
|
|
1111
1456
|
phaseId: args.phaseId
|
|
1112
1457
|
});
|
|
1113
1458
|
const updates = buildActivityUpdate(args, context);
|
|
1459
|
+
// Field-key validation ā runs AFTER buildActivityUpdate's auto-fixups
|
|
1460
|
+
// (values only, keys unchanged; see validateFieldKeys), right before the
|
|
1461
|
+
// API call. Unknown keys (e.g. field NAMES) silently no-op server-side.
|
|
1462
|
+
const singleKeyError = updates.fields
|
|
1463
|
+
? await validateUpdateFieldKeys(args.activityId, updates.fields, context, resolveKnownWorkflowFields(args.workflowId, context))
|
|
1464
|
+
: undefined;
|
|
1465
|
+
if (singleKeyError) {
|
|
1466
|
+
return {
|
|
1467
|
+
content: [{ type: 'text', text: singleKeyError }],
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1114
1470
|
const options = args.phaseId ? { phaseId: args.phaseId } : undefined;
|
|
1115
1471
|
const result = await context.hailer.updateActivities([updates], options);
|
|
1116
1472
|
return formatUpdateActivityResponse(args, result);
|
|
1117
1473
|
}
|
|
1118
1474
|
catch (error) {
|
|
1119
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1120
|
-
logger.error(
|
|
1475
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
1476
|
+
logger.error('Failed to update activity', error, {
|
|
1121
1477
|
activityId: args.activityId || 'bulk',
|
|
1122
1478
|
activityCount: args.activities?.length,
|
|
1123
1479
|
});
|
|
1480
|
+
}
|
|
1124
1481
|
return {
|
|
1125
1482
|
content: [
|
|
1126
1483
|
{
|
|
1127
|
-
type:
|
|
1484
|
+
type: 'text',
|
|
1128
1485
|
text: `ā Error updating ${args.activities ? 'activities' : 'activity'}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1129
1486
|
},
|
|
1130
1487
|
],
|