@desplega.ai/agent-swarm 1.20.0 → 1.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +271 -169
- package/openapi.json +5015 -0
- package/package.json +40 -7
- package/plugin/commands/close-issue.md +7 -3
- package/plugin/commands/create-pr.md +18 -12
- package/plugin/commands/implement-issue.md +7 -3
- package/plugin/commands/respond-github.md +8 -4
- package/plugin/commands/review-pr.md +44 -10
- package/plugin/commands/start-leader.md +1 -3
- package/plugin/commands/start-worker.md +1 -3
- package/plugin/commands/work-on-task.md +22 -3
- package/plugin/pi-skills/close-issue/SKILL.md +90 -0
- package/plugin/pi-skills/create-pr/SKILL.md +99 -0
- package/plugin/pi-skills/implement-issue/SKILL.md +135 -0
- package/plugin/pi-skills/investigate-sentry-issue/SKILL.md +138 -0
- package/plugin/pi-skills/respond-github/SKILL.md +98 -0
- package/plugin/pi-skills/review-offered-task/SKILL.md +45 -0
- package/plugin/pi-skills/review-pr/SKILL.md +261 -0
- package/plugin/pi-skills/start-leader/SKILL.md +121 -0
- package/plugin/pi-skills/start-worker/SKILL.md +60 -0
- package/plugin/pi-skills/swarm-chat/SKILL.md +82 -0
- package/plugin/pi-skills/todos/SKILL.md +66 -0
- package/plugin/pi-skills/work-on-task/SKILL.md +65 -0
- package/plugin/skills/artifacts/examples/approval-flow.ts +34 -0
- package/plugin/skills/artifacts/examples/hono-dashboard.ts +31 -0
- package/plugin/skills/artifacts/examples/multi-artifact.ts +20 -0
- package/plugin/skills/artifacts/examples/static-report.sh +17 -0
- package/plugin/skills/artifacts/skill.md +71 -0
- package/src/agentmail/app.ts +65 -0
- package/src/agentmail/handlers.ts +262 -0
- package/src/agentmail/index.ts +9 -0
- package/src/agentmail/templates.ts +111 -0
- package/src/agentmail/types.ts +51 -0
- package/src/artifact-sdk/browser-sdk.ts +30 -0
- package/src/artifact-sdk/index.ts +2 -0
- package/src/artifact-sdk/localtunnel.d.ts +20 -0
- package/src/artifact-sdk/port.ts +12 -0
- package/src/artifact-sdk/server.ts +156 -0
- package/src/artifact-sdk/tunnel.ts +19 -0
- package/src/be/chunking.ts +193 -0
- package/src/be/db-queries/oauth.ts +90 -0
- package/src/be/db-queries/tracker.ts +182 -0
- package/src/be/db.ts +3327 -784
- package/src/be/embedding.ts +80 -0
- package/src/be/migrations/001_initial.sql +409 -0
- package/src/be/migrations/002_one_time_schedules.sql +59 -0
- package/src/be/migrations/003_workflows.sql +51 -0
- package/src/be/migrations/004_workflow_source.sql +81 -0
- package/src/be/migrations/005_epic_next_steps.sql +2 -0
- package/src/be/migrations/006_vcs_provider.sql +94 -0
- package/src/be/migrations/007_task_dir.sql +2 -0
- package/src/be/migrations/008_workflow_redesign.sql +85 -0
- package/src/be/migrations/009_tracker_integration.sql +144 -0
- package/src/be/migrations/010_step_diagnostics.sql +1 -0
- package/src/be/migrations/011_step_next_port.sql +1 -0
- package/src/be/migrations/012_trigger_schema.sql +1 -0
- package/src/be/migrations/013_task_output_schema.sql +2 -0
- package/src/be/migrations/014_prompt_templates.sql +33 -0
- package/src/be/migrations/015_workflow_workspace.sql +3 -0
- package/src/be/migrations/016_active_session_runner_session.sql +4 -0
- package/src/be/migrations/017_channel_activity_cursors.sql +6 -0
- package/src/be/migrations/018_fix_seed_double_version.sql +30 -0
- package/src/be/migrations/runner.ts +188 -0
- package/src/be/seed.ts +62 -0
- package/src/cli.tsx +231 -299
- package/src/commands/artifact.ts +241 -0
- package/src/commands/onboard/compose-generator.ts +169 -0
- package/src/commands/onboard/env-generator.ts +79 -0
- package/src/commands/onboard/manifest.ts +37 -0
- package/src/commands/onboard/presets.ts +85 -0
- package/src/commands/onboard/service-names.ts +47 -0
- package/src/commands/onboard/steps/core-credentials.tsx +111 -0
- package/src/commands/onboard/steps/custom-templates.tsx +168 -0
- package/src/commands/onboard/steps/generate.tsx +154 -0
- package/src/commands/onboard/steps/harness-credentials.tsx +195 -0
- package/src/commands/onboard/steps/harness.tsx +21 -0
- package/src/commands/onboard/steps/health-check.tsx +171 -0
- package/src/commands/onboard/steps/integration-github.tsx +105 -0
- package/src/commands/onboard/steps/integration-gitlab.tsx +79 -0
- package/src/commands/onboard/steps/integration-menu.tsx +58 -0
- package/src/commands/onboard/steps/integration-sentry.tsx +79 -0
- package/src/commands/onboard/steps/integration-slack.tsx +165 -0
- package/src/commands/onboard/steps/post-connect.tsx +145 -0
- package/src/commands/onboard/steps/post-dashboard.tsx +34 -0
- package/src/commands/onboard/steps/post-task.tsx +103 -0
- package/src/commands/onboard/steps/prereq-check.tsx +178 -0
- package/src/commands/onboard/steps/review.tsx +82 -0
- package/src/commands/onboard/steps/start.tsx +97 -0
- package/src/commands/onboard/templates.ts +34 -0
- package/src/commands/onboard/types.ts +259 -0
- package/src/commands/onboard.tsx +425 -0
- package/src/commands/runner.ts +1540 -630
- package/src/commands/setup.tsx +23 -38
- package/src/commands/shared/client-config.ts +41 -0
- package/src/commands/templates.ts +172 -0
- package/src/github/app.ts +8 -0
- package/src/github/handlers.ts +384 -151
- package/src/github/index.ts +1 -0
- package/src/github/mentions-aliases.test.ts +73 -0
- package/src/github/mentions.test.ts +3 -3
- package/src/github/mentions.ts +32 -6
- package/src/github/templates.ts +398 -0
- package/src/github/types.ts +1 -0
- package/src/gitlab/auth.ts +63 -0
- package/src/gitlab/handlers.ts +368 -0
- package/src/gitlab/index.ts +19 -0
- package/src/gitlab/reactions.ts +104 -0
- package/src/gitlab/templates.ts +140 -0
- package/src/gitlab/types.ts +130 -0
- package/src/heartbeat/heartbeat.ts +434 -0
- package/src/heartbeat/index.ts +1 -0
- package/src/heartbeat/templates.ts +30 -0
- package/src/hooks/hook.ts +555 -4
- package/src/hooks/tool-loop-detection.test.ts +158 -0
- package/src/hooks/tool-loop-detection.ts +167 -0
- package/src/http/active-sessions.ts +199 -0
- package/src/http/agents.ts +328 -0
- package/src/http/config.ts +191 -0
- package/src/http/core.ts +309 -0
- package/src/http/db-query.ts +91 -0
- package/src/http/ecosystem.ts +63 -0
- package/src/http/epics.ts +460 -0
- package/src/http/index.ts +216 -0
- package/src/http/mcp.ts +77 -0
- package/src/http/memory.ts +168 -0
- package/src/http/openapi.ts +109 -0
- package/src/http/poll.ts +299 -0
- package/src/http/prompt-templates.ts +412 -0
- package/src/http/repos.ts +195 -0
- package/src/http/route-def.ts +123 -0
- package/src/http/schedules.ts +426 -0
- package/src/http/session-data.ts +241 -0
- package/src/http/stats.ts +174 -0
- package/src/http/tasks.ts +468 -0
- package/src/http/trackers/index.ts +10 -0
- package/src/http/trackers/linear.ts +187 -0
- package/src/http/types.ts +12 -0
- package/src/http/utils.ts +87 -0
- package/src/http/webhooks.ts +432 -0
- package/src/http/workflows.ts +530 -0
- package/src/http.ts +1 -1890
- package/src/linear/README.md +65 -0
- package/src/linear/app.ts +48 -0
- package/src/linear/client.ts +18 -0
- package/src/linear/index.ts +1 -0
- package/src/linear/oauth.ts +35 -0
- package/src/linear/outbound.ts +212 -0
- package/src/linear/sync.ts +567 -0
- package/src/linear/templates.ts +47 -0
- package/src/linear/types.ts +7 -0
- package/src/linear/webhook.ts +104 -0
- package/src/oauth/README.md +66 -0
- package/src/oauth/index.ts +6 -0
- package/src/oauth/wrapper.ts +204 -0
- package/src/prompts/base-prompt.ts +150 -265
- package/src/prompts/defaults.ts +196 -0
- package/src/prompts/registry.ts +57 -0
- package/src/prompts/resolver.ts +296 -0
- package/src/prompts/session-templates.ts +604 -0
- package/src/providers/claude-adapter.ts +442 -0
- package/src/providers/index.ts +24 -0
- package/src/providers/pi-mono-adapter.ts +442 -0
- package/src/providers/pi-mono-extension.ts +624 -0
- package/src/providers/pi-mono-mcp-client.ts +124 -0
- package/src/providers/types.ts +75 -0
- package/src/scheduler/scheduler.test.ts +2 -0
- package/src/scheduler/scheduler.ts +231 -40
- package/src/server.ts +97 -6
- package/src/slack/HEURISTICS.md +105 -0
- package/src/slack/actions.ts +133 -0
- package/src/slack/app.ts +7 -0
- package/src/slack/assistant.ts +118 -0
- package/src/slack/blocks.ts +233 -0
- package/src/slack/channel-activity.ts +177 -0
- package/src/slack/commands.ts +31 -17
- package/src/slack/files.ts +1 -1
- package/src/slack/handlers.test.ts +114 -1
- package/src/slack/handlers.ts +230 -55
- package/src/slack/responses.ts +120 -67
- package/src/slack/router.ts +17 -99
- package/src/slack/templates.ts +55 -0
- package/src/slack/thread-buffer.ts +213 -0
- package/src/slack/watcher.ts +119 -4
- package/src/tests/agent-activity.test.ts +247 -0
- package/src/tests/agentmail-filters.test.ts +97 -0
- package/src/tests/artifact-sdk.test.ts +800 -0
- package/src/tests/base-prompt.test.ts +264 -0
- package/src/tests/build-pi-skills.test.ts +127 -0
- package/src/tests/channel-activity.test.ts +363 -0
- package/src/tests/claude-adapter.test.ts +126 -0
- package/src/tests/context-versioning.test.ts +425 -0
- package/src/tests/db-queries-oauth.test.ts +197 -0
- package/src/tests/db-queries-tracker.test.ts +230 -0
- package/src/tests/epics.test.ts +3 -3
- package/src/tests/error-tracker.test.ts +368 -0
- package/src/tests/fetch-resolved-env.test.ts +167 -0
- package/src/tests/generate-default-claude-md.test.ts +9 -1
- package/src/tests/generate-identity-templates.test.ts +124 -0
- package/src/tests/gitlab-auth.test.ts +109 -0
- package/src/tests/gitlab-handlers.test.ts +691 -0
- package/src/tests/gitlab-vcs-db.test.ts +177 -0
- package/src/tests/heartbeat.test.ts +364 -0
- package/src/tests/http-api-integration.test.ts +1698 -0
- package/src/tests/linear-outbound-sync.test.ts +200 -0
- package/src/tests/linear-webhook.test.ts +406 -0
- package/src/tests/match-route.test.ts +187 -0
- package/src/tests/memory.test.ts +737 -0
- package/src/tests/migration-runner-regressions.test.ts +86 -0
- package/src/tests/model-control.test.ts +338 -0
- package/src/tests/oauth-wrapper.test.ts +147 -0
- package/src/tests/onboard-compose.test.ts +138 -0
- package/src/tests/onboard-env.test.ts +174 -0
- package/src/tests/onboard-manifest.test.ts +137 -0
- package/src/tests/pi-mono-adapter.test.ts +234 -0
- package/src/tests/pool-session-logs.test.ts +199 -0
- package/src/tests/progress-dedup.test.ts +98 -0
- package/src/tests/prompt-template-github.test.ts +682 -0
- package/src/tests/prompt-template-remaining.test.ts +504 -0
- package/src/tests/prompt-template-resolver.test.ts +621 -0
- package/src/tests/prompt-template-session.test.ts +363 -0
- package/src/tests/prompt-templates-db.test.ts +616 -0
- package/src/tests/provider-adapter.test.ts +122 -0
- package/src/tests/provider-command-format.test.ts +98 -0
- package/src/tests/reload-config.test.ts +170 -0
- package/src/tests/runner-polling-api.test.ts +25 -20
- package/src/tests/scheduled-tasks.test.ts +104 -0
- package/src/tests/scheduler-backoff.test.ts +166 -0
- package/src/tests/self-improvement.test.ts +541 -0
- package/src/tests/session-attach.test.ts +536 -0
- package/src/tests/session-costs.test.ts +267 -1
- package/src/tests/slack-actions.test.ts +133 -0
- package/src/tests/slack-assistant.test.ts +136 -0
- package/src/tests/slack-blocks.test.ts +246 -0
- package/src/tests/slack-metadata-inheritance.test.ts +243 -0
- package/src/tests/slack-queue-offline.test.ts +174 -0
- package/src/tests/slack-router.test.ts +181 -0
- package/src/tests/slack-thread-buffer.test.ts +305 -0
- package/src/tests/slack-thread-followups.test.ts +298 -0
- package/src/tests/slack-watcher.test.ts +101 -0
- package/src/tests/structured-output.test.ts +307 -0
- package/src/tests/swarm-repos.test.ts +198 -0
- package/src/tests/task-cancellation.test.ts +6 -4
- package/src/tests/task-working-dir.test.ts +176 -0
- package/src/tests/template-fetch.test.ts +490 -0
- package/src/tests/tool-annotations.test.ts +371 -0
- package/src/tests/tracker-tools.test.ts +184 -0
- package/src/tests/update-profile-agentid.test.ts +248 -0
- package/src/tests/update-profile-api.test.ts +143 -3
- package/src/tests/update-profile-auth.test.ts +195 -0
- package/src/tests/validation-adapters.test.ts +86 -0
- package/src/tests/vcs-provider.test.ts +27 -0
- package/src/tests/workflow-agent-task.test.ts +196 -0
- package/src/tests/workflow-async-v2.test.ts +508 -0
- package/src/tests/workflow-convergence.test.ts +541 -0
- package/src/tests/workflow-definition-validation.test.ts +366 -0
- package/src/tests/workflow-engine-v2.test.ts +691 -0
- package/src/tests/workflow-executors.test.ts +736 -0
- package/src/tests/workflow-http-v2.test.ts +599 -0
- package/src/tests/workflow-integration-io.test.ts +902 -0
- package/src/tests/workflow-io-schemas.test.ts +624 -0
- package/src/tests/workflow-registry.test.ts +592 -0
- package/src/tests/workflow-retry-v2.test.ts +401 -0
- package/src/tests/workflow-retry-validation.test.ts +282 -0
- package/src/tests/workflow-schedule-trigger.test.ts +104 -0
- package/src/tests/workflow-template.test.ts +288 -0
- package/src/tests/workflow-trigger-schema.test.ts +359 -0
- package/src/tests/workflow-triggers-v2.test.ts +264 -0
- package/src/tests/workflow-versions.test.ts +208 -0
- package/src/tests/workflow-workspace.test.ts +272 -0
- package/src/tests/x402-client.test.ts +117 -0
- package/src/tests/x402-config.test.ts +182 -0
- package/src/tests/x402-spending-tracker.test.ts +185 -0
- package/src/tools/cancel-task.ts +2 -0
- package/src/tools/context-diff.ts +171 -0
- package/src/tools/context-history.ts +138 -0
- package/src/tools/create-channel.ts +1 -0
- package/src/tools/db-query.ts +78 -0
- package/src/tools/delete-channel.ts +132 -0
- package/src/tools/epics/assign-task-to-epic.ts +1 -0
- package/src/tools/epics/create-epic.ts +3 -2
- package/src/tools/epics/delete-epic.ts +2 -0
- package/src/tools/epics/get-epic-details.ts +2 -0
- package/src/tools/epics/list-epics.ts +2 -0
- package/src/tools/epics/unassign-task-from-epic.ts +1 -0
- package/src/tools/epics/update-epic.ts +7 -4
- package/src/tools/get-swarm.ts +2 -0
- package/src/tools/get-task-details.ts +2 -0
- package/src/tools/get-tasks.ts +27 -1
- package/src/tools/inject-learning.ts +106 -0
- package/src/tools/join-swarm.ts +17 -7
- package/src/tools/list-channels.ts +2 -0
- package/src/tools/list-services.ts +2 -0
- package/src/tools/memory-get.ts +56 -0
- package/src/tools/memory-search.ts +131 -0
- package/src/tools/my-agent-info.ts +2 -0
- package/src/tools/poll-task.ts +2 -20
- package/src/tools/post-message.ts +1 -0
- package/src/tools/prompt-templates/delete.ts +86 -0
- package/src/tools/prompt-templates/get.ts +89 -0
- package/src/tools/prompt-templates/index.ts +5 -0
- package/src/tools/prompt-templates/list.ts +95 -0
- package/src/tools/prompt-templates/preview.ts +84 -0
- package/src/tools/prompt-templates/set.ts +117 -0
- package/src/tools/read-messages.ts +2 -0
- package/src/tools/register-agentmail-inbox.ts +166 -0
- package/src/tools/register-service.ts +2 -0
- package/src/tools/schedules/create-schedule.ts +134 -24
- package/src/tools/schedules/delete-schedule.ts +2 -0
- package/src/tools/schedules/list-schedules.ts +20 -4
- package/src/tools/schedules/run-schedule-now.ts +1 -0
- package/src/tools/schedules/update-schedule.ts +49 -17
- package/src/tools/send-task.ts +132 -10
- package/src/tools/slack-download-file.ts +4 -2
- package/src/tools/slack-list-channels.ts +2 -0
- package/src/tools/slack-post.ts +2 -0
- package/src/tools/slack-read.ts +2 -0
- package/src/tools/slack-reply.ts +2 -0
- package/src/tools/slack-upload-file.ts +2 -0
- package/src/tools/store-progress.ts +205 -4
- package/src/tools/swarm-config/delete-config.ts +87 -0
- package/src/tools/swarm-config/get-config.ts +108 -0
- package/src/tools/swarm-config/index.ts +4 -0
- package/src/tools/swarm-config/list-config.ts +99 -0
- package/src/tools/swarm-config/set-config.ts +118 -0
- package/src/tools/task-action.ts +50 -5
- package/src/tools/task-dedup.ts +97 -0
- package/src/tools/templates.ts +53 -0
- package/src/tools/tool-config.ts +124 -0
- package/src/tools/tracker/index.ts +6 -0
- package/src/tools/tracker/tracker-link-epic.ts +64 -0
- package/src/tools/tracker/tracker-link-task.ts +64 -0
- package/src/tools/tracker/tracker-map-agent.ts +57 -0
- package/src/tools/tracker/tracker-status.ts +56 -0
- package/src/tools/tracker/tracker-sync-status.ts +42 -0
- package/src/tools/tracker/tracker-unlink.ts +41 -0
- package/src/tools/unregister-service.ts +2 -0
- package/src/tools/update-profile.ts +172 -17
- package/src/tools/update-service-status.ts +2 -0
- package/src/tools/utils.ts +10 -1
- package/src/tools/workflows/create-workflow.ts +129 -0
- package/src/tools/workflows/delete-workflow.ts +42 -0
- package/src/tools/workflows/get-workflow-run.ts +59 -0
- package/src/tools/workflows/get-workflow.ts +53 -0
- package/src/tools/workflows/index.ts +9 -0
- package/src/tools/workflows/list-workflow-runs.ts +48 -0
- package/src/tools/workflows/list-workflows.ts +42 -0
- package/src/tools/workflows/retry-workflow-run.ts +40 -0
- package/src/tools/workflows/trigger-workflow.ts +96 -0
- package/src/tools/workflows/update-workflow.ts +133 -0
- package/src/tracker/types.ts +51 -0
- package/src/types.ts +530 -14
- package/src/utils/credentials.test.ts +156 -0
- package/src/utils/credentials.ts +50 -0
- package/src/utils/error-tracker.ts +190 -0
- package/src/vcs/index.ts +15 -0
- package/src/vcs/types.ts +5 -0
- package/src/workflows/checkpoint.ts +121 -0
- package/src/workflows/cooldown.ts +28 -0
- package/src/workflows/definition.ts +235 -0
- package/src/workflows/engine.ts +580 -0
- package/src/workflows/event-bus.ts +29 -0
- package/src/workflows/executors/agent-task.ts +103 -0
- package/src/workflows/executors/base.ts +86 -0
- package/src/workflows/executors/code-match.ts +88 -0
- package/src/workflows/executors/index.ts +16 -0
- package/src/workflows/executors/notify.ts +93 -0
- package/src/workflows/executors/property-match.ts +104 -0
- package/src/workflows/executors/raw-llm.ts +83 -0
- package/src/workflows/executors/registry.ts +76 -0
- package/src/workflows/executors/script.ts +103 -0
- package/src/workflows/executors/validate.ts +215 -0
- package/src/workflows/executors/vcs.ts +58 -0
- package/src/workflows/index.ts +61 -0
- package/src/workflows/input.ts +46 -0
- package/src/workflows/json-schema-validator.ts +118 -0
- package/src/workflows/recovery.ts +139 -0
- package/src/workflows/resume.ts +229 -0
- package/src/workflows/retry-poller.ts +216 -0
- package/src/workflows/template.ts +74 -0
- package/src/workflows/templates.ts +86 -0
- package/src/workflows/triggers.ts +124 -0
- package/src/workflows/validation.ts +104 -0
- package/src/workflows/version.ts +44 -0
- package/src/x402/cli.ts +140 -0
- package/src/x402/client.ts +192 -0
- package/src/x402/config.ts +131 -0
- package/src/x402/index.ts +37 -0
- package/src/x402/openfort-signer.ts +83 -0
- package/src/x402/spending-tracker.ts +109 -0
- package/templates/official/coder/CLAUDE.md +49 -0
- package/templates/official/coder/IDENTITY.md +28 -0
- package/templates/official/coder/SOUL.md +43 -0
- package/templates/official/coder/TOOLS.md +40 -0
- package/templates/official/coder/config.json +23 -0
- package/templates/official/coder/start-up.sh +23 -0
- package/templates/official/content-reviewer/CLAUDE.md +68 -0
- package/templates/official/content-reviewer/IDENTITY.md +28 -0
- package/templates/official/content-reviewer/SOUL.md +44 -0
- package/templates/official/content-reviewer/TOOLS.md +37 -0
- package/templates/official/content-reviewer/config.json +23 -0
- package/templates/official/content-reviewer/start-up.sh +23 -0
- package/templates/official/content-strategist/CLAUDE.md +63 -0
- package/templates/official/content-strategist/IDENTITY.md +33 -0
- package/templates/official/content-strategist/SOUL.md +48 -0
- package/templates/official/content-strategist/TOOLS.md +47 -0
- package/templates/official/content-strategist/config.json +23 -0
- package/templates/official/content-strategist/start-up.sh +23 -0
- package/templates/official/content-writer/CLAUDE.md +72 -0
- package/templates/official/content-writer/IDENTITY.md +30 -0
- package/templates/official/content-writer/SOUL.md +46 -0
- package/templates/official/content-writer/TOOLS.md +44 -0
- package/templates/official/content-writer/config.json +23 -0
- package/templates/official/content-writer/start-up.sh +23 -0
- package/templates/official/forward-deployed-engineer/CLAUDE.md +54 -0
- package/templates/official/forward-deployed-engineer/IDENTITY.md +37 -0
- package/templates/official/forward-deployed-engineer/SOUL.md +55 -0
- package/templates/official/forward-deployed-engineer/config.json +21 -0
- package/templates/official/lead/CLAUDE.md +33 -0
- package/templates/official/lead/IDENTITY.md +36 -0
- package/templates/official/lead/SOUL.md +51 -0
- package/templates/official/lead/config.json +22 -0
- package/templates/official/researcher/CLAUDE.md +46 -0
- package/templates/official/researcher/IDENTITY.md +28 -0
- package/templates/official/researcher/SOUL.md +43 -0
- package/templates/official/researcher/config.json +21 -0
- package/templates/official/reviewer/CLAUDE.md +63 -0
- package/templates/official/reviewer/IDENTITY.md +28 -0
- package/templates/official/reviewer/SOUL.md +45 -0
- package/templates/official/reviewer/config.json +21 -0
- package/templates/official/tester/CLAUDE.md +53 -0
- package/templates/official/tester/IDENTITY.md +28 -0
- package/templates/official/tester/SOUL.md +55 -0
- package/templates/official/tester/config.json +21 -0
- package/templates/schema.ts +35 -0
- package/.claude/settings.local.json +0 -115
- package/.dockerignore +0 -61
- package/.editorconfig +0 -15
- package/.env.docker.example +0 -39
- package/.env.example +0 -40
- package/.github/workflows/ci.yml +0 -76
- package/.github/workflows/docker-and-deploy.yml +0 -117
- package/.wts-config.json +0 -4
- package/.wts-setup.ts +0 -102
- package/CLAUDE.md +0 -104
- package/CONTRIBUTING.md +0 -270
- package/DEPLOYMENT.md +0 -605
- package/Dockerfile +0 -57
- package/Dockerfile.worker +0 -157
- package/FAQ.md +0 -19
- package/MCP.md +0 -406
- package/UI.md +0 -40
- package/assets/agent-swarm-logo-orange.png +0 -0
- package/assets/agent-swarm-logo.png +0 -0
- package/assets/agent-swarm.mp4 +0 -0
- package/assets/agent-swarm.png +0 -0
- package/biome.json +0 -39
- package/deploy/DEPLOY.md +0 -60
- package/deploy/agent-swarm.service +0 -17
- package/deploy/docker-push.ts +0 -30
- package/deploy/install.ts +0 -85
- package/deploy/prod-db.ts +0 -42
- package/deploy/uninstall.ts +0 -12
- package/deploy/update.ts +0 -21
- package/docker-compose.example.yml +0 -159
- package/docker-entrypoint.sh +0 -352
- package/ecosystem.config.cjs +0 -66
- package/plugin/README.md +0 -1
- package/plugin/hooks/hooks.json +0 -71
- package/pyproject.toml +0 -9
- package/scripts/generate-mcp-docs.ts +0 -415
- package/slack-manifest.json +0 -71
- package/src/tests/get-inbox-message.test.ts +0 -145
- package/src/tools/get-inbox-message.ts +0 -89
- package/src/tools/inbox-delegate.ts +0 -113
- package/thoughts/shared/plans/2025-12-18-slack-integration.md +0 -1195
- package/thoughts/shared/plans/2025-12-19-agent-log-streaming.md +0 -732
- package/thoughts/shared/plans/2025-12-19-role-based-swarm-plugin.md +0 -361
- package/thoughts/shared/plans/2025-12-20-mobile-responsive-ui.md +0 -501
- package/thoughts/shared/plans/2025-12-20-startup-team-swarm.md +0 -560
- package/thoughts/shared/plans/2025-12-23-runner-level-polling.md +0 -934
- package/thoughts/shared/plans/2025-12-23-runner-session-logs.md +0 -1000
- package/thoughts/shared/plans/2025-12-23-worker-lead-spawn-triggers.md +0 -568
- package/thoughts/shared/plans/2026-01-09-inverse-teleport.md +0 -1516
- package/thoughts/shared/plans/2026-01-12-agent-rename-pm2-control.md +0 -1133
- package/thoughts/shared/plans/2026-01-12-github-app-integration.md +0 -380
- package/thoughts/shared/plans/2026-01-12-lead-inbox-model.md +0 -876
- package/thoughts/shared/plans/2026-01-12-ralph-wiggum-integration.md +0 -463
- package/thoughts/shared/plans/2026-01-13-agent-concurrency.md +0 -691
- package/thoughts/shared/plans/2026-01-13-github-assignment-handling.md +0 -690
- package/thoughts/shared/plans/2026-01-13-prevent-duplicate-trigger-processing.md +0 -1071
- package/thoughts/shared/plans/2026-01-14-fix-slack-thread-context.md +0 -507
- package/thoughts/shared/plans/2026-01-15-scheduled-tasks-implementation.md +0 -565
- package/thoughts/shared/plans/2026-01-15-usage-cost-tracking-ui.md +0 -1479
- package/thoughts/shared/plans/2026-01-16-epics-feature-implementation.md +0 -1230
- package/thoughts/shared/research/.gitkeep +0 -0
- package/thoughts/shared/research/2025-01-09-inverse-teleport-plan-review.md +0 -420
- package/thoughts/shared/research/2025-12-18-slack-integration.md +0 -442
- package/thoughts/shared/research/2025-12-19-agent-log-streaming.md +0 -339
- package/thoughts/shared/research/2025-12-19-agent-secrets-cli-research.md +0 -390
- package/thoughts/shared/research/2025-12-21-gemini-cli-integration.md +0 -376
- package/thoughts/shared/research/2025-12-22-runner-loop-architecture.md +0 -582
- package/thoughts/shared/research/2025-12-22-setup-experience-improvements.md +0 -264
- package/thoughts/shared/research/2026-01-13-lead-duplicate-trigger-processing.md +0 -223
- package/thoughts/shared/research/2026-01-14-lead-slack-thread-context.md +0 -277
- package/thoughts/shared/research/2026-01-15-ai-tracker-agent-swarm-integration.md +0 -376
- package/thoughts/shared/research/2026-01-15-auto-starting-processes-in-worker-containers.md +0 -787
- package/thoughts/shared/research/2026-01-15-scheduled-tasks.md +0 -390
- package/thoughts/shared/research/2026-01-16-epics-feature-research.md +0 -437
- package/thoughts/taras/plans/2026-01-22-agent-swarm-schemas.md +0 -98
- package/thoughts/taras/plans/2026-01-28-per-worker-claude-md.md +0 -617
- package/thoughts/taras/plans/2026-01-28-sentry-cli-integration.md +0 -214
- package/thoughts/taras/research/2026-01-22-vercel-cli-integration.md +0 -287
- package/thoughts/taras/research/2026-01-27-excessive-polling-issue.md +0 -311
- package/thoughts/taras/research/2026-01-28-per-worker-claude-md.md +0 -383
- package/thoughts/taras/research/2026-01-28-sentry-cli-integration.md +0 -240
- package/tsconfig.json +0 -37
- package/ui/CLAUDE.md +0 -49
- package/ui/bun.lock +0 -771
- package/ui/index.html +0 -22
- package/ui/package-lock.json +0 -5290
- package/ui/package.json +0 -33
- package/ui/pnpm-lock.yaml +0 -3341
- package/ui/postcss.config.js +0 -6
- package/ui/public/logo.png +0 -0
- package/ui/src/App.tsx +0 -63
- package/ui/src/components/ActivityFeed.tsx +0 -440
- package/ui/src/components/AgentDetailPanel.tsx +0 -733
- package/ui/src/components/AgentsPanel.tsx +0 -815
- package/ui/src/components/ChatPanel.tsx +0 -1920
- package/ui/src/components/ConfigModal.tsx +0 -253
- package/ui/src/components/Dashboard.tsx +0 -832
- package/ui/src/components/EditAgentProfileModal.tsx +0 -433
- package/ui/src/components/EpicDetailPage.tsx +0 -741
- package/ui/src/components/EpicsPanel.tsx +0 -566
- package/ui/src/components/Header.tsx +0 -160
- package/ui/src/components/JsonViewer.tsx +0 -171
- package/ui/src/components/ScheduledTaskDetailPanel.tsx +0 -517
- package/ui/src/components/ScheduledTasksPanel.tsx +0 -639
- package/ui/src/components/ServicesPanel.tsx +0 -622
- package/ui/src/components/SessionLogPanel.tsx +0 -1219
- package/ui/src/components/StatsBar.tsx +0 -321
- package/ui/src/components/StatusBadge.tsx +0 -168
- package/ui/src/components/TaskDetailPanel.tsx +0 -903
- package/ui/src/components/TasksPanel.tsx +0 -614
- package/ui/src/components/UsageCharts.tsx +0 -216
- package/ui/src/components/UsageTab.tsx +0 -394
- package/ui/src/hooks/queries.ts +0 -353
- package/ui/src/hooks/useAutoScroll.ts +0 -83
- package/ui/src/index.css +0 -257
- package/ui/src/lib/api.ts +0 -268
- package/ui/src/lib/config.ts +0 -35
- package/ui/src/lib/contentPreview.ts +0 -208
- package/ui/src/lib/theme.ts +0 -214
- package/ui/src/lib/utils.ts +0 -88
- package/ui/src/main.tsx +0 -28
- package/ui/src/types/api.ts +0 -323
- package/ui/src/vite-env.d.ts +0 -1
- package/ui/tailwind.config.js +0 -37
- package/ui/tsconfig.json +0 -31
- package/ui/vite.config.ts +0 -35
- /package/{thoughts/shared/plans → templates/community}/.gitkeep +0 -0
|
@@ -1,582 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
date: 2025-12-22T17:45:00-08:00
|
|
3
|
-
researcher: master lord
|
|
4
|
-
git_commit: d1c17d6b4588df88de9a8587b6e2cc245d9014ff
|
|
5
|
-
branch: main
|
|
6
|
-
repository: agent-swarm
|
|
7
|
-
topic: "Runner While Loop and Task Triggering Architecture"
|
|
8
|
-
tags: [research, codebase, runner, poll-task, slack, task-assignment, ai-loop]
|
|
9
|
-
status: complete
|
|
10
|
-
last_updated: 2025-12-22
|
|
11
|
-
last_updated_by: master lord
|
|
12
|
-
last_updated_note: "Added AI-based loop analysis, user feedback, and proposed architecture"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# Research: Runner While Loop and Task Triggering Architecture
|
|
16
|
-
|
|
17
|
-
**Date**: 2025-12-22T17:45:00-08:00
|
|
18
|
-
**Researcher**: master lord
|
|
19
|
-
**Git Commit**: d1c17d6b4588df88de9a8587b6e2cc245d9014ff
|
|
20
|
-
**Branch**: main
|
|
21
|
-
**Repository**: agent-swarm
|
|
22
|
-
|
|
23
|
-
## Research Question
|
|
24
|
-
|
|
25
|
-
Document the current architecture of the runner while loop, poll API, task assignment mechanisms, and how leads/workers are triggered. This research supports understanding how to change from a continuous-loop model to an on-demand spawn model.
|
|
26
|
-
|
|
27
|
-
## Summary
|
|
28
|
-
|
|
29
|
-
The current architecture runs agents in an **infinite while loop** that unconditionally spawns Claude on each iteration. Task waiting happens **inside Claude** via the `poll-task` MCP tool, not before spawning. Both lead and worker agents use the same runner loop with different prompts. Slack integration creates tasks on mentions but does **not** create tasks for regular thread follow-ups without an explicit @mention.
|
|
30
|
-
|
|
31
|
-
## Detailed Findings
|
|
32
|
-
|
|
33
|
-
### 1. Runner While Loop Implementation
|
|
34
|
-
|
|
35
|
-
**File**: `src/commands/runner.ts`
|
|
36
|
-
|
|
37
|
-
The runner is a simple infinite loop at **line 208**:
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
while (true) {
|
|
41
|
-
iteration++;
|
|
42
|
-
// ... logging and metadata
|
|
43
|
-
const exitCode = await runClaudeIteration({...});
|
|
44
|
-
// ... error handling
|
|
45
|
-
console.log(`[${role}] Iteration ${iteration} complete. Starting next iteration...`);
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**Key characteristics:**
|
|
50
|
-
- **No pre-spawn task checking** - Claude is spawned immediately on each iteration
|
|
51
|
-
- **No external trigger waiting** - The loop runs unconditionally
|
|
52
|
-
- **Claude spawned via `Bun.spawn()`** at line 85 with command-line arguments
|
|
53
|
-
- **Error handling** - On exit code != 0, stops unless YOLO mode is enabled (line 247-253)
|
|
54
|
-
|
|
55
|
-
**`runClaudeIteration()` function (lines 57-136):**
|
|
56
|
-
```typescript
|
|
57
|
-
const proc = Bun.spawn(CMD, {
|
|
58
|
-
env: process.env,
|
|
59
|
-
stdout: "pipe",
|
|
60
|
-
stderr: "pipe",
|
|
61
|
-
});
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
The command array includes:
|
|
65
|
-
- `claude --verbose --output-format stream-json`
|
|
66
|
-
- `--dangerously-skip-permissions` flags
|
|
67
|
-
- `-p <prompt>` with the role-specific prompt
|
|
68
|
-
- `--append-system-prompt` with base prompt + optional additional prompt
|
|
69
|
-
|
|
70
|
-
### 2. Lead vs Worker Configuration
|
|
71
|
-
|
|
72
|
-
**Lead Agent** (`src/commands/lead.ts`):
|
|
73
|
-
```typescript
|
|
74
|
-
const leadConfig: RunnerConfig = {
|
|
75
|
-
role: "lead",
|
|
76
|
-
defaultPrompt: "/start-leader",
|
|
77
|
-
metadataType: "lead_metadata",
|
|
78
|
-
capabilities: getEnabledCapabilities(),
|
|
79
|
-
};
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Worker Agent** (`src/commands/worker.ts`):
|
|
83
|
-
```typescript
|
|
84
|
-
const workerConfig: RunnerConfig = {
|
|
85
|
-
role: "worker",
|
|
86
|
-
defaultPrompt: "/start-worker",
|
|
87
|
-
metadataType: "worker_metadata",
|
|
88
|
-
capabilities: getEnabledCapabilities(),
|
|
89
|
-
};
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Both use the same `runAgent()` function - the only difference is:
|
|
93
|
-
1. The `role` string for logging
|
|
94
|
-
2. The `defaultPrompt` (which triggers different plugin commands)
|
|
95
|
-
3. The `metadataType` for log files
|
|
96
|
-
|
|
97
|
-
### 3. Current AI-Based Loop (Inside Claude)
|
|
98
|
-
|
|
99
|
-
The current architecture relies on **AI-driven polling** defined in plugin commands. This is problematic because it consumes tokens and is unreliable (Claude decides when/how to poll).
|
|
100
|
-
|
|
101
|
-
**Worker Loop** (`plugin/commands/start-worker.md`):
|
|
102
|
-
```
|
|
103
|
-
1. Check for existing tasks with `get-tasks mineOnly=true`
|
|
104
|
-
1.1. If in-progress task exists, resume it
|
|
105
|
-
2. If no tasks, call `poll-task` (waits up to 1 minute inside Claude)
|
|
106
|
-
2.1. If task assigned → call `/work-on-task <taskId>`
|
|
107
|
-
2.2. If no task → "start polling immediately FOREVER"
|
|
108
|
-
3. Only stop if interrupted by user
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**Leader Loop** (`plugin/commands/start-leader.md`):
|
|
112
|
-
```
|
|
113
|
-
1. Check `get-swarm` and `get-tasks` to understand current state
|
|
114
|
-
2. Assign work to idle workers via `send-task`
|
|
115
|
-
3. Periodically check `get-task-details` on in-progress tasks
|
|
116
|
-
4. Use `read-messages` to catch @mentions
|
|
117
|
-
5. Use `poll-task` for tasks needing your attention
|
|
118
|
-
6. Provide updates to user on overall progress
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Work on Task** (`plugin/commands/work-on-task.md`):
|
|
122
|
-
```
|
|
123
|
-
1. Call `get-task-details` to get task info
|
|
124
|
-
2. Add todo item for tracking
|
|
125
|
-
3. Call `store-progress` to mark as in-progress
|
|
126
|
-
4. Work on task, calling `store-progress` periodically
|
|
127
|
-
5. On completion, mark as complete/failed and reply "DONE"
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Problems with AI-based loop:**
|
|
131
|
-
- **Token consumption**: Every poll iteration consumes Claude tokens
|
|
132
|
-
- **Unreliability**: Claude decides when/how to poll, may miss tasks
|
|
133
|
-
- **No external control**: Can't trigger Claude spawn from outside events
|
|
134
|
-
- **Session persistence**: Claude session stays alive, consuming resources
|
|
135
|
-
|
|
136
|
-
### 4. Poll-Task API Implementation
|
|
137
|
-
|
|
138
|
-
**File**: `src/tools/poll-task.ts`
|
|
139
|
-
|
|
140
|
-
The poll-task is an **MCP tool called from within Claude**, not an external pre-spawn mechanism.
|
|
141
|
-
|
|
142
|
-
**Constants (lines 16-17):**
|
|
143
|
-
```typescript
|
|
144
|
-
const DEFAULT_POLL_INTERVAL_MS = 2000; // 2 seconds
|
|
145
|
-
const MAX_POLL_DURATION_MS = 1 * 60 * 1000; // 1 minute
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
**Behavior flow:**
|
|
149
|
-
|
|
150
|
-
1. **Check for offered tasks first** (lines 83-104):
|
|
151
|
-
- If tasks are offered to the agent, returns immediately
|
|
152
|
-
- Agent must use `task-action` with `accept` or `reject`
|
|
153
|
-
|
|
154
|
-
2. **Poll for pending tasks** (lines 107-162):
|
|
155
|
-
- While loop with 2-second sleep intervals
|
|
156
|
-
- Maximum duration of 1 minute before timing out
|
|
157
|
-
- Uses database transaction to avoid race conditions (line 109)
|
|
158
|
-
|
|
159
|
-
3. **Auto-start task on find** (lines 120-128):
|
|
160
|
-
- When a pending task is found, `startTask()` is called
|
|
161
|
-
- Task status changes from `pending` to `in_progress`
|
|
162
|
-
- Agent status updated to `busy`
|
|
163
|
-
|
|
164
|
-
**Return structure:**
|
|
165
|
-
```typescript
|
|
166
|
-
{
|
|
167
|
-
success: boolean,
|
|
168
|
-
message: string,
|
|
169
|
-
task?: AgentTask, // The started task (if found)
|
|
170
|
-
offeredTasks: AgentTask[], // Tasks awaiting accept/reject
|
|
171
|
-
availableCount: number, // Unassigned tasks in pool
|
|
172
|
-
waitedForSeconds: number // How long polling took
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### 5. Slack Integration - Task Creation
|
|
177
|
-
|
|
178
|
-
**File**: `src/slack/handlers.ts`
|
|
179
|
-
|
|
180
|
-
**Message handler registration** (lines 140-273):
|
|
181
|
-
```typescript
|
|
182
|
-
app.event("message", async ({ event, client, say }) => {
|
|
183
|
-
// 1. Ignore bot messages and message_changed
|
|
184
|
-
// 2. Deduplicate events
|
|
185
|
-
// 3. Check if bot was mentioned
|
|
186
|
-
// 4. Route message to agents
|
|
187
|
-
// 5. Rate limit check
|
|
188
|
-
// 6. Extract task description
|
|
189
|
-
// 7. Create tasks for matched agents
|
|
190
|
-
});
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
**Task creation** (lines 231-237):
|
|
194
|
-
```typescript
|
|
195
|
-
const task = createTask(agent.id, fullTaskDescription, {
|
|
196
|
-
source: "slack",
|
|
197
|
-
slackChannelId: msg.channel,
|
|
198
|
-
slackThreadTs: threadTs,
|
|
199
|
-
slackUserId: msg.user,
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Tasks are created with status `pending` (directly assigned to agent).
|
|
204
|
-
|
|
205
|
-
### 6. Slack Message Routing
|
|
206
|
-
|
|
207
|
-
**File**: `src/slack/router.ts`
|
|
208
|
-
|
|
209
|
-
**`routeMessage()` function** (lines 77-155) - Routing rules in order:
|
|
210
|
-
|
|
211
|
-
| Priority | Pattern | Target | Code Location |
|
|
212
|
-
|----------|---------|--------|---------------|
|
|
213
|
-
| 1 | `swarm#<uuid>` | Exact agent by ID | lines 86-95 |
|
|
214
|
-
| 2 | `swarm#all` | All non-lead agents | lines 97-105 |
|
|
215
|
-
| 3 | Partial name match (3+ chars) | Agent by name | lines 107-120 |
|
|
216
|
-
| 4 | Multiple partial matches | Lead agent (to decide) | lines 122-135 |
|
|
217
|
-
| 5 | Thread follow-up (no match) | Agent working on thread | lines 138-144 |
|
|
218
|
-
| 6 | Bot @mention only | Lead agent | lines 146-152 |
|
|
219
|
-
|
|
220
|
-
**Thread follow-up handling** (lines 138-144):
|
|
221
|
-
```typescript
|
|
222
|
-
if (matches.length === 0 && threadContext) {
|
|
223
|
-
const workingAgent = getAgentWorkingOnThread(threadContext.channelId, threadContext.threadTs);
|
|
224
|
-
if (workingAgent && workingAgent.status !== "offline") {
|
|
225
|
-
matches.push({ agent: workingAgent, matchedText: "thread follow-up" });
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
**Current limitation**: Thread follow-ups only trigger when:
|
|
231
|
-
1. The message handler is invoked (requires bot mention OR agent name match)
|
|
232
|
-
2. No explicit agent match found, AND
|
|
233
|
-
3. An agent is already working on that thread
|
|
234
|
-
|
|
235
|
-
**Regular thread replies WITHOUT @mention do NOT create tasks.**
|
|
236
|
-
|
|
237
|
-
### 7. Database: Thread Agent Lookup
|
|
238
|
-
|
|
239
|
-
**File**: `src/be/db.ts`
|
|
240
|
-
|
|
241
|
-
**`getAgentWorkingOnThread()` function** (lines 732-747):
|
|
242
|
-
```sql
|
|
243
|
-
SELECT * FROM agent_tasks
|
|
244
|
-
WHERE source = 'slack'
|
|
245
|
-
AND slackChannelId = ?
|
|
246
|
-
AND slackThreadTs = ?
|
|
247
|
-
AND status IN ('in_progress', 'pending')
|
|
248
|
-
ORDER BY createdAt DESC
|
|
249
|
-
LIMIT 1
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
Returns the agent that has an active task in the specified Slack thread.
|
|
253
|
-
|
|
254
|
-
### 8. Hook System
|
|
255
|
-
|
|
256
|
-
**File**: `src/hooks/hook.ts`
|
|
257
|
-
|
|
258
|
-
The hook system provides status information at various Claude lifecycle events but does **not** control spawning:
|
|
259
|
-
|
|
260
|
-
| Event | Current Behavior |
|
|
261
|
-
|-------|------------------|
|
|
262
|
-
| `SessionStart` | Shows agent registration status |
|
|
263
|
-
| `PreCompact` | (No specific action) |
|
|
264
|
-
| `PreToolUse` | (No specific action) |
|
|
265
|
-
| `PostToolUse` | Reminders about `store-progress` |
|
|
266
|
-
| `UserPromptSubmit` | (No specific action) |
|
|
267
|
-
| `Stop` | Saves PM2 state, marks agent offline |
|
|
268
|
-
|
|
269
|
-
The hook fetches agent info via HTTP `/me?include=inbox` endpoint (line 124) and displays system tray with:
|
|
270
|
-
- Unread message count
|
|
271
|
-
- Offered tasks count
|
|
272
|
-
- Pool tasks count
|
|
273
|
-
- In-progress tasks count
|
|
274
|
-
- Recent @mentions
|
|
275
|
-
|
|
276
|
-
## Architecture Diagram
|
|
277
|
-
|
|
278
|
-
```
|
|
279
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
280
|
-
│ Current Architecture │
|
|
281
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
282
|
-
│ │
|
|
283
|
-
│ CLI invocation (worker/lead command) │
|
|
284
|
-
│ │ │
|
|
285
|
-
│ ▼ │
|
|
286
|
-
│ ┌──────────────────────────────────────────────────┐ │
|
|
287
|
-
│ │ runAgent() - src/commands/runner.ts │ │
|
|
288
|
-
│ │ ┌────────────────────────────────────────────┐ │ │
|
|
289
|
-
│ │ │ while (true) { │ │ │
|
|
290
|
-
│ │ │ // No external trigger waiting │ │ │
|
|
291
|
-
│ │ │ // Spawns Claude immediately │ │ │
|
|
292
|
-
│ │ │ exitCode = await runClaudeIteration() │ │ │
|
|
293
|
-
│ │ │ } │ │ │
|
|
294
|
-
│ │ └────────────────────────────────────────────┘ │ │
|
|
295
|
-
│ └──────────────────────────────────────────────────┘ │
|
|
296
|
-
│ │ │
|
|
297
|
-
│ ▼ │
|
|
298
|
-
│ ┌──────────────────────────────────────────────────┐ │
|
|
299
|
-
│ │ Claude Process │ │
|
|
300
|
-
│ │ - Receives /start-leader or /start-worker prompt│ │
|
|
301
|
-
│ │ - Calls MCP tools internally │ │
|
|
302
|
-
│ │ - Uses poll-task to wait for assignments │ │
|
|
303
|
-
│ │ - Task waiting happens INSIDE Claude │ │
|
|
304
|
-
│ └──────────────────────────────────────────────────┘ │
|
|
305
|
-
│ │
|
|
306
|
-
│ ┌──────────────────────────────────────────────────┐ │
|
|
307
|
-
│ │ Slack Integration (separate process) │ │
|
|
308
|
-
│ │ - Creates tasks on mentions │ │
|
|
309
|
-
│ │ - Does NOT notify running agents directly │ │
|
|
310
|
-
│ │ - Agents must poll to discover new tasks │ │
|
|
311
|
-
│ └──────────────────────────────────────────────────┘ │
|
|
312
|
-
│ │
|
|
313
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
## Code References
|
|
317
|
-
|
|
318
|
-
- `src/commands/runner.ts:208` - Main while loop
|
|
319
|
-
- `src/commands/runner.ts:57-136` - `runClaudeIteration()` function
|
|
320
|
-
- `src/commands/runner.ts:85` - `Bun.spawn()` call
|
|
321
|
-
- `src/commands/lead.ts:6-11` - Lead configuration
|
|
322
|
-
- `src/commands/worker.ts:6-11` - Worker configuration
|
|
323
|
-
- `src/tools/poll-task.ts:16-17` - Polling constants
|
|
324
|
-
- `src/tools/poll-task.ts:83-104` - Offered tasks check
|
|
325
|
-
- `src/tools/poll-task.ts:107-162` - Polling loop
|
|
326
|
-
- `src/slack/handlers.ts:140-273` - Message handler
|
|
327
|
-
- `src/slack/handlers.ts:231-237` - Task creation
|
|
328
|
-
- `src/slack/router.ts:77-155` - `routeMessage()` function
|
|
329
|
-
- `src/slack/router.ts:138-144` - Thread follow-up routing
|
|
330
|
-
- `src/be/db.ts:732-747` - `getAgentWorkingOnThread()`
|
|
331
|
-
- `src/hooks/hook.ts:56-290` - Hook handler
|
|
332
|
-
|
|
333
|
-
## Current Spawn Triggers Summary
|
|
334
|
-
|
|
335
|
-
### Lead Agent (Current)
|
|
336
|
-
| Trigger | Creates Task? | Spawns Agent? |
|
|
337
|
-
|---------|---------------|---------------|
|
|
338
|
-
| CLI invocation | No | Yes (runs forever) |
|
|
339
|
-
| @bot mention in Slack | Yes | No (already running) |
|
|
340
|
-
| Agent finished a task | N/A | No (already running) |
|
|
341
|
-
|
|
342
|
-
### Worker Agent (Current)
|
|
343
|
-
| Trigger | Creates Task? | Spawns Agent? |
|
|
344
|
-
|---------|---------------|---------------|
|
|
345
|
-
| CLI invocation | No | Yes (runs forever) |
|
|
346
|
-
| `swarm#<uuid>` in Slack | Yes | No (already running) |
|
|
347
|
-
| `swarm#all` in Slack | Yes | No (already running) |
|
|
348
|
-
| Agent name match in Slack | Yes | No (already running) |
|
|
349
|
-
| Thread follow-up | Yes | No (already running) |
|
|
350
|
-
| `send-task` from lead | Yes | No (already running) |
|
|
351
|
-
| Offered task (poll-task returns) | No (exists) | N/A |
|
|
352
|
-
|
|
353
|
-
### Slack Thread Behavior
|
|
354
|
-
| Scenario | Task Created? |
|
|
355
|
-
|----------|---------------|
|
|
356
|
-
| @bot mention in new message | Yes (to lead) |
|
|
357
|
-
| @bot mention in thread | Yes (to lead or working agent) |
|
|
358
|
-
| Agent name in thread | Yes (to matched agent) |
|
|
359
|
-
| `swarm#<uuid>` in thread | Yes (to specified agent) |
|
|
360
|
-
| Reply in thread WITHOUT @mention | **No** |
|
|
361
|
-
| Reply in thread to agent working on it | **No** (unless @mention or name match) |
|
|
362
|
-
|
|
363
|
-
## Proposed Architecture: Runner-Level Polling
|
|
364
|
-
|
|
365
|
-
### Design Decisions
|
|
366
|
-
|
|
367
|
-
Based on discussion, the following decisions have been made:
|
|
368
|
-
|
|
369
|
-
1. **Thread reply detection**: Will need to subscribe to all thread messages in Slack, not just mentions. This is a Slack configuration change.
|
|
370
|
-
|
|
371
|
-
2. **Agent process lifecycle**: Polling should happen **at the runner level** (TypeScript), not inside Claude:
|
|
372
|
-
- Wait for something with a timeout
|
|
373
|
-
- If nothing, wait a bit and repeat
|
|
374
|
-
- If got something, spawn Claude to process it and repeat
|
|
375
|
-
|
|
376
|
-
3. **MCP session persistence**: Each spawn will be a new session. Remove the `SESSION_ID` parameter for now.
|
|
377
|
-
|
|
378
|
-
4. **Offered task acceptance**: Spawn Claude with a prompt like:
|
|
379
|
-
> "Hey there's task <id>, check it out and accept it if you think it's good for your skills"
|
|
380
|
-
|
|
381
|
-
5. **Configuration**: The approach should be **opt-in** via `--ai-loop` flag:
|
|
382
|
-
- Default (new): Runner-level polling, spawn on-demand
|
|
383
|
-
- `--ai-loop`: Current behavior (AI-based polling inside Claude)
|
|
384
|
-
|
|
385
|
-
### Proposed Runner Flow (Pseudocode)
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
// src/commands/runner.ts - proposed changes
|
|
389
|
-
|
|
390
|
-
export async function runAgent(config: RunnerConfig, opts: RunnerOptions) {
|
|
391
|
-
const { role } = config;
|
|
392
|
-
const swarmUrl = process.env.SWARM_URL || 'http://localhost:3013';
|
|
393
|
-
const apiKey = process.env.API_KEY || '';
|
|
394
|
-
const agentId = process.env.AGENT_ID || crypto.randomUUID();
|
|
395
|
-
|
|
396
|
-
// Step 1: Register agent via API (before polling)
|
|
397
|
-
const agent = await registerAgent(swarmUrl, apiKey, {
|
|
398
|
-
id: agentId,
|
|
399
|
-
name: opts.name || `${role}-${agentId.slice(0, 8)}`,
|
|
400
|
-
isLead: role === 'lead',
|
|
401
|
-
capabilities: config.capabilities,
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
console.log(`[${role}] Registered as "${agent.name}" (ID: ${agent.id})`);
|
|
405
|
-
|
|
406
|
-
while (true) {
|
|
407
|
-
if (opts.aiLoop) {
|
|
408
|
-
// Current behavior: spawn Claude immediately with /start-* prompt
|
|
409
|
-
await runClaudeIteration({ prompt: config.defaultPrompt });
|
|
410
|
-
} else {
|
|
411
|
-
// New behavior: poll at runner level via API
|
|
412
|
-
const trigger = await pollForTrigger(swarmUrl, apiKey, agentId, {
|
|
413
|
-
timeout: POLL_TIMEOUT_MS, // e.g., 60000 (1 min)
|
|
414
|
-
checkInterval: POLL_INTERVAL_MS, // e.g., 2000 (2 sec)
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
if (trigger) {
|
|
418
|
-
// Spawn Claude with specific prompt based on trigger type
|
|
419
|
-
const prompt = buildPromptForTrigger(trigger);
|
|
420
|
-
await runClaudeIteration({ prompt });
|
|
421
|
-
}
|
|
422
|
-
// If no trigger (timeout), loop continues (wait and repeat)
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// API call to register agent
|
|
428
|
-
async function registerAgent(swarmUrl: string, apiKey: string, opts: RegisterOpts): Promise<Agent> {
|
|
429
|
-
const response = await fetch(`${swarmUrl}/api/agents`, {
|
|
430
|
-
method: 'POST',
|
|
431
|
-
headers: {
|
|
432
|
-
'Content-Type': 'application/json',
|
|
433
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
434
|
-
'X-Agent-ID': opts.id,
|
|
435
|
-
},
|
|
436
|
-
body: JSON.stringify(opts),
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
if (!response.ok) {
|
|
440
|
-
// Handle already-registered case (409 Conflict) - fetch existing
|
|
441
|
-
if (response.status === 409) {
|
|
442
|
-
const existing = await fetch(`${swarmUrl}/me`, {
|
|
443
|
-
headers: { 'Authorization': `Bearer ${apiKey}`, 'X-Agent-ID': opts.id },
|
|
444
|
-
});
|
|
445
|
-
return existing.json();
|
|
446
|
-
}
|
|
447
|
-
throw new Error(`Failed to register: ${response.statusText}`);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
return response.json();
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// API call to poll for triggers
|
|
454
|
-
async function pollForTrigger(
|
|
455
|
-
swarmUrl: string,
|
|
456
|
-
apiKey: string,
|
|
457
|
-
opts: PollOpts
|
|
458
|
-
): Promise<Trigger | null> {
|
|
459
|
-
const startTime = Date.now();
|
|
460
|
-
|
|
461
|
-
while (Date.now() - startTime < opts.timeout) {
|
|
462
|
-
const response = await fetch(`${swarmUrl}/api/poll?agentId=${opts.id}`, {
|
|
463
|
-
headers: { 'Authorization': `Bearer ${apiKey}`, 'X-Agent-ID': opts.id },
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
const data = await response.json();
|
|
467
|
-
|
|
468
|
-
if (data.trigger) {
|
|
469
|
-
return data.trigger; // { type: 'task_assigned', taskId: '...' }
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
await Bun.sleep(opts.checkInterval);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
return null; // Timeout, no trigger
|
|
476
|
-
}
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
### Trigger Types and Prompts
|
|
480
|
-
|
|
481
|
-
| Trigger Type | Prompt | Command |
|
|
482
|
-
|--------------|--------|---------|
|
|
483
|
-
| Task assigned (pending) | "Work on task `<id>`" | `/work-on-task <id>` |
|
|
484
|
-
| Task offered | "Task `<id>` offered, check if it fits your skills" | (new command?) |
|
|
485
|
-
| Unread @mention | "You have unread mentions, check messages" | `/swarm-chat` |
|
|
486
|
-
| Agent finished task (lead) | "Worker completed task `<id>`, review results" | (custom) |
|
|
487
|
-
|
|
488
|
-
### Lead Agent Triggers (Proposed)
|
|
489
|
-
|
|
490
|
-
| Trigger | Creates Task? | Spawns Agent? |
|
|
491
|
-
|---------|---------------|---------------|
|
|
492
|
-
| @bot mention in Slack | Yes | **Yes** |
|
|
493
|
-
| Follow-up in thread (any message) | Yes | **Yes** |
|
|
494
|
-
| Direct task assignment | Yes | **Yes** |
|
|
495
|
-
| Any agent finished a task | No | **Yes** (to review) |
|
|
496
|
-
| Unread @mention in channels | No | **Yes** |
|
|
497
|
-
|
|
498
|
-
### Worker Agent Triggers (Proposed)
|
|
499
|
-
|
|
500
|
-
| Trigger | Creates Task? | Spawns Agent? |
|
|
501
|
-
|---------|---------------|---------------|
|
|
502
|
-
| Task assigned to them | Yes (already exists) | **Yes** |
|
|
503
|
-
| Task offered to them | Yes (already exists) | **Yes** (to accept/reject) |
|
|
504
|
-
| Direct mention in swarm chat | No | **Yes** |
|
|
505
|
-
|
|
506
|
-
### Critical: API-Based Architecture
|
|
507
|
-
|
|
508
|
-
The runner **cannot access the database directly** - the DB runs in the API service (could be different infrastructure). The runner must use HTTP API calls.
|
|
509
|
-
|
|
510
|
-
**Current API Endpoints** (`src/http.ts`):
|
|
511
|
-
| Endpoint | Method | Purpose |
|
|
512
|
-
|----------|--------|---------|
|
|
513
|
-
| `/me` | GET | Get agent info (requires `X-Agent-ID` header) |
|
|
514
|
-
| `/ping` | POST | Update agent status to idle/busy |
|
|
515
|
-
| `/close` | POST | Mark agent offline |
|
|
516
|
-
| `/api/agents` | GET | List all agents |
|
|
517
|
-
| `/api/tasks` | GET | List tasks with filters |
|
|
518
|
-
| `/api/tasks/:id` | GET | Get task details |
|
|
519
|
-
|
|
520
|
-
**Missing API Endpoints (Need to Add)**:
|
|
521
|
-
| Endpoint | Method | Purpose |
|
|
522
|
-
|----------|--------|---------|
|
|
523
|
-
| `/api/agents` | POST | Register an agent (equivalent to `join-swarm` MCP tool) |
|
|
524
|
-
| `/api/poll` | GET | Poll for triggers (tasks, mentions, etc.) |
|
|
525
|
-
|
|
526
|
-
**Agent Registration Flow (New)**:
|
|
527
|
-
```typescript
|
|
528
|
-
// Runner must register BEFORE polling
|
|
529
|
-
const response = await fetch(`${swarmUrl}/api/agents`, {
|
|
530
|
-
method: 'POST',
|
|
531
|
-
headers: { 'Authorization': `Bearer ${apiKey}`, 'X-Agent-ID': agentId },
|
|
532
|
-
body: JSON.stringify({
|
|
533
|
-
name: agentName,
|
|
534
|
-
isLead: role === 'lead',
|
|
535
|
-
capabilities: config.capabilities,
|
|
536
|
-
}),
|
|
537
|
-
});
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
**Polling Flow (New)**:
|
|
541
|
-
```typescript
|
|
542
|
-
// Poll for triggers via API
|
|
543
|
-
const response = await fetch(`${swarmUrl}/api/poll`, {
|
|
544
|
-
method: 'GET',
|
|
545
|
-
headers: { 'Authorization': `Bearer ${apiKey}`, 'X-Agent-ID': agentId },
|
|
546
|
-
});
|
|
547
|
-
const trigger = await response.json();
|
|
548
|
-
// trigger: { type: 'task_assigned', taskId: '...' } | null
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
**Types Reuse**: Types from `src/types.ts` (`AgentSchema`, `AgentTaskSchema`, etc.) can be reused in the runner since they're in the same codebase.
|
|
552
|
-
|
|
553
|
-
### Files to Modify
|
|
554
|
-
|
|
555
|
-
1. **`src/http.ts`** (NEW)
|
|
556
|
-
- Add `POST /api/agents` - Agent registration endpoint
|
|
557
|
-
- Add `GET /api/poll` - Trigger polling endpoint
|
|
558
|
-
|
|
559
|
-
2. **`src/commands/runner.ts`**
|
|
560
|
-
- Add `--ai-loop` flag handling
|
|
561
|
-
- Add `pollForTrigger()` function (calls `GET /api/poll`)
|
|
562
|
-
- Add `registerAgent()` function (calls `POST /api/agents`)
|
|
563
|
-
- Add `buildPromptForTrigger()` function
|
|
564
|
-
- Remove `SESSION_ID` usage
|
|
565
|
-
|
|
566
|
-
3. **`src/commands/lead.ts` / `src/commands/worker.ts`**
|
|
567
|
-
- Pass `aiLoop` config option
|
|
568
|
-
|
|
569
|
-
4. **`src/cli.tsx`**
|
|
570
|
-
- Add `--ai-loop` CLI flag
|
|
571
|
-
|
|
572
|
-
5. **`plugin/commands/work-on-task.md`**
|
|
573
|
-
- Consider reuse for lead (or create `/lead-work-on-task`)
|
|
574
|
-
|
|
575
|
-
6. **`src/slack/handlers.ts`** (future)
|
|
576
|
-
- Subscribe to all thread messages, not just mentions
|
|
577
|
-
|
|
578
|
-
### Open Questions (Remaining)
|
|
579
|
-
|
|
580
|
-
1. **Lead work-on-task**: Should we reuse `/work-on-task` for lead, or create a separate `/lead-work-on-task` command? Reuse preferred if possible.
|
|
581
|
-
|
|
582
|
-
2. **Slack thread subscription**: Need to investigate Slack API for subscribing to all messages in threads where bot is active (not just mentions).
|