@jungjaehoon/mama-os 0.28.6 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent-loop.d.ts +0 -4
- package/dist/agent/agent-loop.d.ts.map +1 -1
- package/dist/agent/agent-loop.js +33 -10
- package/dist/agent/agent-loop.js.map +1 -1
- package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
- package/dist/agent/code-act/host-bridge.js +53 -3
- package/dist/agent/code-act/host-bridge.js.map +1 -1
- package/dist/agent/code-act/tool-policy.d.ts.map +1 -1
- package/dist/agent/code-act/tool-policy.js +5 -0
- package/dist/agent/code-act/tool-policy.js.map +1 -1
- package/dist/agent/codex-auth.d.ts +0 -1
- package/dist/agent/codex-auth.d.ts.map +1 -1
- package/dist/agent/codex-auth.js +0 -4
- package/dist/agent/codex-auth.js.map +1 -1
- package/dist/agent/codex-home.d.ts +0 -2
- package/dist/agent/codex-home.d.ts.map +1 -1
- package/dist/agent/codex-home.js +0 -66
- package/dist/agent/codex-home.js.map +1 -1
- package/dist/agent/context-compile-service.d.ts +9 -0
- package/dist/agent/context-compile-service.d.ts.map +1 -1
- package/dist/agent/context-compile-service.js +6 -0
- package/dist/agent/context-compile-service.js.map +1 -1
- package/dist/agent/context-prompt-builder.d.ts +0 -6
- package/dist/agent/context-prompt-builder.d.ts.map +1 -1
- package/dist/agent/context-prompt-builder.js +0 -131
- package/dist/agent/context-prompt-builder.js.map +1 -1
- package/dist/agent/contract-extractor.d.ts +0 -4
- package/dist/agent/contract-extractor.d.ts.map +1 -1
- package/dist/agent/contract-extractor.js +0 -68
- package/dist/agent/contract-extractor.js.map +1 -1
- package/dist/agent/gateway-tool-executor.d.ts +20 -15
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
- package/dist/agent/gateway-tool-executor.js +236 -90
- package/dist/agent/gateway-tool-executor.js.map +1 -1
- package/dist/agent/gateway-tools.md +7 -4
- package/dist/agent/skill-loader.d.ts +0 -7
- package/dist/agent/skill-loader.d.ts.map +1 -1
- package/dist/agent/skill-loader.js +0 -86
- package/dist/agent/skill-loader.js.map +1 -1
- package/dist/agent/token-estimator.d.ts +0 -8
- package/dist/agent/token-estimator.d.ts.map +1 -1
- package/dist/agent/token-estimator.js +0 -14
- package/dist/agent/token-estimator.js.map +1 -1
- package/dist/agent/tool-registry.d.ts.map +1 -1
- package/dist/agent/tool-registry.js +23 -5
- package/dist/agent/tool-registry.js.map +1 -1
- package/dist/agent/types.d.ts +27 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/agent-graph-handler.d.ts +9 -0
- package/dist/api/agent-graph-handler.d.ts.map +1 -1
- package/dist/api/agent-graph-handler.js +27 -1
- package/dist/api/agent-graph-handler.js.map +1 -1
- package/dist/api/entity-audit-handler.d.ts +1 -2
- package/dist/api/entity-audit-handler.d.ts.map +1 -1
- package/dist/api/entity-audit-handler.js +0 -5
- package/dist/api/entity-audit-handler.js.map +1 -1
- package/dist/api/index.d.ts +1 -9
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +4 -17
- package/dist/api/index.js.map +1 -1
- package/dist/api/intelligence-handler.d.ts +0 -5
- package/dist/api/intelligence-handler.d.ts.map +1 -1
- package/dist/api/intelligence-handler.js +0 -15
- package/dist/api/intelligence-handler.js.map +1 -1
- package/dist/api/types.d.ts +1 -5
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js +0 -14
- package/dist/api/types.js.map +1 -1
- package/dist/cli/commands/start.d.ts +117 -3
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +223 -62
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/config-manager.d.ts +0 -5
- package/dist/cli/config/config-manager.d.ts.map +1 -1
- package/dist/cli/config/config-manager.js +0 -29
- package/dist/cli/config/config-manager.js.map +1 -1
- package/dist/cli/config/types.d.ts.map +1 -1
- package/dist/cli/config/types.js +3 -0
- package/dist/cli/config/types.js.map +1 -1
- package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-routes-init.js +32 -5
- package/dist/cli/runtime/api-routes-init.js.map +1 -1
- package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-server-init.js +2 -0
- package/dist/cli/runtime/api-server-init.js.map +1 -1
- package/dist/cli/runtime/gateway-init.d.ts +1 -1
- package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
- package/dist/cli/runtime/gateway-init.js +11 -38
- package/dist/cli/runtime/gateway-init.js.map +1 -1
- package/dist/cli/runtime/gateway-wiring.d.ts.map +1 -1
- package/dist/cli/runtime/gateway-wiring.js +6 -120
- package/dist/cli/runtime/gateway-wiring.js.map +1 -1
- package/dist/cli/utils/pid-manager.d.ts +0 -10
- package/dist/cli/utils/pid-manager.d.ts.map +1 -1
- package/dist/cli/utils/pid-manager.js +0 -26
- package/dist/cli/utils/pid-manager.js.map +1 -1
- package/dist/connectors/framework/polling-scheduler.d.ts +33 -1
- package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
- package/dist/connectors/framework/polling-scheduler.js +46 -40
- package/dist/connectors/framework/polling-scheduler.js.map +1 -1
- package/dist/connectors/trello/query-tools.d.ts +32 -5
- package/dist/connectors/trello/query-tools.d.ts.map +1 -1
- package/dist/connectors/trello/query-tools.js +56 -17
- package/dist/connectors/trello/query-tools.js.map +1 -1
- package/dist/db/agent-store.d.ts +0 -4
- package/dist/db/agent-store.d.ts.map +1 -1
- package/dist/db/agent-store.js +0 -65
- package/dist/db/agent-store.js.map +1 -1
- package/dist/envelope/enforcer.d.ts.map +1 -1
- package/dist/envelope/enforcer.js +10 -1
- package/dist/envelope/enforcer.js.map +1 -1
- package/dist/envelope/index.d.ts +0 -1
- package/dist/envelope/index.d.ts.map +1 -1
- package/dist/envelope/index.js +0 -1
- package/dist/envelope/index.js.map +1 -1
- package/dist/envelope/signature.d.ts +0 -1
- package/dist/envelope/signature.d.ts.map +1 -1
- package/dist/envelope/signature.js +0 -7
- package/dist/envelope/signature.js.map +1 -1
- package/dist/envelope/tool-connector-scope.d.ts +35 -0
- package/dist/envelope/tool-connector-scope.d.ts.map +1 -0
- package/dist/envelope/tool-connector-scope.js +57 -0
- package/dist/envelope/tool-connector-scope.js.map +1 -0
- package/dist/evidence/effects.d.ts +107 -0
- package/dist/evidence/effects.d.ts.map +1 -0
- package/dist/evidence/effects.js +281 -0
- package/dist/evidence/effects.js.map +1 -0
- package/dist/evidence/read.d.ts +75 -0
- package/dist/evidence/read.d.ts.map +1 -0
- package/dist/evidence/read.js +105 -0
- package/dist/evidence/read.js.map +1 -0
- package/dist/gateways/base-gateway.d.ts +23 -3
- package/dist/gateways/base-gateway.d.ts.map +1 -1
- package/dist/gateways/base-gateway.js +15 -2
- package/dist/gateways/base-gateway.js.map +1 -1
- package/dist/gateways/discord.d.ts +4 -16
- package/dist/gateways/discord.d.ts.map +1 -1
- package/dist/gateways/discord.js +22 -189
- package/dist/gateways/discord.js.map +1 -1
- package/dist/gateways/index.d.ts +2 -1
- package/dist/gateways/index.d.ts.map +1 -1
- package/dist/gateways/message-router.d.ts +13 -20
- package/dist/gateways/message-router.d.ts.map +1 -1
- package/dist/gateways/message-router.js +32 -3
- package/dist/gateways/message-router.js.map +1 -1
- package/dist/gateways/slack.d.ts +2 -12
- package/dist/gateways/slack.d.ts.map +1 -1
- package/dist/gateways/slack.js +6 -220
- package/dist/gateways/slack.js.map +1 -1
- package/dist/gateways/telegram.d.ts +2 -2
- package/dist/gateways/telegram.d.ts.map +1 -1
- package/dist/gateways/telegram.js +3 -2
- package/dist/gateways/telegram.js.map +1 -1
- package/dist/gateways/turn-contract.d.ts +104 -0
- package/dist/gateways/turn-contract.d.ts.map +1 -0
- package/dist/{memory/consult-contract.js → gateways/turn-contract.js} +1 -1
- package/dist/gateways/turn-contract.js.map +1 -0
- package/dist/memory/provenance-live.d.ts +111 -0
- package/dist/memory/provenance-live.d.ts.map +1 -0
- package/dist/memory/provenance-live.js +381 -0
- package/dist/memory/provenance-live.js.map +1 -0
- package/dist/memory/provenance-resolver.d.ts +184 -0
- package/dist/memory/provenance-resolver.d.ts.map +1 -0
- package/dist/memory/provenance-resolver.js +152 -0
- package/dist/memory/provenance-resolver.js.map +1 -0
- package/dist/multi-agent/agent-event-bus.d.ts +1 -0
- package/dist/multi-agent/agent-event-bus.d.ts.map +1 -1
- package/dist/multi-agent/bmad-templates.d.ts +0 -18
- package/dist/multi-agent/bmad-templates.d.ts.map +1 -1
- package/dist/multi-agent/bmad-templates.js +0 -127
- package/dist/multi-agent/bmad-templates.js.map +1 -1
- package/dist/multi-agent/dashboard-agent-persona.js +3 -3
- package/dist/operator/board-reconcile.d.ts +2 -3
- package/dist/operator/board-reconcile.d.ts.map +1 -1
- package/dist/operator/board-reconcile.js +18 -32
- package/dist/operator/board-reconcile.js.map +1 -1
- package/dist/operator/changes-projection.d.ts +70 -0
- package/dist/operator/changes-projection.d.ts.map +1 -0
- package/dist/operator/changes-projection.js +109 -0
- package/dist/operator/changes-projection.js.map +1 -0
- package/dist/operator/external-correlation.d.ts +94 -0
- package/dist/operator/external-correlation.d.ts.map +1 -0
- package/dist/operator/external-correlation.js +177 -0
- package/dist/operator/external-correlation.js.map +1 -0
- package/dist/operator/operator-trigger-loop.d.ts +9 -1
- package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
- package/dist/operator/operator-trigger-loop.js +8 -4
- package/dist/operator/operator-trigger-loop.js.map +1 -1
- package/dist/operator/provenance-lookup.d.ts +18 -0
- package/dist/operator/provenance-lookup.d.ts.map +1 -0
- package/dist/operator/provenance-lookup.js +54 -0
- package/dist/operator/provenance-lookup.js.map +1 -0
- package/dist/operator/report-carry.d.ts +18 -1
- package/dist/operator/report-carry.d.ts.map +1 -1
- package/dist/operator/report-carry.js +22 -3
- package/dist/operator/report-carry.js.map +1 -1
- package/dist/operator/report-run.d.ts +31 -0
- package/dist/operator/report-run.d.ts.map +1 -1
- package/dist/operator/report-run.js +140 -22
- package/dist/operator/report-run.js.map +1 -1
- package/dist/operator/task-ledger.d.ts +84 -2
- package/dist/operator/task-ledger.d.ts.map +1 -1
- package/dist/operator/task-ledger.js +274 -31
- package/dist/operator/task-ledger.js.map +1 -1
- package/dist/operator/worker-run.js +1 -1
- package/dist/operator/worker-run.js.map +1 -1
- package/dist/operator/workorder-hooks.d.ts +79 -4
- package/dist/operator/workorder-hooks.d.ts.map +1 -1
- package/dist/operator/workorder-hooks.js +152 -20
- package/dist/operator/workorder-hooks.js.map +1 -1
- package/dist/operator/workorder-publishers.d.ts +2 -0
- package/dist/operator/workorder-publishers.d.ts.map +1 -1
- package/dist/operator/workorder-publishers.js +8 -1
- package/dist/operator/workorder-publishers.js.map +1 -1
- package/dist/utils/untrusted-content.d.ts +11 -0
- package/dist/utils/untrusted-content.d.ts.map +1 -1
- package/dist/utils/untrusted-content.js +20 -0
- package/dist/utils/untrusted-content.js.map +1 -1
- package/package.json +4 -3
- package/scripts/backfill-channel-keys.ts +451 -0
- package/dist/agent/auto-recall.d.ts +0 -48
- package/dist/agent/auto-recall.d.ts.map +0 -1
- package/dist/agent/auto-recall.js +0 -192
- package/dist/agent/auto-recall.js.map +0 -1
- package/dist/agent/claude-client.d.ts +0 -50
- package/dist/agent/claude-client.d.ts.map +0 -1
- package/dist/agent/claude-client.js +0 -219
- package/dist/agent/claude-client.js.map +0 -1
- package/dist/agent/delegation-executor.d.ts +0 -49
- package/dist/agent/delegation-executor.d.ts.map +0 -1
- package/dist/agent/delegation-executor.js +0 -692
- package/dist/agent/delegation-executor.js.map +0 -1
- package/dist/agent/mcp-executor.d.ts +0 -60
- package/dist/agent/mcp-executor.d.ts.map +0 -1
- package/dist/agent/mcp-executor.js +0 -190
- package/dist/agent/mcp-executor.js.map +0 -1
- package/dist/agent/process-tree.d.ts +0 -6
- package/dist/agent/process-tree.d.ts.map +0 -1
- package/dist/agent/process-tree.js +0 -21
- package/dist/agent/process-tree.js.map +0 -1
- package/dist/agent/streaming-callback-manager.d.ts +0 -85
- package/dist/agent/streaming-callback-manager.d.ts.map +0 -1
- package/dist/agent/streaming-callback-manager.js +0 -103
- package/dist/agent/streaming-callback-manager.js.map +0 -1
- package/dist/agent/token-budget.d.ts +0 -49
- package/dist/agent/token-budget.d.ts.map +0 -1
- package/dist/agent/token-budget.js +0 -92
- package/dist/agent/token-budget.js.map +0 -1
- package/dist/connectors/kagemusha/history-compiler.d.ts +0 -18
- package/dist/connectors/kagemusha/history-compiler.d.ts.map +0 -1
- package/dist/connectors/kagemusha/history-compiler.js +0 -35
- package/dist/connectors/kagemusha/history-compiler.js.map +0 -1
- package/dist/db/migrations/wiki-artifacts.d.ts +0 -3
- package/dist/db/migrations/wiki-artifacts.d.ts.map +0 -1
- package/dist/db/migrations/wiki-artifacts.js +0 -24
- package/dist/db/migrations/wiki-artifacts.js.map +0 -1
- package/dist/envelope/subset.d.ts +0 -9
- package/dist/envelope/subset.d.ts.map +0 -1
- package/dist/envelope/subset.js +0 -67
- package/dist/envelope/subset.js.map +0 -1
- package/dist/memory/consult-contract.d.ts +0 -8
- package/dist/memory/consult-contract.d.ts.map +0 -1
- package/dist/memory/consult-contract.js.map +0 -1
- package/dist/multi-agent/agent-message-queue.d.ts +0 -104
- package/dist/multi-agent/agent-message-queue.d.ts.map +0 -1
- package/dist/multi-agent/agent-message-queue.js +0 -227
- package/dist/multi-agent/agent-message-queue.js.map +0 -1
- package/dist/multi-agent/background-task-manager.d.ts +0 -248
- package/dist/multi-agent/background-task-manager.d.ts.map +0 -1
- package/dist/multi-agent/background-task-manager.js +0 -415
- package/dist/multi-agent/background-task-manager.js.map +0 -1
- package/dist/multi-agent/category-router.d.ts +0 -56
- package/dist/multi-agent/category-router.d.ts.map +0 -1
- package/dist/multi-agent/category-router.js +0 -99
- package/dist/multi-agent/category-router.js.map +0 -1
- package/dist/multi-agent/council-engine.d.ts +0 -60
- package/dist/multi-agent/council-engine.d.ts.map +0 -1
- package/dist/multi-agent/council-engine.js +0 -284
- package/dist/multi-agent/council-engine.js.map +0 -1
- package/dist/multi-agent/delegation-format-validator.d.ts +0 -22
- package/dist/multi-agent/delegation-format-validator.d.ts.map +0 -1
- package/dist/multi-agent/delegation-format-validator.js +0 -31
- package/dist/multi-agent/delegation-format-validator.js.map +0 -1
- package/dist/multi-agent/delegation-manager.d.ts +0 -128
- package/dist/multi-agent/delegation-manager.d.ts.map +0 -1
- package/dist/multi-agent/delegation-manager.js +0 -276
- package/dist/multi-agent/delegation-manager.js.map +0 -1
- package/dist/multi-agent/i18n-messages.d.ts +0 -35
- package/dist/multi-agent/i18n-messages.d.ts.map +0 -1
- package/dist/multi-agent/i18n-messages.js +0 -54
- package/dist/multi-agent/i18n-messages.js.map +0 -1
- package/dist/multi-agent/index.d.ts +0 -31
- package/dist/multi-agent/index.d.ts.map +0 -1
- package/dist/multi-agent/index.js +0 -46
- package/dist/multi-agent/index.js.map +0 -1
- package/dist/multi-agent/multi-agent-base.d.ts +0 -223
- package/dist/multi-agent/multi-agent-base.d.ts.map +0 -1
- package/dist/multi-agent/multi-agent-base.js +0 -592
- package/dist/multi-agent/multi-agent-base.js.map +0 -1
- package/dist/multi-agent/multi-agent-discord.d.ts +0 -142
- package/dist/multi-agent/multi-agent-discord.d.ts.map +0 -1
- package/dist/multi-agent/multi-agent-discord.js +0 -1235
- package/dist/multi-agent/multi-agent-discord.js.map +0 -1
- package/dist/multi-agent/multi-agent-slack.d.ts +0 -146
- package/dist/multi-agent/multi-agent-slack.d.ts.map +0 -1
- package/dist/multi-agent/multi-agent-slack.js +0 -953
- package/dist/multi-agent/multi-agent-slack.js.map +0 -1
- package/dist/multi-agent/multi-bot-manager.d.ts +0 -119
- package/dist/multi-agent/multi-bot-manager.d.ts.map +0 -1
- package/dist/multi-agent/multi-bot-manager.js +0 -449
- package/dist/multi-agent/multi-bot-manager.js.map +0 -1
- package/dist/multi-agent/orchestrator.d.ts +0 -110
- package/dist/multi-agent/orchestrator.d.ts.map +0 -1
- package/dist/multi-agent/orchestrator.js +0 -436
- package/dist/multi-agent/orchestrator.js.map +0 -1
- package/dist/multi-agent/rate-limiter.d.ts +0 -76
- package/dist/multi-agent/rate-limiter.d.ts.map +0 -1
- package/dist/multi-agent/rate-limiter.js +0 -128
- package/dist/multi-agent/rate-limiter.js.map +0 -1
- package/dist/multi-agent/shared-context.d.ts +0 -127
- package/dist/multi-agent/shared-context.d.ts.map +0 -1
- package/dist/multi-agent/shared-context.js +0 -239
- package/dist/multi-agent/shared-context.js.map +0 -1
- package/dist/multi-agent/slack-config-validator.d.ts +0 -42
- package/dist/multi-agent/slack-config-validator.d.ts.map +0 -1
- package/dist/multi-agent/slack-config-validator.js +0 -194
- package/dist/multi-agent/slack-config-validator.js.map +0 -1
- package/dist/multi-agent/slack-multi-bot-manager.d.ts +0 -143
- package/dist/multi-agent/slack-multi-bot-manager.d.ts.map +0 -1
- package/dist/multi-agent/slack-multi-bot-manager.js +0 -413
- package/dist/multi-agent/slack-multi-bot-manager.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-anti-pattern-detector.d.ts +0 -98
- package/dist/multi-agent/swarm/swarm-anti-pattern-detector.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-anti-pattern-detector.js +0 -225
- package/dist/multi-agent/swarm/swarm-anti-pattern-detector.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-db.d.ts +0 -175
- package/dist/multi-agent/swarm/swarm-db.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-db.js +0 -313
- package/dist/multi-agent/swarm/swarm-db.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-event-reporter.d.ts +0 -116
- package/dist/multi-agent/swarm/swarm-event-reporter.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-event-reporter.js +0 -243
- package/dist/multi-agent/swarm/swarm-event-reporter.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts +0 -57
- package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-mama-adapter.js +0 -87
- package/dist/multi-agent/swarm/swarm-mama-adapter.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-manager.d.ts +0 -122
- package/dist/multi-agent/swarm/swarm-manager.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-manager.js +0 -199
- package/dist/multi-agent/swarm/swarm-manager.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-task-learner.d.ts +0 -104
- package/dist/multi-agent/swarm/swarm-task-learner.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-task-learner.js +0 -211
- package/dist/multi-agent/swarm/swarm-task-learner.js.map +0 -1
- package/dist/multi-agent/swarm/swarm-task-runner.d.ts +0 -155
- package/dist/multi-agent/swarm/swarm-task-runner.d.ts.map +0 -1
- package/dist/multi-agent/swarm/swarm-task-runner.js +0 -615
- package/dist/multi-agent/swarm/swarm-task-runner.js.map +0 -1
- package/dist/multi-agent/swarm/wave-engine.d.ts +0 -96
- package/dist/multi-agent/swarm/wave-engine.d.ts.map +0 -1
- package/dist/multi-agent/swarm/wave-engine.js +0 -123
- package/dist/multi-agent/swarm/wave-engine.js.map +0 -1
- package/dist/multi-agent/system-reminder.d.ts +0 -206
- package/dist/multi-agent/system-reminder.d.ts.map +0 -1
- package/dist/multi-agent/system-reminder.js +0 -455
- package/dist/multi-agent/system-reminder.js.map +0 -1
- package/dist/multi-agent/task-continuation.d.ts +0 -74
- package/dist/multi-agent/task-continuation.d.ts.map +0 -1
- package/dist/multi-agent/task-continuation.js +0 -172
- package/dist/multi-agent/task-continuation.js.map +0 -1
- package/dist/multi-agent/ultrawork-state.d.ts +0 -57
- package/dist/multi-agent/ultrawork-state.d.ts.map +0 -1
- package/dist/multi-agent/ultrawork-state.js +0 -191
- package/dist/multi-agent/ultrawork-state.js.map +0 -1
- package/dist/multi-agent/ultrawork.d.ts +0 -152
- package/dist/multi-agent/ultrawork.d.ts.map +0 -1
- package/dist/multi-agent/ultrawork.js +0 -879
- package/dist/multi-agent/ultrawork.js.map +0 -1
- package/dist/multi-agent/work-tracker.d.ts +0 -22
- package/dist/multi-agent/work-tracker.d.ts.map +0 -1
- package/dist/multi-agent/work-tracker.js +0 -45
- package/dist/multi-agent/work-tracker.js.map +0 -1
- package/dist/multi-agent/workflow-engine.d.ts +0 -87
- package/dist/multi-agent/workflow-engine.d.ts.map +0 -1
- package/dist/multi-agent/workflow-engine.js +0 -604
- package/dist/multi-agent/workflow-engine.js.map +0 -1
- package/dist/onboarding/all-tools.d.ts +0 -18
- package/dist/onboarding/all-tools.d.ts.map +0 -1
- package/dist/onboarding/all-tools.js +0 -149
- package/dist/onboarding/all-tools.js.map +0 -1
- package/dist/onboarding/autonomous-discovery-tools.d.ts +0 -23
- package/dist/onboarding/autonomous-discovery-tools.d.ts.map +0 -1
- package/dist/onboarding/autonomous-discovery-tools.js +0 -268
- package/dist/onboarding/autonomous-discovery-tools.js.map +0 -1
- package/dist/onboarding/onboarding-state.d.ts +0 -70
- package/dist/onboarding/onboarding-state.d.ts.map +0 -1
- package/dist/onboarding/onboarding-state.js +0 -183
- package/dist/onboarding/onboarding-state.js.map +0 -1
- package/dist/onboarding/personality-quiz.d.ts +0 -35
- package/dist/onboarding/personality-quiz.d.ts.map +0 -1
- package/dist/onboarding/personality-quiz.js +0 -219
- package/dist/onboarding/personality-quiz.js.map +0 -1
- package/dist/onboarding/phase-5-summary.d.ts +0 -26
- package/dist/onboarding/phase-5-summary.d.ts.map +0 -1
- package/dist/onboarding/phase-5-summary.js +0 -153
- package/dist/onboarding/phase-5-summary.js.map +0 -1
- package/dist/onboarding/phase-6-security.d.ts +0 -33
- package/dist/onboarding/phase-6-security.d.ts.map +0 -1
- package/dist/onboarding/phase-6-security.js +0 -473
- package/dist/onboarding/phase-6-security.js.map +0 -1
- package/dist/onboarding/phase-7-integrations.d.ts +0 -91
- package/dist/onboarding/phase-7-integrations.d.ts.map +0 -1
- package/dist/onboarding/phase-7-integrations.js +0 -725
- package/dist/onboarding/phase-7-integrations.js.map +0 -1
- package/dist/onboarding/phase-8-demo.d.ts +0 -43
- package/dist/onboarding/phase-8-demo.d.ts.map +0 -1
- package/dist/onboarding/phase-8-demo.js +0 -346
- package/dist/onboarding/phase-8-demo.js.map +0 -1
- package/dist/onboarding/phase-9-finalization.d.ts +0 -27
- package/dist/onboarding/phase-9-finalization.d.ts.map +0 -1
- package/dist/onboarding/phase-9-finalization.js +0 -417
- package/dist/onboarding/phase-9-finalization.js.map +0 -1
- package/dist/onboarding/ritual-prompt.d.ts +0 -2
- package/dist/onboarding/ritual-prompt.d.ts.map +0 -1
- package/dist/onboarding/ritual-prompt.js +0 -285
- package/dist/onboarding/ritual-prompt.js.map +0 -1
- package/dist/onboarding/ritual-tools.d.ts +0 -17
- package/dist/onboarding/ritual-tools.d.ts.map +0 -1
- package/dist/onboarding/ritual-tools.js +0 -93
- package/dist/onboarding/ritual-tools.js.map +0 -1
- package/dist/setup/setup-tools.d.ts +0 -13
- package/dist/setup/setup-tools.d.ts.map +0 -1
- package/dist/setup/setup-tools.js +0 -106
- package/dist/setup/setup-tools.js.map +0 -1
- package/dist/utils/slack-input-validator.d.ts +0 -74
- package/dist/utils/slack-input-validator.d.ts.map +0 -1
- package/dist/utils/slack-input-validator.js +0 -275
- package/dist/utils/slack-input-validator.js.map +0 -1
- package/dist/utils/slack-rate-limiter.d.ts +0 -139
- package/dist/utils/slack-rate-limiter.d.ts.map +0 -1
- package/dist/utils/slack-rate-limiter.js +0 -324
- package/dist/utils/slack-rate-limiter.js.map +0 -1
- package/dist/wiki/wiki-compiler.d.ts +0 -13
- package/dist/wiki/wiki-compiler.d.ts.map +0 -1
- package/dist/wiki/wiki-compiler.js +0 -82
- package/dist/wiki/wiki-compiler.js.map +0 -1
|
@@ -1,953 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Multi-Agent Slack Integration
|
|
4
|
-
*
|
|
5
|
-
* Extends the Slack gateway with multi-agent support.
|
|
6
|
-
* Mirrors MultiAgentDiscordHandler but uses Slack-specific APIs.
|
|
7
|
-
*
|
|
8
|
-
* Reused platform-agnostic components:
|
|
9
|
-
* - MultiAgentOrchestrator: agent selection, chain tracking
|
|
10
|
-
* - AgentProcessManager: getProcess('slack', channelId, agentId)
|
|
11
|
-
* - SharedContextManager: channelId-based context
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.MultiAgentSlackHandler = void 0;
|
|
15
|
-
const slack_multi_bot_manager_js_1 = require("./slack-multi-bot-manager.js");
|
|
16
|
-
const message_splitter_js_1 = require("../gateways/message-splitter.js");
|
|
17
|
-
const log_sanitizer_js_1 = require("../utils/log-sanitizer.js");
|
|
18
|
-
const channel_history_js_1 = require("../gateways/channel-history.js");
|
|
19
|
-
const multi_agent_base_js_1 = require("./multi-agent-base.js");
|
|
20
|
-
const prompt_enhancer_js_1 = require("../agent/prompt-enhancer.js");
|
|
21
|
-
const tool_status_tracker_js_1 = require("../gateways/tool-status-tracker.js");
|
|
22
|
-
const config_manager_js_1 = require("../cli/config/config-manager.js");
|
|
23
|
-
/** Heartbeat interval for status polling (60 seconds) */
|
|
24
|
-
const HEARTBEAT_INTERVAL_MS = () => (0, config_manager_js_1.getConfig)().gateway_tuning?.heartbeat_interval_ms ?? 60_000;
|
|
25
|
-
/** Status emoji for each process state */
|
|
26
|
-
const STATE_EMOJI = {
|
|
27
|
-
busy: '🔄',
|
|
28
|
-
idle: '💤',
|
|
29
|
-
starting: '⏳',
|
|
30
|
-
dead: '💀',
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Multi-Agent Slack Handler
|
|
34
|
-
*
|
|
35
|
-
* Integrates with the Slack gateway to provide multi-agent support.
|
|
36
|
-
*/
|
|
37
|
-
class MultiAgentSlackHandler extends multi_agent_base_js_1.MultiAgentHandlerBase {
|
|
38
|
-
multiBotManager;
|
|
39
|
-
logger = (0, log_sanitizer_js_1.createSafeLogger)('MultiAgentSlack');
|
|
40
|
-
/** Main Slack WebClient for posting system messages (heartbeat) */
|
|
41
|
-
mainWebClient = null;
|
|
42
|
-
/** Per-channel WebClient mapping (for multi-workspace support) */
|
|
43
|
-
channelWebClients = new Map();
|
|
44
|
-
/** Active channel for heartbeat reporting */
|
|
45
|
-
heartbeatChannelId = null;
|
|
46
|
-
/** Heartbeat polling interval handle */
|
|
47
|
-
heartbeatInterval;
|
|
48
|
-
/** Interval handle for periodic cleanup */
|
|
49
|
-
/** Tracks the process used for history seeding per agent:channel */
|
|
50
|
-
historySeedProcess = new Map();
|
|
51
|
-
promptEnhancer;
|
|
52
|
-
constructor(config, processOptions = {}, runtimeOptions = {}) {
|
|
53
|
-
super(config, processOptions, runtimeOptions);
|
|
54
|
-
this.multiBotManager = new slack_multi_bot_manager_js_1.SlackMultiBotManager(config);
|
|
55
|
-
this.promptEnhancer = new prompt_enhancer_js_1.PromptEnhancer();
|
|
56
|
-
// Setup idle event listeners for all agents (F7: message queue drain)
|
|
57
|
-
this.setupIdleListeners();
|
|
58
|
-
}
|
|
59
|
-
getPlatformName() {
|
|
60
|
-
return 'slack';
|
|
61
|
-
}
|
|
62
|
-
formatBold(text) {
|
|
63
|
-
return `*${text}*`;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the correct WebClient for a channel (multi-workspace aware).
|
|
67
|
-
* Returns channel-specific client if registered, otherwise mainWebClient.
|
|
68
|
-
*/
|
|
69
|
-
getWebClientForChannel(channelId) {
|
|
70
|
-
return this.channelWebClients.get(channelId) ?? this.mainWebClient;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Register a WebClient for a specific channel (call when receiving messages from agent bots)
|
|
74
|
-
*/
|
|
75
|
-
registerChannelWebClient(channelId, client) {
|
|
76
|
-
this.channelWebClients.set(channelId, client);
|
|
77
|
-
}
|
|
78
|
-
async sendChannelNotification(channelId, message) {
|
|
79
|
-
try {
|
|
80
|
-
const client = this.getWebClientForChannel(channelId);
|
|
81
|
-
if (client) {
|
|
82
|
-
await client.chat.postMessage({ channel: channelId, text: message });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
console.error(`[MultiAgentSlack] Failed to send channel notification:`, err);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Extract agent IDs from <@U...> mentions in message content
|
|
91
|
-
*/
|
|
92
|
-
extractMentionedAgentIds(content) {
|
|
93
|
-
const mentionPattern = /<@([UW]\w+)>/g;
|
|
94
|
-
const agentIds = [];
|
|
95
|
-
let match;
|
|
96
|
-
while ((match = mentionPattern.exec(content)) !== null) {
|
|
97
|
-
const userId = match[1];
|
|
98
|
-
const agentId = this.multiBotManager.resolveAgentIdFromUserId(userId);
|
|
99
|
-
if (agentId) {
|
|
100
|
-
// Resolve 'main' to the actual agent ID (e.g., 'conductor')
|
|
101
|
-
const resolvedId = agentId === 'main' ? (this.multiBotManager.getMainBotAgentId() ?? agentId) : agentId;
|
|
102
|
-
agentIds.push(resolvedId);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return agentIds;
|
|
106
|
-
}
|
|
107
|
-
async platformCleanup() {
|
|
108
|
-
this.stopHeartbeat();
|
|
109
|
-
this.historySeedProcess.clear();
|
|
110
|
-
this.channelWebClients.clear();
|
|
111
|
-
await this.multiBotManager.stopAll();
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Initialize multi-bot support (call after Slack connects)
|
|
115
|
-
*/
|
|
116
|
-
async initializeMultiBots() {
|
|
117
|
-
if (this.multiBotInitialized)
|
|
118
|
-
return;
|
|
119
|
-
// Register mention callback so agent bots forward mentions to handler
|
|
120
|
-
this.multiBotManager.onMention(async (agentId, event, webClient) => {
|
|
121
|
-
// Register this channel's WebClient for correct workspace routing
|
|
122
|
-
this.channelWebClients.set(event.channel, webClient);
|
|
123
|
-
const cleanContent = event.text.replace(/<@[UW]\w+>/g, '').trim();
|
|
124
|
-
if (!cleanContent)
|
|
125
|
-
return;
|
|
126
|
-
// Determine if sender is an agent bot
|
|
127
|
-
const isFromAgent = !!event.bot_id;
|
|
128
|
-
const senderAgentId = isFromAgent
|
|
129
|
-
? (this.multiBotManager.isFromAgentBot(event.bot_id) ?? undefined)
|
|
130
|
-
: undefined;
|
|
131
|
-
// Chain depth check for mention_delegation
|
|
132
|
-
if (isFromAgent && senderAgentId && senderAgentId !== 'main') {
|
|
133
|
-
const chainState = this.orchestrator.getChainState(event.channel);
|
|
134
|
-
const maxDepth = this.config.max_mention_depth ?? 3;
|
|
135
|
-
if (chainState.blocked) {
|
|
136
|
-
this.logger.log(`[MultiAgentSlack] Mention chain blocked in channel ${event.channel}, ignoring`);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (chainState.length >= maxDepth) {
|
|
140
|
-
this.logger.log(`[MultiAgentSlack] Mention chain depth ${chainState.length} >= max ${maxDepth}, ignoring`);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
this.logger.log(`[MultiAgentSlack] Mention-triggered: agent=${agentId}, from=${senderAgentId ?? event.user}, content="${cleanContent.substring(0, 50)}"`);
|
|
145
|
-
// Extract mentioned agent IDs from the original content
|
|
146
|
-
const mentionedAgentIds = this.extractMentionedAgentIds(event.text);
|
|
147
|
-
// Force this specific agent to respond
|
|
148
|
-
const mentionDescription = cleanContent.substring(0, 200);
|
|
149
|
-
try {
|
|
150
|
-
this.systemReminder.notify({
|
|
151
|
-
type: 'delegation-started',
|
|
152
|
-
taskId: '',
|
|
153
|
-
description: mentionDescription,
|
|
154
|
-
agentId,
|
|
155
|
-
requestedBy: senderAgentId ?? event.user,
|
|
156
|
-
channelId: event.channel,
|
|
157
|
-
source: 'slack',
|
|
158
|
-
timestamp: Date.now(),
|
|
159
|
-
});
|
|
160
|
-
const response = await this.processAgentResponse(agentId, {
|
|
161
|
-
channelId: event.channel,
|
|
162
|
-
userId: event.user,
|
|
163
|
-
content: cleanContent,
|
|
164
|
-
isBot: isFromAgent,
|
|
165
|
-
senderAgentId: senderAgentId && senderAgentId !== 'main' ? senderAgentId : undefined,
|
|
166
|
-
mentionedAgentIds,
|
|
167
|
-
messageId: event.ts,
|
|
168
|
-
timestamp: parseFloat(event.ts) * 1000,
|
|
169
|
-
}, cleanContent);
|
|
170
|
-
if (response) {
|
|
171
|
-
this.systemReminder.notify({
|
|
172
|
-
type: 'delegation-completed',
|
|
173
|
-
taskId: '',
|
|
174
|
-
description: mentionDescription,
|
|
175
|
-
agentId,
|
|
176
|
-
requestedBy: senderAgentId ?? event.user,
|
|
177
|
-
channelId: event.channel,
|
|
178
|
-
source: 'slack',
|
|
179
|
-
duration: response.duration,
|
|
180
|
-
timestamp: Date.now(),
|
|
181
|
-
});
|
|
182
|
-
const threadTs = event.thread_ts || event.ts;
|
|
183
|
-
await this.sendAgentResponses(event.channel, threadTs, [response]);
|
|
184
|
-
this.orchestrator.recordAgentResponse(agentId, event.channel, response.messageId);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
catch (err) {
|
|
188
|
-
this.logger.error(`[MultiAgentSlack] Mention handler error:`, err);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
await this.multiBotManager.initialize();
|
|
192
|
-
this.multiBotInitialized = true;
|
|
193
|
-
const connectedAgents = this.multiBotManager.getConnectedAgents();
|
|
194
|
-
if (connectedAgents.length > 0) {
|
|
195
|
-
this.logger.log(`[MultiAgentSlack] Multi-bot mode active for: ${connectedAgents.join(', ')}`);
|
|
196
|
-
}
|
|
197
|
-
// Pass bot ID map to process manager for mention-based delegation prompts
|
|
198
|
-
if (this.config.mention_delegation) {
|
|
199
|
-
const botUserIdMap = this.multiBotManager.getBotUserIdMap();
|
|
200
|
-
this.processManager.setBotUserIdMap(botUserIdMap);
|
|
201
|
-
this.processManager.setMentionDelegation(true);
|
|
202
|
-
this.logger.log(`[MultiAgentSlack] Mention delegation enabled with ${botUserIdMap.size} bot IDs`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Set main Slack WebClient (for heartbeat status messages)
|
|
207
|
-
*/
|
|
208
|
-
setMainWebClient(client) {
|
|
209
|
-
this.mainWebClient = client;
|
|
210
|
-
this.systemReminder.registerCallback(async (channelId, message) => {
|
|
211
|
-
const webClient = this.getWebClientForChannel(channelId) ?? client;
|
|
212
|
-
const chunks = (0, message_splitter_js_1.splitForSlack)(message);
|
|
213
|
-
for (const chunk of chunks) {
|
|
214
|
-
await webClient.chat.postMessage({ channel: channelId, text: chunk });
|
|
215
|
-
}
|
|
216
|
-
}, 'slack');
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Set main bot's user ID (call when Slack connects via auth.test)
|
|
220
|
-
*/
|
|
221
|
-
setBotUserId(userId) {
|
|
222
|
-
this.multiBotManager.setMainBotUserId(userId);
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Set main bot's bot ID
|
|
226
|
-
*/
|
|
227
|
-
setMainBotId(botId) {
|
|
228
|
-
this.multiBotManager.setMainBotId(botId);
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Set main bot token (to avoid duplicate connections)
|
|
232
|
-
*/
|
|
233
|
-
setMainBotToken(token) {
|
|
234
|
-
this.multiBotManager.setMainBotToken(token);
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Update configuration (for hot reload)
|
|
238
|
-
*/
|
|
239
|
-
updateConfig(config) {
|
|
240
|
-
this.config = config;
|
|
241
|
-
this.orchestrator.updateConfig(config);
|
|
242
|
-
this.processManager.updateConfig(config);
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Handle a Slack message with multi-agent logic
|
|
246
|
-
*
|
|
247
|
-
* @returns Object with selected agents and their responses, or null if no agents respond
|
|
248
|
-
*/
|
|
249
|
-
async handleMessage(event, cleanContent) {
|
|
250
|
-
// Build message context (extract mentioned agents from original text)
|
|
251
|
-
const context = this.buildMessageContext(event, cleanContent);
|
|
252
|
-
context.mentionedAgentIds = this.extractMentionedAgentIds(event.text);
|
|
253
|
-
// Record human message to shared context
|
|
254
|
-
if (!context.isBot) {
|
|
255
|
-
this.sharedContext.recordHumanMessage(context.channelId, event.user, cleanContent, event.ts);
|
|
256
|
-
}
|
|
257
|
-
// Select responding agents
|
|
258
|
-
const selection = this.orchestrator.selectRespondingAgents(context);
|
|
259
|
-
this.logger.log(`[MultiAgentSlack] Selection result: agents=${selection.selectedAgents.join(',')}, reason=${selection.reason}, blocked=${selection.blocked}`);
|
|
260
|
-
if (selection.blocked) {
|
|
261
|
-
this.logger.log(`[MultiAgentSlack] Blocked: ${selection.blockReason}`);
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
if (selection.selectedAgents.length === 0) {
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
// Process all selected agents in parallel
|
|
268
|
-
const results = await Promise.allSettled(selection.selectedAgents.map((agentId) => this.processAgentResponse(agentId, context, cleanContent)));
|
|
269
|
-
const responses = [];
|
|
270
|
-
for (let i = 0; i < results.length; i++) {
|
|
271
|
-
const result = results[i];
|
|
272
|
-
const agentId = selection.selectedAgents[i];
|
|
273
|
-
if (result.status === 'fulfilled' && result.value) {
|
|
274
|
-
const response = result.value;
|
|
275
|
-
responses.push(response);
|
|
276
|
-
// Record agent response to orchestrator and shared context
|
|
277
|
-
this.orchestrator.recordAgentResponse(agentId, context.channelId, response.messageId);
|
|
278
|
-
const agent = this.orchestrator.getAgent(agentId);
|
|
279
|
-
if (agent) {
|
|
280
|
-
this.sharedContext.recordAgentMessage(context.channelId, agent, response.content, response.messageId);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
else if (result.status === 'rejected') {
|
|
284
|
-
this.logger.error(`[MultiAgentSlack] Error processing agent ${agentId}:`, result.reason);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
if (responses.length === 0) {
|
|
288
|
-
return null;
|
|
289
|
-
}
|
|
290
|
-
return {
|
|
291
|
-
selectedAgents: selection.selectedAgents,
|
|
292
|
-
reason: selection.reason,
|
|
293
|
-
responses,
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Process a single agent's response
|
|
298
|
-
*/
|
|
299
|
-
async processAgentResponse(agentId, context, userMessage) {
|
|
300
|
-
const agent = this.orchestrator.getAgent(agentId);
|
|
301
|
-
if (!agent) {
|
|
302
|
-
this.logger.error(`[MultiAgentSlack] Unknown agent: ${agentId}`);
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
// Strip trigger prefix from message if present
|
|
306
|
-
const cleanMessage = this.orchestrator.stripTriggerPrefix(userMessage, agentId);
|
|
307
|
-
// Build context for this agent
|
|
308
|
-
const agentContext = this.sharedContext.buildContextForAgent(context.channelId, agentId, 5);
|
|
309
|
-
// Enhance with skill detection + keyword instructions
|
|
310
|
-
const workspacePath = globalThis.process?.env?.MAMA_WORKSPACE || globalThis.process?.env?.HOME || '/tmp';
|
|
311
|
-
const ruleContext = {
|
|
312
|
-
agentId,
|
|
313
|
-
tier: agent.tier,
|
|
314
|
-
channelId: context.channelId,
|
|
315
|
-
};
|
|
316
|
-
const enhanced = await this.promptEnhancer.enhance(cleanMessage, workspacePath, ruleContext);
|
|
317
|
-
// Build full prompt with context.
|
|
318
|
-
let fullPrompt = cleanMessage;
|
|
319
|
-
// Inject matched skill content into user message
|
|
320
|
-
if (enhanced.skillContent) {
|
|
321
|
-
const safeSkillContent = enhanced.skillContent.replace(/<\/system-reminder>/gi, '</system\\u2011reminder>');
|
|
322
|
-
fullPrompt = `<system-reminder>\n${safeSkillContent}\n</system-reminder>\n\n${fullPrompt}`;
|
|
323
|
-
this.logger.log(`[SkillMatch] Injecting skill into Slack agent ${agentId}: ${enhanced.skillContent.length} chars`);
|
|
324
|
-
}
|
|
325
|
-
if (enhanced.keywordInstructions) {
|
|
326
|
-
fullPrompt = `${enhanced.keywordInstructions}\n\n${fullPrompt}`;
|
|
327
|
-
this.logger.log(`[PromptEnhancer] Keyword detected for Slack agent ${agentId}: ${enhanced.keywordInstructions.length} chars`);
|
|
328
|
-
}
|
|
329
|
-
if (enhanced.rulesContent) {
|
|
330
|
-
fullPrompt = `## Project Rules\n${enhanced.rulesContent}\n\n${fullPrompt}`;
|
|
331
|
-
}
|
|
332
|
-
// Track work start (completed in finally block)
|
|
333
|
-
this.workTracker.startWork(agentId, context.channelId, cleanMessage);
|
|
334
|
-
let process = null;
|
|
335
|
-
try {
|
|
336
|
-
// Get or create process for this agent in this channel
|
|
337
|
-
process = await this.processManager.getProcess('slack', context.channelId, agentId);
|
|
338
|
-
// Inject channel history when process is new/replaced for this agent:channel.
|
|
339
|
-
// After process restart the CLI has no prior memory, so history must be re-seeded.
|
|
340
|
-
const sessionKey = `${agentId}:${context.channelId}`;
|
|
341
|
-
const needsHistorySeed = this.historySeedProcess.get(sessionKey) !== process;
|
|
342
|
-
if (needsHistorySeed) {
|
|
343
|
-
const channelHistory = (0, channel_history_js_1.getChannelHistory)();
|
|
344
|
-
const displayName = agent.display_name || agentId;
|
|
345
|
-
const historyContext = channelHistory.formatForContext(context.channelId, context.messageId, displayName);
|
|
346
|
-
if (historyContext) {
|
|
347
|
-
fullPrompt = `${historyContext}\n\n${fullPrompt}`;
|
|
348
|
-
}
|
|
349
|
-
this.historySeedProcess.set(sessionKey, process);
|
|
350
|
-
}
|
|
351
|
-
if (agentContext) {
|
|
352
|
-
fullPrompt = `${agentContext}\n\n${fullPrompt}`;
|
|
353
|
-
}
|
|
354
|
-
// Inject agent availability status and active work (Phase 2 + 3)
|
|
355
|
-
const agentStatus = this.buildAgentStatusSection(agentId);
|
|
356
|
-
const workSection = this.workTracker.buildWorkSection(agentId);
|
|
357
|
-
const channelInfo = `## Current Channel\nPlatform: Slack\nchannel_id: ${context.channelId}\nUse **slack_send** to send messages/files to this channel.`;
|
|
358
|
-
const dynamicContext = [agentStatus, workSection, channelInfo].filter(Boolean).join('\n');
|
|
359
|
-
if (dynamicContext) {
|
|
360
|
-
fullPrompt = `${dynamicContext}\n\n${fullPrompt}`;
|
|
361
|
-
}
|
|
362
|
-
this.logger.log(`[MultiAgentSlack] Processing agent ${agentId}, prompt length: ${fullPrompt.length}`);
|
|
363
|
-
// Create tool status tracker for real-time progress
|
|
364
|
-
let tracker = null;
|
|
365
|
-
const channelClient = this.getWebClientForChannel(context.channelId);
|
|
366
|
-
if (channelClient) {
|
|
367
|
-
const webClient = channelClient;
|
|
368
|
-
const channelId = context.channelId;
|
|
369
|
-
const slackAdapter = {
|
|
370
|
-
postPlaceholder: async (content) => {
|
|
371
|
-
const res = await webClient.chat.postMessage({
|
|
372
|
-
channel: channelId,
|
|
373
|
-
text: content,
|
|
374
|
-
});
|
|
375
|
-
return res.ts ?? null;
|
|
376
|
-
},
|
|
377
|
-
editPlaceholder: async (handle, content) => {
|
|
378
|
-
await webClient.chat.update({ channel: channelId, ts: handle, text: content });
|
|
379
|
-
},
|
|
380
|
-
deletePlaceholder: async (handle) => {
|
|
381
|
-
await webClient.chat.delete({ channel: channelId, ts: handle });
|
|
382
|
-
},
|
|
383
|
-
};
|
|
384
|
-
tracker = new tool_status_tracker_js_1.ToolStatusTracker(slackAdapter, {
|
|
385
|
-
throttleMs: 1500,
|
|
386
|
-
initialDelayMs: 3000,
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
// Send message and get response (with timeout, properly cleaned up)
|
|
390
|
-
// agent_ms=0 means unlimited (no timeout race)
|
|
391
|
-
let timeoutHandle;
|
|
392
|
-
let result;
|
|
393
|
-
try {
|
|
394
|
-
const agentTimeout = (0, multi_agent_base_js_1.AGENT_TIMEOUT_MS)();
|
|
395
|
-
const sendPromise = process.sendMessage(fullPrompt, tracker?.toPromptCallbacks());
|
|
396
|
-
if (agentTimeout > 0) {
|
|
397
|
-
result = await Promise.race([
|
|
398
|
-
sendPromise,
|
|
399
|
-
new Promise((_, reject) => {
|
|
400
|
-
timeoutHandle = setTimeout(() => reject(new Error(`Agent ${agentId} timed out after ${agentTimeout / 1000}s`)), agentTimeout);
|
|
401
|
-
}),
|
|
402
|
-
]);
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
result = await sendPromise;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
finally {
|
|
409
|
-
if (timeoutHandle)
|
|
410
|
-
clearTimeout(timeoutHandle);
|
|
411
|
-
await tracker?.cleanup();
|
|
412
|
-
}
|
|
413
|
-
// Check for workflow plan BEFORE executing tool calls (priority)
|
|
414
|
-
const wfClient = this.getWebClientForChannel(context.channelId);
|
|
415
|
-
const workflowResult = await this.tryExecuteWorkflow(result.response, context.channelId, 'slack', (event) => {
|
|
416
|
-
if (!wfClient) {
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
let msg = '';
|
|
420
|
-
const modelTag = event.agentModel ? ` [${event.agentModel}]` : '';
|
|
421
|
-
const progress = event.totalSteps && event.completedSteps !== undefined
|
|
422
|
-
? ` [${event.completedSteps}/${event.totalSteps}]`
|
|
423
|
-
: '';
|
|
424
|
-
if (event.type === 'step-started') {
|
|
425
|
-
msg = ` ${event.agentDisplayName}${modelTag}${progress} starting...`;
|
|
426
|
-
}
|
|
427
|
-
else if (event.type === 'step-completed') {
|
|
428
|
-
const sec = event.duration_ms ? Math.round(event.duration_ms / 1000) : 0;
|
|
429
|
-
const pct = event.totalSteps && event.completedSteps !== undefined
|
|
430
|
-
? ` (${Math.round((event.completedSteps / event.totalSteps) * 100)}%)`
|
|
431
|
-
: '';
|
|
432
|
-
msg = `${event.agentDisplayName}${modelTag} (${sec}s)${pct} completed`;
|
|
433
|
-
}
|
|
434
|
-
else if (event.type === 'step-failed') {
|
|
435
|
-
msg = `${event.agentDisplayName}${modelTag}${progress} ❌ failed: ${event.error?.substring(0, 100)}`;
|
|
436
|
-
}
|
|
437
|
-
if (msg) {
|
|
438
|
-
wfClient.chat.postMessage({ channel: context.channelId, text: msg }).catch(() => { });
|
|
439
|
-
}
|
|
440
|
-
}, wfClient
|
|
441
|
-
? (_stepAgentId) => {
|
|
442
|
-
const chId = context.channelId;
|
|
443
|
-
const adapter = {
|
|
444
|
-
postPlaceholder: async (content) => {
|
|
445
|
-
const res = await wfClient.chat.postMessage({ channel: chId, text: content });
|
|
446
|
-
return res.ts ?? null;
|
|
447
|
-
},
|
|
448
|
-
editPlaceholder: async (handle, content) => {
|
|
449
|
-
await wfClient.chat.update({ channel: chId, ts: handle, text: content });
|
|
450
|
-
},
|
|
451
|
-
deletePlaceholder: async (handle) => {
|
|
452
|
-
await wfClient.chat.delete({ channel: chId, ts: handle });
|
|
453
|
-
},
|
|
454
|
-
};
|
|
455
|
-
const stepTracker = new tool_status_tracker_js_1.ToolStatusTracker(adapter, {
|
|
456
|
-
throttleMs: 1500,
|
|
457
|
-
initialDelayMs: 2000,
|
|
458
|
-
});
|
|
459
|
-
return {
|
|
460
|
-
callbacks: stepTracker.toPromptCallbacks(),
|
|
461
|
-
cleanup: () => stepTracker.cleanup(),
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
: undefined);
|
|
465
|
-
if (workflowResult) {
|
|
466
|
-
if (workflowResult.failed) {
|
|
467
|
-
this.logger.warn(`[MultiAgentSlack] Workflow failed: ${workflowResult.failed}, sending feedback to conductor`);
|
|
468
|
-
const feedback = `[SYSTEM] Your workflow_plan failed to execute.\nReason: ${workflowResult.failed}\nPlease adjust and retry, or respond without a workflow_plan.`;
|
|
469
|
-
const retryResult = await process.sendMessage(feedback);
|
|
470
|
-
const cleanedRetry = await this.executeTextToolCalls(retryResult.response);
|
|
471
|
-
const formattedResponse = this.formatAgentResponse(agent, cleanedRetry);
|
|
472
|
-
return {
|
|
473
|
-
agentId,
|
|
474
|
-
agent,
|
|
475
|
-
content: formattedResponse,
|
|
476
|
-
rawContent: cleanedRetry,
|
|
477
|
-
duration: result.duration_ms,
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
const display = workflowResult.directMessage
|
|
481
|
-
? `${workflowResult.directMessage}\n\n${workflowResult.result}`
|
|
482
|
-
: workflowResult.result;
|
|
483
|
-
const formattedResponse = this.formatAgentResponse(agent, display);
|
|
484
|
-
return {
|
|
485
|
-
agentId,
|
|
486
|
-
agent,
|
|
487
|
-
content: formattedResponse,
|
|
488
|
-
rawContent: display,
|
|
489
|
-
duration: result.duration_ms,
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
// Check for council plan (after workflow, before tool calls)
|
|
493
|
-
const councilClient = this.getWebClientForChannel(context.channelId);
|
|
494
|
-
const councilResult = await this.tryExecuteCouncil(result.response, context.channelId, 'slack', async (event) => {
|
|
495
|
-
if (!councilClient) {
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
let msg = '';
|
|
499
|
-
if (event.type === 'council-round-started') {
|
|
500
|
-
msg = `🗣️ ${event.agentDisplayName} Round ${event.round} starting...`;
|
|
501
|
-
}
|
|
502
|
-
else if (event.type === 'council-round-completed') {
|
|
503
|
-
const sec = event.duration_ms ? Math.round(event.duration_ms / 1000) : 0;
|
|
504
|
-
msg = `🗣️ ${event.agentDisplayName} Round ${event.round} (${sec}s) completed`;
|
|
505
|
-
}
|
|
506
|
-
else if (event.type === 'council-round-failed') {
|
|
507
|
-
msg = `🗣️ ${event.agentDisplayName} Round ${event.round} ❌ failed: ${event.error?.substring(0, 100)}`;
|
|
508
|
-
}
|
|
509
|
-
if (msg) {
|
|
510
|
-
try {
|
|
511
|
-
await councilClient.chat.postMessage({ channel: context.channelId, text: msg });
|
|
512
|
-
}
|
|
513
|
-
catch (err) {
|
|
514
|
-
this.logger?.warn('[MultiAgentSlack] Failed to post council progress:', err);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
if (councilResult) {
|
|
519
|
-
const display = councilResult.directMessage
|
|
520
|
-
? `${councilResult.directMessage}\n\n${councilResult.result}`
|
|
521
|
-
: councilResult.result;
|
|
522
|
-
const formattedResponse = this.formatAgentResponse(agent, display);
|
|
523
|
-
return {
|
|
524
|
-
agentId,
|
|
525
|
-
agent,
|
|
526
|
-
content: formattedResponse,
|
|
527
|
-
rawContent: display,
|
|
528
|
-
duration: result.duration_ms,
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
// Strip any workflow/council plan JSON that wasn't executed
|
|
532
|
-
// (prevents raw JSON from leaking to Slack when plan execution is skipped)
|
|
533
|
-
let responseForProcessing = result.response;
|
|
534
|
-
if (this.workflowEngine?.isEnabled()) {
|
|
535
|
-
responseForProcessing = this.workflowEngine.extractNonPlanContent(responseForProcessing);
|
|
536
|
-
}
|
|
537
|
-
if (this.councilEngine) {
|
|
538
|
-
responseForProcessing = this.councilEngine.extractNonPlanContent(responseForProcessing);
|
|
539
|
-
}
|
|
540
|
-
// Execute text-based gateway tool calls (```tool_call blocks in response)
|
|
541
|
-
const cleanedResponse = await this.executeTextToolCalls(responseForProcessing);
|
|
542
|
-
// Format response with agent prefix
|
|
543
|
-
const formattedResponse = this.formatAgentResponse(agent, cleanedResponse);
|
|
544
|
-
return {
|
|
545
|
-
agentId,
|
|
546
|
-
agent,
|
|
547
|
-
content: formattedResponse,
|
|
548
|
-
rawContent: cleanedResponse,
|
|
549
|
-
duration: result.duration_ms,
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
catch (error) {
|
|
553
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
554
|
-
this.logger.error(`[MultiAgentSlack] Failed to get response from ${agentId}:`, error);
|
|
555
|
-
// Enqueue busy responses (F7: message queue)
|
|
556
|
-
if (errMsg.includes('busy')) {
|
|
557
|
-
this.logger.log(`[MultiAgentSlack] Agent ${agentId} busy, enqueuing message`);
|
|
558
|
-
const queuedMessage = {
|
|
559
|
-
prompt: fullPrompt,
|
|
560
|
-
channelId: context.channelId,
|
|
561
|
-
threadTs: context.messageId,
|
|
562
|
-
source: 'slack',
|
|
563
|
-
enqueuedAt: Date.now(),
|
|
564
|
-
context,
|
|
565
|
-
};
|
|
566
|
-
this.messageQueue.enqueue(agentId, queuedMessage);
|
|
567
|
-
const queueSize = this.messageQueue.getQueueSize(agentId);
|
|
568
|
-
const queueText = queueSize > 0
|
|
569
|
-
? `⚠️ ${agent.display_name} is currently busy. ${queueSize} messages queued.`
|
|
570
|
-
: `⚠️ ${agent.display_name} is currently busy. Your request has been queued.`;
|
|
571
|
-
// Trigger immediate drain if process is idle or reaped
|
|
572
|
-
this.tryDrainNow(agentId, 'slack', context.channelId).catch(() => { });
|
|
573
|
-
return {
|
|
574
|
-
agentId,
|
|
575
|
-
agent,
|
|
576
|
-
content: this.formatAgentResponse(agent, queueText),
|
|
577
|
-
rawContent: queueText,
|
|
578
|
-
duration: 0,
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
const fallbackMessage = errMsg.toLowerCase().includes('timed out') || errMsg.toLowerCase().includes('timeout')
|
|
582
|
-
? `⚠️ ${agent.display_name} response timed out. Please try again later.`
|
|
583
|
-
: `⚠️ ${agent.display_name} error occurred while processing: ${errMsg}`;
|
|
584
|
-
const fallbackRaw = errMsg.toLowerCase().includes('timed out') || errMsg.toLowerCase().includes('timeout')
|
|
585
|
-
? 'Response timed out'
|
|
586
|
-
: `Error: ${errMsg}`;
|
|
587
|
-
return {
|
|
588
|
-
agentId,
|
|
589
|
-
agent,
|
|
590
|
-
content: this.formatAgentResponse(agent, fallbackMessage),
|
|
591
|
-
rawContent: fallbackRaw,
|
|
592
|
-
duration: 0,
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
finally {
|
|
596
|
-
this.workTracker.completeWork(agentId, context.channelId);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Build message context from Slack event
|
|
601
|
-
*/
|
|
602
|
-
buildMessageContext(event, cleanContent) {
|
|
603
|
-
const isBot = !!event.bot_id;
|
|
604
|
-
let senderAgentId;
|
|
605
|
-
if (isBot && event.bot_id) {
|
|
606
|
-
const agentBotId = this.multiBotManager.isFromAgentBot(event.bot_id);
|
|
607
|
-
if (agentBotId && agentBotId !== 'main') {
|
|
608
|
-
senderAgentId = agentBotId;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
return {
|
|
612
|
-
channelId: event.channel,
|
|
613
|
-
userId: event.user,
|
|
614
|
-
content: cleanContent,
|
|
615
|
-
isBot,
|
|
616
|
-
senderAgentId,
|
|
617
|
-
messageId: event.ts,
|
|
618
|
-
timestamp: parseFloat(event.ts) * 1000,
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* Send formatted responses to Slack (handles message splitting)
|
|
623
|
-
* Uses agent's dedicated bot if available, otherwise main WebClient
|
|
624
|
-
*/
|
|
625
|
-
async sendAgentResponses(channelId, threadTs, responses, mainWebClient) {
|
|
626
|
-
const sentMessageTs = [];
|
|
627
|
-
for (const response of responses) {
|
|
628
|
-
try {
|
|
629
|
-
const chunks = (0, message_splitter_js_1.splitForSlack)(response.content);
|
|
630
|
-
const hasOwnBot = this.multiBotManager.hasAgentBot(response.agentId);
|
|
631
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
632
|
-
let messageTs = null;
|
|
633
|
-
if (hasOwnBot && threadTs) {
|
|
634
|
-
// Use agent's dedicated bot (requires threadTs for reply)
|
|
635
|
-
messageTs = await this.multiBotManager.replyAsAgent(response.agentId, channelId, threadTs, chunks[i]);
|
|
636
|
-
}
|
|
637
|
-
else if (hasOwnBot && !threadTs) {
|
|
638
|
-
// Use agent's dedicated bot for top-level message
|
|
639
|
-
messageTs = await this.multiBotManager.sendAsAgent(response.agentId, channelId, chunks[i]);
|
|
640
|
-
}
|
|
641
|
-
else if (mainWebClient) {
|
|
642
|
-
// Use main bot -- broadcast first chunk to channel
|
|
643
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
644
|
-
const msgParams = {
|
|
645
|
-
channel: channelId,
|
|
646
|
-
text: chunks[i],
|
|
647
|
-
...(threadTs && { thread_ts: threadTs }),
|
|
648
|
-
};
|
|
649
|
-
if (i === 0) {
|
|
650
|
-
msgParams.reply_broadcast = true;
|
|
651
|
-
}
|
|
652
|
-
const result = await mainWebClient.chat.postMessage(msgParams);
|
|
653
|
-
messageTs = result.ts;
|
|
654
|
-
}
|
|
655
|
-
if (messageTs) {
|
|
656
|
-
sentMessageTs.push(messageTs);
|
|
657
|
-
if (i === 0) {
|
|
658
|
-
response.messageId = messageTs;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
catch (err) {
|
|
664
|
-
this.logger.error(`[MultiAgentSlack] Failed to send response for agent ${response.agentId}:`, err);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
return sentMessageTs;
|
|
668
|
-
}
|
|
669
|
-
/**
|
|
670
|
-
* Send queued response to Slack (F7: message queue drain callback)
|
|
671
|
-
*/
|
|
672
|
-
async sendQueuedResponse(agentId, message, response) {
|
|
673
|
-
const agent = this.orchestrator.getAgent(agentId);
|
|
674
|
-
if (!agent) {
|
|
675
|
-
this.logger.error(`[MultiAgentSlack] Unknown agent in queue: ${agentId}`);
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
let displayResponse = response;
|
|
679
|
-
// Try executing workflow if this is a conductor response with a workflow_plan
|
|
680
|
-
const queueClient = this.getWebClientForChannel(message.channelId);
|
|
681
|
-
const createStepCbs = queueClient
|
|
682
|
-
? (_stepAgentId) => {
|
|
683
|
-
const chId = message.channelId;
|
|
684
|
-
const adapter = {
|
|
685
|
-
postPlaceholder: async (content) => {
|
|
686
|
-
const res = await queueClient.chat.postMessage({ channel: chId, text: content });
|
|
687
|
-
return res.ts ?? null;
|
|
688
|
-
},
|
|
689
|
-
editPlaceholder: async (handle, content) => {
|
|
690
|
-
await queueClient.chat.update({ channel: chId, ts: handle, text: content });
|
|
691
|
-
},
|
|
692
|
-
deletePlaceholder: async (handle) => {
|
|
693
|
-
await queueClient.chat.delete({ channel: chId, ts: handle });
|
|
694
|
-
},
|
|
695
|
-
};
|
|
696
|
-
const stepTracker = new tool_status_tracker_js_1.ToolStatusTracker(adapter, {
|
|
697
|
-
throttleMs: 1500,
|
|
698
|
-
initialDelayMs: 2000,
|
|
699
|
-
});
|
|
700
|
-
return {
|
|
701
|
-
callbacks: stepTracker.toPromptCallbacks(),
|
|
702
|
-
cleanup: () => stepTracker.cleanup(),
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
: undefined;
|
|
706
|
-
const workflowResult = await this.tryExecuteWorkflow(response, message.channelId, 'slack', undefined, createStepCbs);
|
|
707
|
-
if (workflowResult && !workflowResult.failed) {
|
|
708
|
-
displayResponse = workflowResult.directMessage
|
|
709
|
-
? `${workflowResult.directMessage}\n\n${workflowResult.result}`
|
|
710
|
-
: workflowResult.result;
|
|
711
|
-
}
|
|
712
|
-
else {
|
|
713
|
-
// Strip workflow/council plan JSON from queued responses
|
|
714
|
-
if (this.workflowEngine?.isEnabled()) {
|
|
715
|
-
displayResponse = this.workflowEngine.extractNonPlanContent(displayResponse);
|
|
716
|
-
}
|
|
717
|
-
if (this.councilEngine) {
|
|
718
|
-
displayResponse = this.councilEngine.extractNonPlanContent(displayResponse);
|
|
719
|
-
}
|
|
720
|
-
// Execute text-based gateway tool calls
|
|
721
|
-
displayResponse = await this.executeTextToolCalls(displayResponse);
|
|
722
|
-
}
|
|
723
|
-
// Format response with agent prefix
|
|
724
|
-
const formattedResponse = this.formatAgentResponse(agent, displayResponse);
|
|
725
|
-
const agentResponse = {
|
|
726
|
-
agentId,
|
|
727
|
-
agent,
|
|
728
|
-
content: formattedResponse,
|
|
729
|
-
rawContent: displayResponse,
|
|
730
|
-
};
|
|
731
|
-
// Send to channel (use channel-aware WebClient as fallback for agents without dedicated bots)
|
|
732
|
-
await this.sendAgentResponses(message.channelId, message.threadTs, [agentResponse], this.getWebClientForChannel(message.channelId) ?? undefined);
|
|
733
|
-
// Record to shared context
|
|
734
|
-
this.sharedContext.recordAgentMessage(message.channelId, agent, displayResponse, agentResponse.messageId || '');
|
|
735
|
-
this.logger.log(`[MultiAgentSlack] Queued message delivered for ${agentId} in ${message.channelId}`);
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Handle bot->agent mention delegation (called by gateway for main bot messages).
|
|
739
|
-
* Bridges the gap where Slack's app_mention event doesn't fire for bot-posted messages.
|
|
740
|
-
*/
|
|
741
|
-
async handleBotToAgentMention(targetAgentId, event, mainWebClient) {
|
|
742
|
-
// Dedup: prevent double processing if both gateway and SlackMultiBotManager fire
|
|
743
|
-
const dedupKey = `${targetAgentId}:${event.ts}`;
|
|
744
|
-
if (this.processedMentions.has(dedupKey))
|
|
745
|
-
return;
|
|
746
|
-
this.processedMentions.set(dedupKey, Date.now());
|
|
747
|
-
const cleanContent = event.text.replace(/<@[UW]\w+>/g, '').trim();
|
|
748
|
-
if (!cleanContent)
|
|
749
|
-
return;
|
|
750
|
-
// Determine sender agent
|
|
751
|
-
const senderBotResult = event.bot_id ? this.multiBotManager.isFromAgentBot(event.bot_id) : null;
|
|
752
|
-
const senderAgentId = senderBotResult === 'main'
|
|
753
|
-
? (this.multiBotManager.getMainBotAgentId() ?? undefined)
|
|
754
|
-
: (senderBotResult ?? undefined);
|
|
755
|
-
// Chain depth check
|
|
756
|
-
const chainState = this.orchestrator.getChainState(event.channel);
|
|
757
|
-
const maxDepth = this.config.max_mention_depth ?? 3;
|
|
758
|
-
if (chainState.blocked || chainState.length >= maxDepth) {
|
|
759
|
-
this.logger.log(`[MultiAgentSlack] Bot->Agent mention chain blocked/maxed in ${event.channel}`);
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
762
|
-
this.logger.log(`[MultiAgentSlack] Bot->Agent mention: ${senderAgentId ?? 'main'} -> ${targetAgentId}, content="${cleanContent.substring(0, 50)}"`);
|
|
763
|
-
// Add eyes reaction
|
|
764
|
-
try {
|
|
765
|
-
await mainWebClient.reactions.add({
|
|
766
|
-
channel: event.channel,
|
|
767
|
-
timestamp: event.ts,
|
|
768
|
-
name: 'eyes',
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
catch {
|
|
772
|
-
/* ignore reaction errors */
|
|
773
|
-
}
|
|
774
|
-
const botMentionDescription = cleanContent.substring(0, 200);
|
|
775
|
-
this.systemReminder.notify({
|
|
776
|
-
type: 'delegation-started',
|
|
777
|
-
taskId: '',
|
|
778
|
-
description: botMentionDescription,
|
|
779
|
-
agentId: targetAgentId,
|
|
780
|
-
requestedBy: senderAgentId ?? 'main',
|
|
781
|
-
channelId: event.channel,
|
|
782
|
-
source: 'slack',
|
|
783
|
-
timestamp: Date.now(),
|
|
784
|
-
});
|
|
785
|
-
try {
|
|
786
|
-
const response = await this.processAgentResponse(targetAgentId, {
|
|
787
|
-
channelId: event.channel,
|
|
788
|
-
userId: event.user,
|
|
789
|
-
content: cleanContent,
|
|
790
|
-
isBot: true,
|
|
791
|
-
senderAgentId,
|
|
792
|
-
mentionedAgentIds: [targetAgentId],
|
|
793
|
-
messageId: event.ts,
|
|
794
|
-
timestamp: parseFloat(event.ts) * 1000,
|
|
795
|
-
}, cleanContent);
|
|
796
|
-
if (response) {
|
|
797
|
-
this.systemReminder.notify({
|
|
798
|
-
type: 'delegation-completed',
|
|
799
|
-
taskId: '',
|
|
800
|
-
description: botMentionDescription,
|
|
801
|
-
agentId: targetAgentId,
|
|
802
|
-
requestedBy: senderAgentId ?? 'main',
|
|
803
|
-
channelId: event.channel,
|
|
804
|
-
source: 'slack',
|
|
805
|
-
duration: response.duration,
|
|
806
|
-
timestamp: Date.now(),
|
|
807
|
-
});
|
|
808
|
-
const threadTs = event.thread_ts || event.ts;
|
|
809
|
-
await this.sendAgentResponses(event.channel, threadTs, [response], mainWebClient);
|
|
810
|
-
this.orchestrator.recordAgentResponse(targetAgentId, event.channel, response.messageId);
|
|
811
|
-
// Recursively route mentions in this agent's response.
|
|
812
|
-
// Necessary because Slack doesn't deliver a bot's own messages back to itself.
|
|
813
|
-
await this.routeResponseMentions(event.channel, threadTs, [response], mainWebClient);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
catch (err) {
|
|
817
|
-
this.logger.error(`[MultiAgentSlack] Bot->Agent mention error:`, err);
|
|
818
|
-
}
|
|
819
|
-
finally {
|
|
820
|
-
// Replace eyes with checkmark regardless of success/failure
|
|
821
|
-
try {
|
|
822
|
-
await mainWebClient.reactions.remove({
|
|
823
|
-
channel: event.channel,
|
|
824
|
-
timestamp: event.ts,
|
|
825
|
-
name: 'eyes',
|
|
826
|
-
});
|
|
827
|
-
await mainWebClient.reactions.add({
|
|
828
|
-
channel: event.channel,
|
|
829
|
-
timestamp: event.ts,
|
|
830
|
-
name: 'white_check_mark',
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
catch {
|
|
834
|
-
/* ignore reaction errors */
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* After sending agent responses, check for mentions to other agents and route them.
|
|
840
|
-
* Necessary because Slack Socket Mode doesn't deliver a bot's own messages back to itself,
|
|
841
|
-
* so the gateway's message listener never fires for responses sent by any bot.
|
|
842
|
-
*/
|
|
843
|
-
async routeResponseMentions(channelId, threadTs, responses, mainWebClient) {
|
|
844
|
-
for (const response of responses) {
|
|
845
|
-
// Filter out self-mentions to prevent routing an agent's response back to itself
|
|
846
|
-
const mentionedAgentIds = this.extractMentionedAgentIds(response.rawContent).filter((id) => id !== response.agentId);
|
|
847
|
-
if (mentionedAgentIds.length === 0) {
|
|
848
|
-
continue;
|
|
849
|
-
}
|
|
850
|
-
this.logger.log(`[MultiAgentSlack] Auto-routing mentions from ${response.agentId}: -> ${mentionedAgentIds.join(', ')}`);
|
|
851
|
-
// Route to all mentioned agents in parallel (not sequential)
|
|
852
|
-
await Promise.all(mentionedAgentIds.map((targetAgentId) => {
|
|
853
|
-
const syntheticEvent = {
|
|
854
|
-
type: 'message',
|
|
855
|
-
channel: channelId,
|
|
856
|
-
user: '',
|
|
857
|
-
text: response.rawContent,
|
|
858
|
-
ts: `${response.messageId || threadTs}-${response.agentId}`,
|
|
859
|
-
thread_ts: threadTs,
|
|
860
|
-
bot_id: 'auto-route',
|
|
861
|
-
};
|
|
862
|
-
return this.handleBotToAgentMention(targetAgentId, syntheticEvent, mainWebClient);
|
|
863
|
-
}));
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
/**
|
|
867
|
-
* Get multi-bot manager
|
|
868
|
-
*/
|
|
869
|
-
getMultiBotManager() {
|
|
870
|
-
return this.multiBotManager;
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
* Start heartbeat polling for a channel.
|
|
874
|
-
* Only reports when at least 1 agent is busy. Silent when all idle.
|
|
875
|
-
*/
|
|
876
|
-
startHeartbeat(channelId) {
|
|
877
|
-
// Already running for this channel
|
|
878
|
-
if (this.heartbeatInterval && this.heartbeatChannelId === channelId)
|
|
879
|
-
return;
|
|
880
|
-
// Stop existing heartbeat if switching channels
|
|
881
|
-
this.stopHeartbeat();
|
|
882
|
-
this.heartbeatChannelId = channelId;
|
|
883
|
-
this.heartbeatInterval = setInterval(() => {
|
|
884
|
-
this.pollAndReport().catch((err) => {
|
|
885
|
-
this.logger.error('[Heartbeat] Poll error:', err);
|
|
886
|
-
});
|
|
887
|
-
}, HEARTBEAT_INTERVAL_MS());
|
|
888
|
-
this.logger.log(`[Heartbeat] Started for channel ${channelId} (${HEARTBEAT_INTERVAL_MS() / 1000}s interval)`);
|
|
889
|
-
}
|
|
890
|
-
/**
|
|
891
|
-
* Stop heartbeat polling
|
|
892
|
-
*/
|
|
893
|
-
stopHeartbeat() {
|
|
894
|
-
if (this.heartbeatInterval) {
|
|
895
|
-
clearInterval(this.heartbeatInterval);
|
|
896
|
-
this.heartbeatInterval = undefined;
|
|
897
|
-
this.heartbeatChannelId = null;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
/**
|
|
901
|
-
* Poll agent states and report to Slack if any are busy
|
|
902
|
-
*/
|
|
903
|
-
async pollAndReport() {
|
|
904
|
-
if (!this.mainWebClient || !this.heartbeatChannelId) {
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
const agentStates = this.processManager.getAgentStates();
|
|
908
|
-
// Check if any agent is busy
|
|
909
|
-
let hasBusy = false;
|
|
910
|
-
for (const state of agentStates.values()) {
|
|
911
|
-
if (state === 'busy' || state === 'starting') {
|
|
912
|
-
hasBusy = true;
|
|
913
|
-
break;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
// Silent when no agents are busy
|
|
917
|
-
if (!hasBusy)
|
|
918
|
-
return;
|
|
919
|
-
// Build status line
|
|
920
|
-
const agentConfigs = this.config.agents;
|
|
921
|
-
const parts = [];
|
|
922
|
-
for (const [agentId, agentConfig] of Object.entries(agentConfigs)) {
|
|
923
|
-
if (agentConfig.enabled === false)
|
|
924
|
-
continue;
|
|
925
|
-
const state = agentStates.get(agentId) ?? 'idle';
|
|
926
|
-
const emoji = STATE_EMOJI[state] ?? '❓';
|
|
927
|
-
const queueSize = this.messageQueue.getQueueSize(agentId);
|
|
928
|
-
let entry = `${emoji} ${agentConfig.display_name}: ${state}`;
|
|
929
|
-
if (queueSize > 0) {
|
|
930
|
-
entry += ` (📬 ${queueSize} queued)`;
|
|
931
|
-
}
|
|
932
|
-
parts.push(entry);
|
|
933
|
-
}
|
|
934
|
-
const statusLine = `⏱️ *Agent Status* | ${parts.join(' | ')}`;
|
|
935
|
-
try {
|
|
936
|
-
await this.mainWebClient.chat.postMessage({
|
|
937
|
-
channel: this.heartbeatChannelId,
|
|
938
|
-
text: statusLine,
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
catch (err) {
|
|
942
|
-
this.logger.error('[Heartbeat] Failed to post status:', err);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
/**
|
|
946
|
-
* Get status of all agent bots
|
|
947
|
-
*/
|
|
948
|
-
getBotStatus() {
|
|
949
|
-
return this.multiBotManager.getStatus();
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
exports.MultiAgentSlackHandler = MultiAgentSlackHandler;
|
|
953
|
-
//# sourceMappingURL=multi-agent-slack.js.map
|