@oni.bot/core 0.6.3 → 1.0.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/CHANGELOG.md +126 -0
- package/README.md +64 -263
- package/SECURITY.md +71 -0
- package/dist/checkpointers/sqlite.d.ts.map +1 -1
- package/dist/checkpointers/sqlite.js +42 -25
- package/dist/checkpointers/sqlite.js.map +1 -1
- package/dist/circuit-breaker.d.ts +20 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +58 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/cli/build.d.ts +11 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +61 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/dev.d.ts +5 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/dev.js +54 -0
- package/dist/cli/dev.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +21 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +4 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +34 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/inspect.d.ts +5 -0
- package/dist/cli/inspect.d.ts.map +1 -0
- package/dist/cli/inspect.js +85 -0
- package/dist/cli/inspect.js.map +1 -0
- package/dist/cli/router.d.ts +14 -0
- package/dist/cli/router.d.ts.map +1 -0
- package/dist/cli/router.js +107 -0
- package/dist/cli/router.js.map +1 -0
- package/dist/cli/run.d.ts +5 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +53 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/templates.d.ts +9 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +159 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/test.d.ts +3 -0
- package/dist/cli/test.d.ts.map +1 -0
- package/dist/cli/test.js +29 -0
- package/dist/cli/test.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +37 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +180 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +74 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +5 -0
- package/dist/config/types.js.map +1 -0
- package/dist/coordination/pubsub.d.ts +4 -0
- package/dist/coordination/pubsub.d.ts.map +1 -1
- package/dist/coordination/pubsub.js +8 -0
- package/dist/coordination/pubsub.js.map +1 -1
- package/dist/coordination/request-reply.d.ts +3 -1
- package/dist/coordination/request-reply.d.ts.map +1 -1
- package/dist/coordination/request-reply.js +11 -2
- package/dist/coordination/request-reply.js.map +1 -1
- package/dist/dlq.d.ts +17 -0
- package/dist/dlq.d.ts.map +1 -0
- package/dist/dlq.js +41 -0
- package/dist/dlq.js.map +1 -0
- package/dist/errors.d.ts +43 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +179 -8
- package/dist/errors.js.map +1 -1
- package/dist/events/bridge.d.ts +17 -0
- package/dist/events/bridge.d.ts.map +1 -0
- package/dist/events/bridge.js +67 -0
- package/dist/events/bridge.js.map +1 -0
- package/dist/events/bus.d.ts +9 -0
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/events/bus.js +39 -4
- package/dist/events/bus.js.map +1 -1
- package/dist/events/index.d.ts +2 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +2 -0
- package/dist/events/index.js.map +1 -1
- package/dist/events/types.d.ts +123 -1
- package/dist/events/types.d.ts.map +1 -1
- package/dist/graph.d.ts +17 -0
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +29 -10
- package/dist/graph.js.map +1 -1
- package/dist/guardrails/types.d.ts +1 -1
- package/dist/guardrails/types.d.ts.map +1 -1
- package/dist/harness/agent-loop.d.ts +8 -0
- package/dist/harness/agent-loop.d.ts.map +1 -0
- package/dist/harness/agent-loop.js +524 -0
- package/dist/harness/agent-loop.js.map +1 -0
- package/dist/harness/context-compactor.d.ts +92 -0
- package/dist/harness/context-compactor.d.ts.map +1 -0
- package/dist/harness/context-compactor.js +201 -0
- package/dist/harness/context-compactor.js.map +1 -0
- package/dist/harness/harness.d.ts +41 -0
- package/dist/harness/harness.d.ts.map +1 -0
- package/dist/harness/harness.js +140 -0
- package/dist/harness/harness.js.map +1 -0
- package/dist/harness/hooks-engine.d.ts +77 -0
- package/dist/harness/hooks-engine.d.ts.map +1 -0
- package/dist/harness/hooks-engine.js +232 -0
- package/dist/harness/hooks-engine.js.map +1 -0
- package/dist/harness/index.d.ts +17 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +21 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/safety-gate.d.ts +29 -0
- package/dist/harness/safety-gate.d.ts.map +1 -0
- package/dist/harness/safety-gate.js +72 -0
- package/dist/harness/safety-gate.js.map +1 -0
- package/dist/harness/skill-loader.d.ts +76 -0
- package/dist/harness/skill-loader.d.ts.map +1 -0
- package/dist/harness/skill-loader.js +244 -0
- package/dist/harness/skill-loader.js.map +1 -0
- package/dist/harness/todo-module.d.ts +39 -0
- package/dist/harness/todo-module.d.ts.map +1 -0
- package/dist/harness/todo-module.js +179 -0
- package/dist/harness/todo-module.js.map +1 -0
- package/dist/harness/types.d.ts +100 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +9 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/harness/validate-args.d.ts +16 -0
- package/dist/harness/validate-args.d.ts.map +1 -0
- package/dist/harness/validate-args.js +132 -0
- package/dist/harness/validate-args.js.map +1 -0
- package/dist/hitl/interrupt.d.ts.map +1 -1
- package/dist/hitl/interrupt.js +7 -6
- package/dist/hitl/interrupt.js.map +1 -1
- package/dist/index.d.ts +16 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -13
- package/dist/index.js.map +1 -1
- package/dist/internal/timeout.d.ts +2 -0
- package/dist/internal/timeout.d.ts.map +1 -0
- package/dist/internal/timeout.js +16 -0
- package/dist/internal/timeout.js.map +1 -0
- package/dist/lsp/client.d.ts +70 -0
- package/dist/lsp/client.d.ts.map +1 -0
- package/dist/lsp/client.js +421 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/lsp/index.d.ts +77 -0
- package/dist/lsp/index.d.ts.map +1 -0
- package/dist/lsp/index.js +183 -0
- package/dist/lsp/index.js.map +1 -0
- package/dist/lsp/servers.d.ts +48 -0
- package/dist/lsp/servers.d.ts.map +1 -0
- package/dist/lsp/servers.js +108 -0
- package/dist/lsp/servers.js.map +1 -0
- package/dist/lsp/types.d.ts +142 -0
- package/dist/lsp/types.d.ts.map +1 -0
- package/dist/lsp/types.js +16 -0
- package/dist/lsp/types.js.map +1 -0
- package/dist/mcp/client.d.ts +56 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +170 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/convert.d.ts +26 -0
- package/dist/mcp/convert.d.ts.map +1 -0
- package/dist/mcp/convert.js +56 -0
- package/dist/mcp/convert.js.map +1 -0
- package/dist/mcp/index.d.ts +21 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +19 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/transport.d.ts +56 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +204 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/mcp/types.d.ts +96 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +11 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/models/anthropic.d.ts.map +1 -1
- package/dist/models/anthropic.js +78 -41
- package/dist/models/anthropic.js.map +1 -1
- package/dist/models/google.d.ts.map +1 -1
- package/dist/models/google.js +54 -52
- package/dist/models/google.js.map +1 -1
- package/dist/models/http-error.d.ts +16 -0
- package/dist/models/http-error.d.ts.map +1 -0
- package/dist/models/http-error.js +67 -0
- package/dist/models/http-error.js.map +1 -0
- package/dist/models/index.d.ts +5 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +3 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/ollama.d.ts.map +1 -1
- package/dist/models/ollama.js +4 -3
- package/dist/models/ollama.js.map +1 -1
- package/dist/models/openai.d.ts.map +1 -1
- package/dist/models/openai.js +42 -45
- package/dist/models/openai.js.map +1 -1
- package/dist/models/openrouter.d.ts +26 -0
- package/dist/models/openrouter.d.ts.map +1 -0
- package/dist/models/openrouter.js +361 -0
- package/dist/models/openrouter.js.map +1 -0
- package/dist/models/sse.d.ts +9 -0
- package/dist/models/sse.d.ts.map +1 -0
- package/dist/models/sse.js +45 -0
- package/dist/models/sse.js.map +1 -0
- package/dist/models/types.d.ts +10 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/oni-code/agent-registry.d.ts +73 -0
- package/dist/oni-code/agent-registry.d.ts.map +1 -0
- package/dist/oni-code/agent-registry.js +151 -0
- package/dist/oni-code/agent-registry.js.map +1 -0
- package/dist/oni-code/bin.d.ts +18 -0
- package/dist/oni-code/bin.d.ts.map +1 -0
- package/dist/oni-code/bin.js +78 -0
- package/dist/oni-code/bin.js.map +1 -0
- package/dist/oni-code/change-tracking.d.ts +28 -0
- package/dist/oni-code/change-tracking.d.ts.map +1 -0
- package/dist/oni-code/change-tracking.js +77 -0
- package/dist/oni-code/change-tracking.js.map +1 -0
- package/dist/oni-code/cli.d.ts +6 -0
- package/dist/oni-code/cli.d.ts.map +1 -0
- package/dist/oni-code/cli.js +30 -0
- package/dist/oni-code/cli.js.map +1 -0
- package/dist/oni-code/conductor.d.ts +203 -0
- package/dist/oni-code/conductor.d.ts.map +1 -0
- package/dist/oni-code/conductor.js +1547 -0
- package/dist/oni-code/conductor.js.map +1 -0
- package/dist/oni-code/config.d.ts +130 -0
- package/dist/oni-code/config.d.ts.map +1 -0
- package/dist/oni-code/config.js +264 -0
- package/dist/oni-code/config.js.map +1 -0
- package/dist/oni-code/context-files.d.ts +22 -0
- package/dist/oni-code/context-files.d.ts.map +1 -0
- package/dist/oni-code/context-files.js +156 -0
- package/dist/oni-code/context-files.js.map +1 -0
- package/dist/oni-code/cron/humanize.d.ts +26 -0
- package/dist/oni-code/cron/humanize.d.ts.map +1 -0
- package/dist/oni-code/cron/humanize.js +83 -0
- package/dist/oni-code/cron/humanize.js.map +1 -0
- package/dist/oni-code/cron/index.d.ts +10 -0
- package/dist/oni-code/cron/index.d.ts.map +1 -0
- package/dist/oni-code/cron/index.js +7 -0
- package/dist/oni-code/cron/index.js.map +1 -0
- package/dist/oni-code/cron/matcher.d.ts +29 -0
- package/dist/oni-code/cron/matcher.d.ts.map +1 -0
- package/dist/oni-code/cron/matcher.js +73 -0
- package/dist/oni-code/cron/matcher.js.map +1 -0
- package/dist/oni-code/cron/parser.d.ts +27 -0
- package/dist/oni-code/cron/parser.d.ts.map +1 -0
- package/dist/oni-code/cron/parser.js +149 -0
- package/dist/oni-code/cron/parser.js.map +1 -0
- package/dist/oni-code/cron/persistence.d.ts +21 -0
- package/dist/oni-code/cron/persistence.d.ts.map +1 -0
- package/dist/oni-code/cron/persistence.js +58 -0
- package/dist/oni-code/cron/persistence.js.map +1 -0
- package/dist/oni-code/cron/scheduler.d.ts +64 -0
- package/dist/oni-code/cron/scheduler.d.ts.map +1 -0
- package/dist/oni-code/cron/scheduler.js +188 -0
- package/dist/oni-code/cron/scheduler.js.map +1 -0
- package/dist/oni-code/cron/store.d.ts +46 -0
- package/dist/oni-code/cron/store.d.ts.map +1 -0
- package/dist/oni-code/cron/store.js +68 -0
- package/dist/oni-code/cron/store.js.map +1 -0
- package/dist/oni-code/env.d.ts +17 -0
- package/dist/oni-code/env.d.ts.map +1 -0
- package/dist/oni-code/env.js +51 -0
- package/dist/oni-code/env.js.map +1 -0
- package/dist/oni-code/file-reader.d.ts +28 -0
- package/dist/oni-code/file-reader.d.ts.map +1 -0
- package/dist/oni-code/file-reader.js +368 -0
- package/dist/oni-code/file-reader.js.map +1 -0
- package/dist/oni-code/file-watcher.d.ts +66 -0
- package/dist/oni-code/file-watcher.d.ts.map +1 -0
- package/dist/oni-code/file-watcher.js +167 -0
- package/dist/oni-code/file-watcher.js.map +1 -0
- package/dist/oni-code/loop-detector.d.ts +64 -0
- package/dist/oni-code/loop-detector.d.ts.map +1 -0
- package/dist/oni-code/loop-detector.js +163 -0
- package/dist/oni-code/loop-detector.js.map +1 -0
- package/dist/oni-code/permissions.d.ts +43 -0
- package/dist/oni-code/permissions.d.ts.map +1 -0
- package/dist/oni-code/permissions.js +98 -0
- package/dist/oni-code/permissions.js.map +1 -0
- package/dist/oni-code/planner.d.ts +26 -0
- package/dist/oni-code/planner.d.ts.map +1 -0
- package/dist/oni-code/planner.js +86 -0
- package/dist/oni-code/planner.js.map +1 -0
- package/dist/oni-code/plugin-loader.d.ts +103 -0
- package/dist/oni-code/plugin-loader.d.ts.map +1 -0
- package/dist/oni-code/plugin-loader.js +171 -0
- package/dist/oni-code/plugin-loader.js.map +1 -0
- package/dist/oni-code/process-tree.d.ts +44 -0
- package/dist/oni-code/process-tree.d.ts.map +1 -0
- package/dist/oni-code/process-tree.js +107 -0
- package/dist/oni-code/process-tree.js.map +1 -0
- package/dist/oni-code/progress-tracker.d.ts +40 -0
- package/dist/oni-code/progress-tracker.d.ts.map +1 -0
- package/dist/oni-code/progress-tracker.js +375 -0
- package/dist/oni-code/progress-tracker.js.map +1 -0
- package/dist/oni-code/scheduler.d.ts +56 -0
- package/dist/oni-code/scheduler.d.ts.map +1 -0
- package/dist/oni-code/scheduler.js +105 -0
- package/dist/oni-code/scheduler.js.map +1 -0
- package/dist/oni-code/session-fork.d.ts +146 -0
- package/dist/oni-code/session-fork.d.ts.map +1 -0
- package/dist/oni-code/session-fork.js +238 -0
- package/dist/oni-code/session-fork.js.map +1 -0
- package/dist/oni-code/session-stats.d.ts +72 -0
- package/dist/oni-code/session-stats.d.ts.map +1 -0
- package/dist/oni-code/session-stats.js +141 -0
- package/dist/oni-code/session-stats.js.map +1 -0
- package/dist/oni-code/session-title.d.ts +25 -0
- package/dist/oni-code/session-title.d.ts.map +1 -0
- package/dist/oni-code/session-title.js +67 -0
- package/dist/oni-code/session-title.js.map +1 -0
- package/dist/oni-code/shell-parser.d.ts +112 -0
- package/dist/oni-code/shell-parser.d.ts.map +1 -0
- package/dist/oni-code/shell-parser.js +657 -0
- package/dist/oni-code/shell-parser.js.map +1 -0
- package/dist/oni-code/summarizer.d.ts +27 -0
- package/dist/oni-code/summarizer.d.ts.map +1 -0
- package/dist/oni-code/summarizer.js +70 -0
- package/dist/oni-code/summarizer.js.map +1 -0
- package/dist/oni-code/swarm-checkpoint.d.ts +52 -0
- package/dist/oni-code/swarm-checkpoint.d.ts.map +1 -0
- package/dist/oni-code/swarm-checkpoint.js +71 -0
- package/dist/oni-code/swarm-checkpoint.js.map +1 -0
- package/dist/oni-code/swarm-runner.d.ts +173 -0
- package/dist/oni-code/swarm-runner.d.ts.map +1 -0
- package/dist/oni-code/swarm-runner.js +873 -0
- package/dist/oni-code/swarm-runner.js.map +1 -0
- package/dist/oni-code/system-prompt.d.ts +13 -0
- package/dist/oni-code/system-prompt.d.ts.map +1 -0
- package/dist/oni-code/system-prompt.js +64 -0
- package/dist/oni-code/system-prompt.js.map +1 -0
- package/dist/oni-code/task-evaluator.d.ts +73 -0
- package/dist/oni-code/task-evaluator.d.ts.map +1 -0
- package/dist/oni-code/task-evaluator.js +172 -0
- package/dist/oni-code/task-evaluator.js.map +1 -0
- package/dist/oni-code/tools/batch.d.ts +12 -0
- package/dist/oni-code/tools/batch.d.ts.map +1 -0
- package/dist/oni-code/tools/batch.js +116 -0
- package/dist/oni-code/tools/batch.js.map +1 -0
- package/dist/oni-code/tools/coding.d.ts +10 -0
- package/dist/oni-code/tools/coding.d.ts.map +1 -0
- package/dist/oni-code/tools/coding.js +557 -0
- package/dist/oni-code/tools/coding.js.map +1 -0
- package/dist/oni-code/tools/cron.d.ts +4 -0
- package/dist/oni-code/tools/cron.d.ts.map +1 -0
- package/dist/oni-code/tools/cron.js +120 -0
- package/dist/oni-code/tools/cron.js.map +1 -0
- package/dist/oni-code/tools/custom.d.ts +43 -0
- package/dist/oni-code/tools/custom.d.ts.map +1 -0
- package/dist/oni-code/tools/custom.js +115 -0
- package/dist/oni-code/tools/custom.js.map +1 -0
- package/dist/oni-code/tools/patch.d.ts +58 -0
- package/dist/oni-code/tools/patch.d.ts.map +1 -0
- package/dist/oni-code/tools/patch.js +247 -0
- package/dist/oni-code/tools/patch.js.map +1 -0
- package/dist/oni-code/tools/plan.d.ts +17 -0
- package/dist/oni-code/tools/plan.d.ts.map +1 -0
- package/dist/oni-code/tools/plan.js +48 -0
- package/dist/oni-code/tools/plan.js.map +1 -0
- package/dist/oni-code/tools/question.d.ts +17 -0
- package/dist/oni-code/tools/question.d.ts.map +1 -0
- package/dist/oni-code/tools/question.js +46 -0
- package/dist/oni-code/tools/question.js.map +1 -0
- package/dist/oni-code/tools/skill.d.ts +36 -0
- package/dist/oni-code/tools/skill.d.ts.map +1 -0
- package/dist/oni-code/tools/skill.js +132 -0
- package/dist/oni-code/tools/skill.js.map +1 -0
- package/dist/oni-code/tools/spawn-agents.d.ts +37 -0
- package/dist/oni-code/tools/spawn-agents.d.ts.map +1 -0
- package/dist/oni-code/tools/spawn-agents.js +91 -0
- package/dist/oni-code/tools/spawn-agents.js.map +1 -0
- package/dist/oni-code/tools/spawn-swarm.d.ts +70 -0
- package/dist/oni-code/tools/spawn-swarm.d.ts.map +1 -0
- package/dist/oni-code/tools/spawn-swarm.js +129 -0
- package/dist/oni-code/tools/spawn-swarm.js.map +1 -0
- package/dist/oni-code/tools/web.d.ts +11 -0
- package/dist/oni-code/tools/web.d.ts.map +1 -0
- package/dist/oni-code/tools/web.js +375 -0
- package/dist/oni-code/tools/web.js.map +1 -0
- package/dist/oni-code/topology-agent-builder.d.ts +22 -0
- package/dist/oni-code/topology-agent-builder.d.ts.map +1 -0
- package/dist/oni-code/topology-agent-builder.js +220 -0
- package/dist/oni-code/topology-agent-builder.js.map +1 -0
- package/dist/oni-code/topology-selector.d.ts +85 -0
- package/dist/oni-code/topology-selector.d.ts.map +1 -0
- package/dist/oni-code/topology-selector.js +338 -0
- package/dist/oni-code/topology-selector.js.map +1 -0
- package/dist/oni-code/ui/App.d.ts +10 -0
- package/dist/oni-code/ui/App.d.ts.map +1 -0
- package/dist/oni-code/ui/App.js +395 -0
- package/dist/oni-code/ui/App.js.map +1 -0
- package/dist/oni-code/ui/FooterPanel.d.ts +16 -0
- package/dist/oni-code/ui/FooterPanel.d.ts.map +1 -0
- package/dist/oni-code/ui/FooterPanel.js +56 -0
- package/dist/oni-code/ui/FooterPanel.js.map +1 -0
- package/dist/oni-code/ui/Header.d.ts +21 -0
- package/dist/oni-code/ui/Header.d.ts.map +1 -0
- package/dist/oni-code/ui/Header.js +105 -0
- package/dist/oni-code/ui/Header.js.map +1 -0
- package/dist/oni-code/ui/InputArea.d.ts +11 -0
- package/dist/oni-code/ui/InputArea.d.ts.map +1 -0
- package/dist/oni-code/ui/InputArea.js +82 -0
- package/dist/oni-code/ui/InputArea.js.map +1 -0
- package/dist/oni-code/ui/MessageBlock.d.ts +11 -0
- package/dist/oni-code/ui/MessageBlock.d.ts.map +1 -0
- package/dist/oni-code/ui/MessageBlock.js +103 -0
- package/dist/oni-code/ui/MessageBlock.js.map +1 -0
- package/dist/oni-code/ui/OutputPane.d.ts +12 -0
- package/dist/oni-code/ui/OutputPane.d.ts.map +1 -0
- package/dist/oni-code/ui/OutputPane.js +8 -0
- package/dist/oni-code/ui/OutputPane.js.map +1 -0
- package/dist/oni-code/ui/PermissionPrompt.d.ts +11 -0
- package/dist/oni-code/ui/PermissionPrompt.d.ts.map +1 -0
- package/dist/oni-code/ui/PermissionPrompt.js +48 -0
- package/dist/oni-code/ui/PermissionPrompt.js.map +1 -0
- package/dist/oni-code/ui/QuestionPrompt.d.ts +8 -0
- package/dist/oni-code/ui/QuestionPrompt.d.ts.map +1 -0
- package/dist/oni-code/ui/QuestionPrompt.js +9 -0
- package/dist/oni-code/ui/QuestionPrompt.js.map +1 -0
- package/dist/oni-code/ui/StatusLine.d.ts +14 -0
- package/dist/oni-code/ui/StatusLine.d.ts.map +1 -0
- package/dist/oni-code/ui/StatusLine.js +23 -0
- package/dist/oni-code/ui/StatusLine.js.map +1 -0
- package/dist/oni-code/ui/SwarmPanel.d.ts +9 -0
- package/dist/oni-code/ui/SwarmPanel.d.ts.map +1 -0
- package/dist/oni-code/ui/SwarmPanel.js +52 -0
- package/dist/oni-code/ui/SwarmPanel.js.map +1 -0
- package/dist/oni-code/ui/ToolCallBlock.d.ts +10 -0
- package/dist/oni-code/ui/ToolCallBlock.d.ts.map +1 -0
- package/dist/oni-code/ui/ToolCallBlock.js +21 -0
- package/dist/oni-code/ui/ToolCallBlock.js.map +1 -0
- package/dist/oni-code/ui/Toolbar.d.ts +8 -0
- package/dist/oni-code/ui/Toolbar.d.ts.map +1 -0
- package/dist/oni-code/ui/Toolbar.js +11 -0
- package/dist/oni-code/ui/Toolbar.js.map +1 -0
- package/dist/oni-code/ui/WelcomeBanner.d.ts +12 -0
- package/dist/oni-code/ui/WelcomeBanner.d.ts.map +1 -0
- package/dist/oni-code/ui/WelcomeBanner.js +24 -0
- package/dist/oni-code/ui/WelcomeBanner.js.map +1 -0
- package/dist/oni-code/ui/activity.d.ts +15 -0
- package/dist/oni-code/ui/activity.d.ts.map +1 -0
- package/dist/oni-code/ui/activity.js +252 -0
- package/dist/oni-code/ui/activity.js.map +1 -0
- package/dist/oni-code/ui/banner.d.ts +16 -0
- package/dist/oni-code/ui/banner.d.ts.map +1 -0
- package/dist/oni-code/ui/banner.js +132 -0
- package/dist/oni-code/ui/banner.js.map +1 -0
- package/dist/oni-code/ui/command-menu.d.ts +7 -0
- package/dist/oni-code/ui/command-menu.d.ts.map +1 -0
- package/dist/oni-code/ui/command-menu.js +20 -0
- package/dist/oni-code/ui/command-menu.js.map +1 -0
- package/dist/oni-code/ui/diff.d.ts +17 -0
- package/dist/oni-code/ui/diff.d.ts.map +1 -0
- package/dist/oni-code/ui/diff.js +37 -0
- package/dist/oni-code/ui/diff.js.map +1 -0
- package/dist/oni-code/ui/format.d.ts +41 -0
- package/dist/oni-code/ui/format.d.ts.map +1 -0
- package/dist/oni-code/ui/format.js +223 -0
- package/dist/oni-code/ui/format.js.map +1 -0
- package/dist/oni-code/ui/input.d.ts +28 -0
- package/dist/oni-code/ui/input.d.ts.map +1 -0
- package/dist/oni-code/ui/input.js +216 -0
- package/dist/oni-code/ui/input.js.map +1 -0
- package/dist/oni-code/ui/insights.d.ts +39 -0
- package/dist/oni-code/ui/insights.d.ts.map +1 -0
- package/dist/oni-code/ui/insights.js +193 -0
- package/dist/oni-code/ui/insights.js.map +1 -0
- package/dist/oni-code/ui/markdown.d.ts +9 -0
- package/dist/oni-code/ui/markdown.d.ts.map +1 -0
- package/dist/oni-code/ui/markdown.js +44 -0
- package/dist/oni-code/ui/markdown.js.map +1 -0
- package/dist/oni-code/ui/panels.d.ts +39 -0
- package/dist/oni-code/ui/panels.d.ts.map +1 -0
- package/dist/oni-code/ui/panels.js +209 -0
- package/dist/oni-code/ui/panels.js.map +1 -0
- package/dist/oni-code/ui/paste.d.ts +17 -0
- package/dist/oni-code/ui/paste.d.ts.map +1 -0
- package/dist/oni-code/ui/paste.js +45 -0
- package/dist/oni-code/ui/paste.js.map +1 -0
- package/dist/oni-code/ui/raw-spinner.d.ts +37 -0
- package/dist/oni-code/ui/raw-spinner.d.ts.map +1 -0
- package/dist/oni-code/ui/raw-spinner.js +121 -0
- package/dist/oni-code/ui/raw-spinner.js.map +1 -0
- package/dist/oni-code/ui/session.d.ts +44 -0
- package/dist/oni-code/ui/session.d.ts.map +1 -0
- package/dist/oni-code/ui/session.js +93 -0
- package/dist/oni-code/ui/session.js.map +1 -0
- package/dist/oni-code/ui/spinner.d.ts +7 -0
- package/dist/oni-code/ui/spinner.d.ts.map +1 -0
- package/dist/oni-code/ui/spinner.js +20 -0
- package/dist/oni-code/ui/spinner.js.map +1 -0
- package/dist/oni-code/ui/swarm-activity.d.ts +50 -0
- package/dist/oni-code/ui/swarm-activity.d.ts.map +1 -0
- package/dist/oni-code/ui/swarm-activity.js +233 -0
- package/dist/oni-code/ui/swarm-activity.js.map +1 -0
- package/dist/oni-code/ui/terminal-size.d.ts +18 -0
- package/dist/oni-code/ui/terminal-size.d.ts.map +1 -0
- package/dist/oni-code/ui/terminal-size.js +45 -0
- package/dist/oni-code/ui/terminal-size.js.map +1 -0
- package/dist/oni-code/ui/theme.d.ts +82 -0
- package/dist/oni-code/ui/theme.d.ts.map +1 -0
- package/dist/oni-code/ui/theme.js +101 -0
- package/dist/oni-code/ui/theme.js.map +1 -0
- package/dist/oni-code/ui/tool-utils.d.ts +10 -0
- package/dist/oni-code/ui/tool-utils.d.ts.map +1 -0
- package/dist/oni-code/ui/tool-utils.js +82 -0
- package/dist/oni-code/ui/tool-utils.js.map +1 -0
- package/dist/oni-code/ui/useTerminalSize.d.ts +3 -0
- package/dist/oni-code/ui/useTerminalSize.d.ts.map +1 -0
- package/dist/oni-code/ui/useTerminalSize.js +16 -0
- package/dist/oni-code/ui/useTerminalSize.js.map +1 -0
- package/dist/oni-code/workspace/change-tracker.d.ts +18 -0
- package/dist/oni-code/workspace/change-tracker.d.ts.map +1 -0
- package/dist/oni-code/workspace/change-tracker.js +67 -0
- package/dist/oni-code/workspace/change-tracker.js.map +1 -0
- package/dist/oni-code/workspace/conflict-detector.d.ts +12 -0
- package/dist/oni-code/workspace/conflict-detector.d.ts.map +1 -0
- package/dist/oni-code/workspace/conflict-detector.js +24 -0
- package/dist/oni-code/workspace/conflict-detector.js.map +1 -0
- package/dist/oni-code/workspace/file-snapshots.d.ts +39 -0
- package/dist/oni-code/workspace/file-snapshots.d.ts.map +1 -0
- package/dist/oni-code/workspace/file-snapshots.js +77 -0
- package/dist/oni-code/workspace/file-snapshots.js.map +1 -0
- package/dist/oni-code/workspace/index.d.ts +5 -0
- package/dist/oni-code/workspace/index.d.ts.map +1 -0
- package/dist/oni-code/workspace/index.js +5 -0
- package/dist/oni-code/workspace/index.js.map +1 -0
- package/dist/oni-code/workspace/project-map.d.ts +14 -0
- package/dist/oni-code/workspace/project-map.d.ts.map +1 -0
- package/dist/oni-code/workspace/project-map.js +91 -0
- package/dist/oni-code/workspace/project-map.js.map +1 -0
- package/dist/prebuilt/tool-node.d.ts.map +1 -1
- package/dist/prebuilt/tool-node.js +0 -1
- package/dist/prebuilt/tool-node.js.map +1 -1
- package/dist/pregel.d.ts +15 -1
- package/dist/pregel.d.ts.map +1 -1
- package/dist/pregel.js +199 -51
- package/dist/pregel.js.map +1 -1
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +16 -4
- package/dist/retry.js.map +1 -1
- package/dist/sentinel/config/index.d.ts +2 -0
- package/dist/sentinel/config/index.d.ts.map +1 -0
- package/dist/sentinel/config/index.js +2 -0
- package/dist/sentinel/config/index.js.map +1 -0
- package/dist/sentinel/config/schema.d.ts +4 -0
- package/dist/sentinel/config/schema.d.ts.map +1 -0
- package/dist/sentinel/config/schema.js +42 -0
- package/dist/sentinel/config/schema.js.map +1 -0
- package/dist/sentinel/debate/index.d.ts +6 -0
- package/dist/sentinel/debate/index.d.ts.map +1 -0
- package/dist/sentinel/debate/index.js +64 -0
- package/dist/sentinel/debate/index.js.map +1 -0
- package/dist/sentinel/debate/prompts.d.ts +4 -0
- package/dist/sentinel/debate/prompts.d.ts.map +1 -0
- package/dist/sentinel/debate/prompts.js +13 -0
- package/dist/sentinel/debate/prompts.js.map +1 -0
- package/dist/sentinel/fix/index.d.ts +6 -0
- package/dist/sentinel/fix/index.d.ts.map +1 -0
- package/dist/sentinel/fix/index.js +27 -0
- package/dist/sentinel/fix/index.js.map +1 -0
- package/dist/sentinel/fix/strategies.d.ts +9 -0
- package/dist/sentinel/fix/strategies.d.ts.map +1 -0
- package/dist/sentinel/fix/strategies.js +40 -0
- package/dist/sentinel/fix/strategies.js.map +1 -0
- package/dist/sentinel/index.d.ts +14 -0
- package/dist/sentinel/index.d.ts.map +1 -0
- package/dist/sentinel/index.js +22 -0
- package/dist/sentinel/index.js.map +1 -0
- package/dist/sentinel/integrations/cli.d.ts +10 -0
- package/dist/sentinel/integrations/cli.d.ts.map +1 -0
- package/dist/sentinel/integrations/cli.js +24 -0
- package/dist/sentinel/integrations/cli.js.map +1 -0
- package/dist/sentinel/integrations/index.d.ts +2 -0
- package/dist/sentinel/integrations/index.d.ts.map +1 -0
- package/dist/sentinel/integrations/index.js +2 -0
- package/dist/sentinel/integrations/index.js.map +1 -0
- package/dist/sentinel/memory/index.d.ts +16 -0
- package/dist/sentinel/memory/index.d.ts.map +1 -0
- package/dist/sentinel/memory/index.js +60 -0
- package/dist/sentinel/memory/index.js.map +1 -0
- package/dist/sentinel/report/console.d.ts +3 -0
- package/dist/sentinel/report/console.d.ts.map +1 -0
- package/dist/sentinel/report/console.js +27 -0
- package/dist/sentinel/report/console.js.map +1 -0
- package/dist/sentinel/report/github.d.ts +3 -0
- package/dist/sentinel/report/github.d.ts.map +1 -0
- package/dist/sentinel/report/github.js +36 -0
- package/dist/sentinel/report/github.js.map +1 -0
- package/dist/sentinel/report/index.d.ts +6 -0
- package/dist/sentinel/report/index.d.ts.map +1 -0
- package/dist/sentinel/report/index.js +15 -0
- package/dist/sentinel/report/index.js.map +1 -0
- package/dist/sentinel/report/sarif.d.ts +3 -0
- package/dist/sentinel/report/sarif.d.ts.map +1 -0
- package/dist/sentinel/report/sarif.js +29 -0
- package/dist/sentinel/report/sarif.js.map +1 -0
- package/dist/sentinel/sentinel.d.ts +17 -0
- package/dist/sentinel/sentinel.d.ts.map +1 -0
- package/dist/sentinel/sentinel.js +111 -0
- package/dist/sentinel/sentinel.js.map +1 -0
- package/dist/sentinel/swarm/agents.d.ts +6 -0
- package/dist/sentinel/swarm/agents.d.ts.map +1 -0
- package/dist/sentinel/swarm/agents.js +36 -0
- package/dist/sentinel/swarm/agents.js.map +1 -0
- package/dist/sentinel/swarm/index.d.ts +8 -0
- package/dist/sentinel/swarm/index.d.ts.map +1 -0
- package/dist/sentinel/swarm/index.js +74 -0
- package/dist/sentinel/swarm/index.js.map +1 -0
- package/dist/sentinel/swarm/prompts.d.ts +2 -0
- package/dist/sentinel/swarm/prompts.d.ts.map +1 -0
- package/dist/sentinel/swarm/prompts.js +24 -0
- package/dist/sentinel/swarm/prompts.js.map +1 -0
- package/dist/sentinel/swarm/topology.d.ts +10 -0
- package/dist/sentinel/swarm/topology.d.ts.map +1 -0
- package/dist/sentinel/swarm/topology.js +38 -0
- package/dist/sentinel/swarm/topology.js.map +1 -0
- package/dist/sentinel/triage/analyzers/complexity-analyzer.d.ts +7 -0
- package/dist/sentinel/triage/analyzers/complexity-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/complexity-analyzer.js +94 -0
- package/dist/sentinel/triage/analyzers/complexity-analyzer.js.map +1 -0
- package/dist/sentinel/triage/analyzers/custom-analyzer.d.ts +19 -0
- package/dist/sentinel/triage/analyzers/custom-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/custom-analyzer.js +268 -0
- package/dist/sentinel/triage/analyzers/custom-analyzer.js.map +1 -0
- package/dist/sentinel/triage/analyzers/dependency-analyzer.d.ts +26 -0
- package/dist/sentinel/triage/analyzers/dependency-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/dependency-analyzer.js +220 -0
- package/dist/sentinel/triage/analyzers/dependency-analyzer.js.map +1 -0
- package/dist/sentinel/triage/analyzers/diff-analyzer.d.ts +12 -0
- package/dist/sentinel/triage/analyzers/diff-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/diff-analyzer.js +19 -0
- package/dist/sentinel/triage/analyzers/diff-analyzer.js.map +1 -0
- package/dist/sentinel/triage/analyzers/index.d.ts +14 -0
- package/dist/sentinel/triage/analyzers/index.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/index.js +25 -0
- package/dist/sentinel/triage/analyzers/index.js.map +1 -0
- package/dist/sentinel/triage/analyzers/pattern-analyzer.d.ts +7 -0
- package/dist/sentinel/triage/analyzers/pattern-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/pattern-analyzer.js +180 -0
- package/dist/sentinel/triage/analyzers/pattern-analyzer.js.map +1 -0
- package/dist/sentinel/triage/analyzers/security-analyzer.d.ts +7 -0
- package/dist/sentinel/triage/analyzers/security-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/security-analyzer.js +96 -0
- package/dist/sentinel/triage/analyzers/security-analyzer.js.map +1 -0
- package/dist/sentinel/triage/analyzers/ts-parser.d.ts +71 -0
- package/dist/sentinel/triage/analyzers/ts-parser.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/ts-parser.js +323 -0
- package/dist/sentinel/triage/analyzers/ts-parser.js.map +1 -0
- package/dist/sentinel/triage/analyzers/typescript-analyzer.d.ts +7 -0
- package/dist/sentinel/triage/analyzers/typescript-analyzer.d.ts.map +1 -0
- package/dist/sentinel/triage/analyzers/typescript-analyzer.js +68 -0
- package/dist/sentinel/triage/analyzers/typescript-analyzer.js.map +1 -0
- package/dist/sentinel/triage/index.d.ts +10 -0
- package/dist/sentinel/triage/index.d.ts.map +1 -0
- package/dist/sentinel/triage/index.js +39 -0
- package/dist/sentinel/triage/index.js.map +1 -0
- package/dist/sentinel/triage/scorer.d.ts +9 -0
- package/dist/sentinel/triage/scorer.d.ts.map +1 -0
- package/dist/sentinel/triage/scorer.js +28 -0
- package/dist/sentinel/triage/scorer.js.map +1 -0
- package/dist/sentinel/types.d.ts +125 -0
- package/dist/sentinel/types.d.ts.map +1 -0
- package/dist/sentinel/types.js +6 -0
- package/dist/sentinel/types.js.map +1 -0
- package/dist/store/index.d.ts +5 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +24 -1
- package/dist/store/index.js.map +1 -1
- package/dist/stream-events.js +2 -2
- package/dist/stream-events.js.map +1 -1
- package/dist/streaming.d.ts +13 -0
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +42 -0
- package/dist/streaming.js.map +1 -1
- package/dist/swarm/graph.d.ts +81 -2
- package/dist/swarm/graph.d.ts.map +1 -1
- package/dist/swarm/graph.js +517 -36
- package/dist/swarm/graph.js.map +1 -1
- package/dist/swarm/index.d.ts +10 -2
- package/dist/swarm/index.d.ts.map +1 -1
- package/dist/swarm/index.js +6 -1
- package/dist/swarm/index.js.map +1 -1
- package/dist/swarm/mermaid.d.ts +10 -0
- package/dist/swarm/mermaid.d.ts.map +1 -0
- package/dist/swarm/mermaid.js +64 -0
- package/dist/swarm/mermaid.js.map +1 -0
- package/dist/swarm/pool.d.ts +9 -1
- package/dist/swarm/pool.d.ts.map +1 -1
- package/dist/swarm/pool.js +58 -10
- package/dist/swarm/pool.js.map +1 -1
- package/dist/swarm/registry.d.ts +11 -1
- package/dist/swarm/registry.d.ts.map +1 -1
- package/dist/swarm/registry.js +17 -3
- package/dist/swarm/registry.js.map +1 -1
- package/dist/swarm/scaling.d.ts +95 -0
- package/dist/swarm/scaling.d.ts.map +1 -0
- package/dist/swarm/scaling.js +214 -0
- package/dist/swarm/scaling.js.map +1 -0
- package/dist/swarm/snapshot.d.ts +51 -0
- package/dist/swarm/snapshot.d.ts.map +1 -0
- package/dist/swarm/snapshot.js +115 -0
- package/dist/swarm/snapshot.js.map +1 -0
- package/dist/swarm/supervisor.d.ts.map +1 -1
- package/dist/swarm/supervisor.js +82 -4
- package/dist/swarm/supervisor.js.map +1 -1
- package/dist/swarm/tracer.d.ts +57 -0
- package/dist/swarm/tracer.d.ts.map +1 -0
- package/dist/swarm/tracer.js +138 -0
- package/dist/swarm/tracer.js.map +1 -0
- package/dist/swarm/types.d.ts +23 -1
- package/dist/swarm/types.d.ts.map +1 -1
- package/dist/swarm/types.js.map +1 -1
- package/dist/telemetry.d.ts +41 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +69 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/testing/index.d.ts +33 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +95 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tools/types.d.ts +2 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +160 -108
package/dist/swarm/graph.js
CHANGED
|
@@ -16,6 +16,7 @@ import { createSupervisorNode } from "./supervisor.js";
|
|
|
16
16
|
import { getInbox } from "./mailbox.js";
|
|
17
17
|
import { RequestReplyBroker } from "../coordination/request-reply.js";
|
|
18
18
|
import { PubSub } from "../coordination/pubsub.js";
|
|
19
|
+
import { runWithTimeout } from "../internal/timeout.js";
|
|
19
20
|
export const baseSwarmChannels = {
|
|
20
21
|
task: lastValue(() => ""),
|
|
21
22
|
context: mergeObject(() => ({})),
|
|
@@ -72,6 +73,8 @@ export class SwarmGraph {
|
|
|
72
73
|
rules: config.supervisor.rules,
|
|
73
74
|
systemPrompt: config.supervisor.systemPrompt,
|
|
74
75
|
maxRounds: config.supervisor.maxRounds,
|
|
76
|
+
deadlineMs: config.supervisor.deadlineMs,
|
|
77
|
+
autoRecover: config.supervisor.autoRecover,
|
|
75
78
|
});
|
|
76
79
|
return swarm;
|
|
77
80
|
}
|
|
@@ -82,29 +85,66 @@ export class SwarmGraph {
|
|
|
82
85
|
*/
|
|
83
86
|
static fanOut(config) {
|
|
84
87
|
const swarm = new SwarmGraph(config.channels);
|
|
88
|
+
const agentIds = config.agents.map((a) => a.id);
|
|
89
|
+
const maxConcurrency = config.maxConcurrency;
|
|
90
|
+
const timeoutMs = config.timeoutMs;
|
|
91
|
+
const weights = config.weights;
|
|
92
|
+
// Register agents in registry (but don't use addAgent — we wire manually)
|
|
85
93
|
for (const agentDef of config.agents) {
|
|
86
|
-
swarm.
|
|
94
|
+
swarm.registry.register(agentDef);
|
|
95
|
+
swarm.agentIds.add(agentDef.id);
|
|
87
96
|
}
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
// Single orchestrator node that runs agents with concurrency/timeout control
|
|
98
|
+
swarm.inner.addNode("__fanout_runner__", async (state, cfg) => {
|
|
99
|
+
const agentMap = new Map(config.agents.map((a) => [a.id, a]));
|
|
100
|
+
async function runAgent(id) {
|
|
101
|
+
const agent = agentMap.get(id);
|
|
102
|
+
try {
|
|
103
|
+
await agent.hooks?.onStart?.(id, state);
|
|
104
|
+
const result = await runWithTimeout(() => agent.skeleton.invoke({ ...state }, { ...cfg, agentId: id }), timeoutMs, () => new Error(`Agent "${id}" timed out after ${timeoutMs}ms`));
|
|
105
|
+
await agent.hooks?.onComplete?.(id, result);
|
|
106
|
+
return { id, result, error: null };
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
await agent.hooks?.onError?.(id, err);
|
|
110
|
+
return { id, result: null, error: err };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
let allResults;
|
|
114
|
+
if (maxConcurrency != null && maxConcurrency > 0) {
|
|
115
|
+
// Batched execution with concurrency limit
|
|
116
|
+
allResults = [];
|
|
117
|
+
const remaining = [...agentIds];
|
|
118
|
+
while (remaining.length > 0) {
|
|
119
|
+
const batch = remaining.splice(0, maxConcurrency);
|
|
120
|
+
const batchResults = await Promise.all(batch.map(runAgent));
|
|
121
|
+
allResults.push(...batchResults);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// All in parallel
|
|
126
|
+
allResults = await Promise.all(agentIds.map(runAgent));
|
|
127
|
+
}
|
|
128
|
+
// Collect results
|
|
129
|
+
const agentResults = { ...(state.agentResults ?? {}) };
|
|
130
|
+
for (const { id, result, error } of allResults) {
|
|
131
|
+
if (error) {
|
|
132
|
+
agentResults[id] = {
|
|
133
|
+
_error: true,
|
|
134
|
+
agent: id,
|
|
135
|
+
error: String(error instanceof Error ? error.message : error),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
agentResults[id] = result;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Run reducer with weights
|
|
143
|
+
const reduced = config.reducer(agentResults, weights);
|
|
144
|
+
return { ...reduced, agentResults };
|
|
97
145
|
});
|
|
98
|
-
|
|
99
|
-
swarm.inner.addEdge(
|
|
100
|
-
// __fanout__ → Send to all agents in parallel
|
|
101
|
-
swarm.inner.addConditionalEdges("__fanout__", ((state) => agentIds.map((id) => new Send(id, { ...state }))));
|
|
102
|
-
// Each agent → __reducer__
|
|
103
|
-
for (const id of agentIds) {
|
|
104
|
-
swarm.inner.addEdge(id, "__reducer__");
|
|
105
|
-
}
|
|
106
|
-
// __reducer__ → END
|
|
107
|
-
swarm.inner.addEdge("__reducer__", END);
|
|
146
|
+
swarm.inner.addEdge(START, "__fanout_runner__");
|
|
147
|
+
swarm.inner.addEdge("__fanout_runner__", END);
|
|
108
148
|
return swarm;
|
|
109
149
|
}
|
|
110
150
|
// ---- Static factory: pipeline template ----
|
|
@@ -220,6 +260,8 @@ export class SwarmGraph {
|
|
|
220
260
|
for (const debater of config.debaters) {
|
|
221
261
|
swarm.addAgent(debater);
|
|
222
262
|
}
|
|
263
|
+
const scoreDebaters = config.judge.scoreDebaters ?? false;
|
|
264
|
+
const consensusThreshold = config.judge.consensusThreshold;
|
|
223
265
|
// Judge node: evaluates arguments, decides continue or consensus
|
|
224
266
|
swarm.inner.addNode("__judge__", async (state) => {
|
|
225
267
|
const round = state.supervisorRound ?? 0;
|
|
@@ -234,21 +276,61 @@ export class SwarmGraph {
|
|
|
234
276
|
const argsText = Object.entries(results)
|
|
235
277
|
.map(([id, r]) => `${id}: ${JSON.stringify(r)}`)
|
|
236
278
|
.join("\n\n");
|
|
279
|
+
const scoreInstruction = scoreDebaters
|
|
280
|
+
? `\nAlso provide a JSON object with scores for each debater and a verdict. Format: {"scores": {"debater_id": score}, "verdict": "CONTINUE" or "${consensusKeyword}"}`
|
|
281
|
+
: "";
|
|
237
282
|
const response = await config.judge.model.chat({
|
|
238
283
|
messages: [{
|
|
239
284
|
role: "user",
|
|
240
|
-
content: `Round ${round}. Evaluate these arguments:\n\n${argsText}\n\nRespond "${consensusKeyword}" if consensus reached, otherwise "CONTINUE"
|
|
285
|
+
content: `Round ${round}. Evaluate these arguments:\n\n${argsText}\n\nRespond "${consensusKeyword}" if consensus reached, otherwise "CONTINUE".${scoreInstruction}`,
|
|
241
286
|
}],
|
|
242
287
|
systemPrompt: config.judge.systemPrompt ?? "You are a debate judge.",
|
|
243
288
|
});
|
|
244
|
-
|
|
289
|
+
let isConsensus = false;
|
|
290
|
+
let roundScores;
|
|
291
|
+
const existingScores = (state.context.debateScores ?? []);
|
|
292
|
+
// Try to parse structured response (JSON with scores + verdict)
|
|
293
|
+
if (scoreDebaters) {
|
|
294
|
+
try {
|
|
295
|
+
const parsed = JSON.parse(response.content);
|
|
296
|
+
if (parsed.scores) {
|
|
297
|
+
roundScores = parsed.scores;
|
|
298
|
+
}
|
|
299
|
+
if (parsed.verdict) {
|
|
300
|
+
isConsensus = parsed.verdict.includes(consensusKeyword);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// Fallback to keyword detection
|
|
305
|
+
isConsensus = response.content.includes(consensusKeyword);
|
|
306
|
+
}
|
|
307
|
+
// Check consensus threshold if scores available
|
|
308
|
+
if (!isConsensus && roundScores && consensusThreshold != null) {
|
|
309
|
+
const scoreValues = Object.values(roundScores);
|
|
310
|
+
if (scoreValues.length >= 2) {
|
|
311
|
+
const spread = Math.max(...scoreValues) - Math.min(...scoreValues);
|
|
312
|
+
if (spread <= consensusThreshold) {
|
|
313
|
+
isConsensus = true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
isConsensus = response.content.includes(consensusKeyword);
|
|
320
|
+
}
|
|
245
321
|
const nextRound = round + 1;
|
|
246
322
|
// Force done if consensus or max rounds exhausted
|
|
247
|
-
// (round 0 is kick-off only, so chat is called maxRounds times)
|
|
248
323
|
const isDone = isConsensus || nextRound > config.judge.maxRounds;
|
|
324
|
+
const updatedScores = roundScores
|
|
325
|
+
? [...existingScores, { round, scores: roundScores }]
|
|
326
|
+
: existingScores;
|
|
249
327
|
return {
|
|
250
328
|
done: isDone,
|
|
251
329
|
supervisorRound: nextRound,
|
|
330
|
+
context: {
|
|
331
|
+
...(state.context ?? {}),
|
|
332
|
+
...(scoreDebaters ? { debateScores: updatedScores } : {}),
|
|
333
|
+
},
|
|
252
334
|
messages: [{ role: "system", content: `Judge round ${round}: ${isDone ? "Consensus" : "Continue"}` }],
|
|
253
335
|
};
|
|
254
336
|
});
|
|
@@ -364,6 +446,248 @@ export class SwarmGraph {
|
|
|
364
446
|
});
|
|
365
447
|
return swarm;
|
|
366
448
|
}
|
|
449
|
+
// ---- Static factory: race template ----
|
|
450
|
+
/**
|
|
451
|
+
* Race all agents in parallel — first acceptable result wins.
|
|
452
|
+
* Optionally filter results with an `accept` predicate.
|
|
453
|
+
*/
|
|
454
|
+
static race(config) {
|
|
455
|
+
const swarm = new SwarmGraph(config.channels);
|
|
456
|
+
const agentIds = config.agents.map((a) => a.id);
|
|
457
|
+
const accept = config.accept ?? (() => true);
|
|
458
|
+
const timeoutMs = config.timeoutMs;
|
|
459
|
+
// Register agents so they appear in the registry
|
|
460
|
+
for (const agentDef of config.agents) {
|
|
461
|
+
swarm.registry.register(agentDef);
|
|
462
|
+
swarm.agentIds.add(agentDef.id);
|
|
463
|
+
}
|
|
464
|
+
// Single node that races all agents
|
|
465
|
+
swarm.inner.addNode("__race__", async (state, cfg) => {
|
|
466
|
+
const promises = config.agents.map(async (agent) => {
|
|
467
|
+
try {
|
|
468
|
+
const result = await agent.skeleton.invoke({ ...state }, { ...cfg, agentId: agent.id });
|
|
469
|
+
return { id: agent.id, result, error: null };
|
|
470
|
+
}
|
|
471
|
+
catch (err) {
|
|
472
|
+
return { id: agent.id, result: null, error: err };
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
let allResults;
|
|
476
|
+
if (timeoutMs != null) {
|
|
477
|
+
// Wrap each promise with a timeout
|
|
478
|
+
const timedPromises = promises.map((p) => Promise.race([
|
|
479
|
+
p,
|
|
480
|
+
new Promise((resolve) => setTimeout(() => resolve({ id: "?", result: null, error: new Error("timeout") }), timeoutMs)),
|
|
481
|
+
]));
|
|
482
|
+
allResults = await Promise.all(timedPromises);
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
allResults = await Promise.all(promises);
|
|
486
|
+
}
|
|
487
|
+
// Find the first acceptable result (in order of agent definition)
|
|
488
|
+
for (const { id, result, error } of allResults) {
|
|
489
|
+
if (!error && accept(result)) {
|
|
490
|
+
return {
|
|
491
|
+
agentResults: { [id]: result },
|
|
492
|
+
context: { ...(state.context ?? {}), raceWinner: id },
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
// No acceptable result
|
|
497
|
+
return {
|
|
498
|
+
context: {
|
|
499
|
+
...(state.context ?? {}),
|
|
500
|
+
raceError: "No agent produced an acceptable result",
|
|
501
|
+
},
|
|
502
|
+
};
|
|
503
|
+
});
|
|
504
|
+
swarm.inner.addEdge(START, "__race__");
|
|
505
|
+
swarm.inner.addEdge("__race__", END);
|
|
506
|
+
return swarm;
|
|
507
|
+
}
|
|
508
|
+
// ---- Static factory: dag template ----
|
|
509
|
+
/**
|
|
510
|
+
* Execute agents in dependency order (directed acyclic graph).
|
|
511
|
+
* Agents with no dependencies run in parallel.
|
|
512
|
+
*/
|
|
513
|
+
static dag(config) {
|
|
514
|
+
const agentMap = new Map(config.agents.map((a) => [a.id, a]));
|
|
515
|
+
// Validate dependencies
|
|
516
|
+
for (const [node, deps] of Object.entries(config.dependencies)) {
|
|
517
|
+
for (const dep of deps) {
|
|
518
|
+
if (!agentMap.has(dep)) {
|
|
519
|
+
throw new Error(`Dependency "${dep}" not found in agents list.`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
// Cycle detection via topological sort
|
|
524
|
+
const visited = new Set();
|
|
525
|
+
const visiting = new Set();
|
|
526
|
+
const sorted = [];
|
|
527
|
+
function visit(id) {
|
|
528
|
+
if (visited.has(id))
|
|
529
|
+
return;
|
|
530
|
+
if (visiting.has(id))
|
|
531
|
+
throw new Error(`Cycle detected involving "${id}".`);
|
|
532
|
+
visiting.add(id);
|
|
533
|
+
for (const dep of config.dependencies[id] ?? []) {
|
|
534
|
+
visit(dep);
|
|
535
|
+
}
|
|
536
|
+
visiting.delete(id);
|
|
537
|
+
visited.add(id);
|
|
538
|
+
sorted.push(id);
|
|
539
|
+
}
|
|
540
|
+
for (const agent of config.agents) {
|
|
541
|
+
visit(agent.id);
|
|
542
|
+
}
|
|
543
|
+
// Build a standard swarm with wiring based on topological sort
|
|
544
|
+
const swarm = new SwarmGraph(config.channels);
|
|
545
|
+
for (const agent of config.agents) {
|
|
546
|
+
swarm.addAgent(agent);
|
|
547
|
+
}
|
|
548
|
+
// Group agents into layers based on dependencies
|
|
549
|
+
const deps = config.dependencies;
|
|
550
|
+
const rootIds = config.agents.filter((a) => !deps[a.id]?.length).map((a) => a.id);
|
|
551
|
+
const nonRootIds = config.agents.filter((a) => deps[a.id]?.length).map((a) => a.id);
|
|
552
|
+
// For DAG execution: use a single orchestrator node
|
|
553
|
+
swarm.inner.addNode("__dag_runner__", async (state, cfg) => {
|
|
554
|
+
const results = {};
|
|
555
|
+
const completed = new Set();
|
|
556
|
+
// Process in topological order
|
|
557
|
+
// Group into parallel batches
|
|
558
|
+
const remaining = new Set(sorted);
|
|
559
|
+
while (remaining.size > 0) {
|
|
560
|
+
// Find all nodes whose deps are satisfied
|
|
561
|
+
const ready = [];
|
|
562
|
+
for (const id of remaining) {
|
|
563
|
+
const idDeps = deps[id] ?? [];
|
|
564
|
+
if (idDeps.every((d) => completed.has(d))) {
|
|
565
|
+
ready.push(id);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
// Execute ready nodes in parallel
|
|
569
|
+
const batchResults = await Promise.all(ready.map(async (id) => {
|
|
570
|
+
const agent = agentMap.get(id);
|
|
571
|
+
const result = await agent.skeleton.invoke({ ...state, agentResults: { ...(state.agentResults ?? {}), ...results } }, { ...cfg, agentId: id });
|
|
572
|
+
return { id, result };
|
|
573
|
+
}));
|
|
574
|
+
for (const { id, result } of batchResults) {
|
|
575
|
+
results[id] = result;
|
|
576
|
+
completed.add(id);
|
|
577
|
+
remaining.delete(id);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
agentResults: { ...(state.agentResults ?? {}), ...results },
|
|
582
|
+
};
|
|
583
|
+
});
|
|
584
|
+
// Wire: START → __dag_runner__ → END
|
|
585
|
+
// Remove any edges added by addAgent
|
|
586
|
+
swarm.inner.edges = [];
|
|
587
|
+
swarm.inner.addEdge(START, "__dag_runner__");
|
|
588
|
+
swarm.inner.addEdge("__dag_runner__", END);
|
|
589
|
+
return swarm;
|
|
590
|
+
}
|
|
591
|
+
// ---- Static factory: pool template ----
|
|
592
|
+
/**
|
|
593
|
+
* Distribute N input items across poolSize copies of a single agent,
|
|
594
|
+
* then reduce all results.
|
|
595
|
+
*/
|
|
596
|
+
static pool(config) {
|
|
597
|
+
const swarm = new SwarmGraph(config.channels);
|
|
598
|
+
const poolSize = config.poolSize;
|
|
599
|
+
// Create pool copies
|
|
600
|
+
const poolIds = [];
|
|
601
|
+
for (let i = 0; i < poolSize; i++) {
|
|
602
|
+
const id = poolSize === 1 ? config.agent.id : `${config.agent.id}_${i}`;
|
|
603
|
+
poolIds.push(id);
|
|
604
|
+
swarm.addAgent({ ...config.agent, id });
|
|
605
|
+
}
|
|
606
|
+
// Orchestrator node: dispatches items to pool agents and reduces
|
|
607
|
+
swarm.inner.addNode("__pool_runner__", async (state, cfg) => {
|
|
608
|
+
const items = state[config.inputField];
|
|
609
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
610
|
+
return config.reducer({});
|
|
611
|
+
}
|
|
612
|
+
// Semaphore for concurrency control
|
|
613
|
+
let running = 0;
|
|
614
|
+
const results = {};
|
|
615
|
+
const queue = items.map((item, idx) => ({
|
|
616
|
+
item,
|
|
617
|
+
idx,
|
|
618
|
+
targetId: poolIds[idx % poolIds.length],
|
|
619
|
+
}));
|
|
620
|
+
await new Promise((resolve, reject) => {
|
|
621
|
+
let completed = 0;
|
|
622
|
+
const total = queue.length;
|
|
623
|
+
function processNext() {
|
|
624
|
+
while (running < poolSize && queue.length > 0) {
|
|
625
|
+
const work = queue.shift();
|
|
626
|
+
running++;
|
|
627
|
+
const agent = swarm.registry.getDef(work.targetId)
|
|
628
|
+
?? config.agent;
|
|
629
|
+
const skeleton = agent.skeleton;
|
|
630
|
+
skeleton.invoke({ ...state, task: String(work.item) }, { ...cfg, agentId: work.targetId }).then((result) => {
|
|
631
|
+
results[`item_${work.idx}`] = result;
|
|
632
|
+
running--;
|
|
633
|
+
completed++;
|
|
634
|
+
if (completed === total)
|
|
635
|
+
resolve();
|
|
636
|
+
else
|
|
637
|
+
processNext();
|
|
638
|
+
}, (err) => {
|
|
639
|
+
results[`item_${work.idx}`] = { _error: String(err) };
|
|
640
|
+
running--;
|
|
641
|
+
completed++;
|
|
642
|
+
if (completed === total)
|
|
643
|
+
resolve();
|
|
644
|
+
else
|
|
645
|
+
processNext();
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
if (total === 0)
|
|
650
|
+
resolve();
|
|
651
|
+
else
|
|
652
|
+
processNext();
|
|
653
|
+
});
|
|
654
|
+
return config.reducer(results);
|
|
655
|
+
});
|
|
656
|
+
// Wire: START → __pool_runner__ → END (bypass agent edges)
|
|
657
|
+
swarm.inner.edges = [];
|
|
658
|
+
swarm.inner.addEdge(START, "__pool_runner__");
|
|
659
|
+
swarm.inner.addEdge("__pool_runner__", END);
|
|
660
|
+
return swarm;
|
|
661
|
+
}
|
|
662
|
+
// ---- Static factory: compose template ----
|
|
663
|
+
/**
|
|
664
|
+
* Compose multiple sub-swarms as pipeline stages.
|
|
665
|
+
* Each stage runs a compiled sub-swarm, passing state through.
|
|
666
|
+
*/
|
|
667
|
+
static compose(config) {
|
|
668
|
+
const swarm = new SwarmGraph(config.channels);
|
|
669
|
+
const stageIds = config.stages.map((s) => s.id);
|
|
670
|
+
for (const stage of config.stages) {
|
|
671
|
+
const compiled = stage.swarm.compile();
|
|
672
|
+
swarm.inner.addNode(stage.id, async (state, cfg) => {
|
|
673
|
+
const stageResult = await compiled.invoke(state, cfg);
|
|
674
|
+
return {
|
|
675
|
+
...stageResult,
|
|
676
|
+
agentResults: {
|
|
677
|
+
...(state.agentResults ?? {}),
|
|
678
|
+
[stage.id]: stageResult,
|
|
679
|
+
},
|
|
680
|
+
};
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
// Wire pipeline: START → stage1 → stage2 → ... → END
|
|
684
|
+
swarm.inner.addEdge(START, stageIds[0]);
|
|
685
|
+
for (let i = 0; i < stageIds.length - 1; i++) {
|
|
686
|
+
swarm.inner.addEdge(stageIds[i], stageIds[i + 1]);
|
|
687
|
+
}
|
|
688
|
+
swarm.inner.addEdge(stageIds[stageIds.length - 1], END);
|
|
689
|
+
return swarm;
|
|
690
|
+
}
|
|
367
691
|
// ---- Agent registration ----
|
|
368
692
|
addAgent(def) {
|
|
369
693
|
this.registry.register(def);
|
|
@@ -371,30 +695,55 @@ export class SwarmGraph {
|
|
|
371
695
|
// Wrap the agent's skeleton as a node
|
|
372
696
|
// The node executes the agent's skeleton and handles Handoff returns
|
|
373
697
|
const agentNode = async (state, config) => {
|
|
374
|
-
console.log(`[swarm] agent="${def.id}" (${def.role}) starting`);
|
|
375
698
|
this.registry.markBusy(def.id);
|
|
699
|
+
// Fire onStart hook
|
|
700
|
+
await def.hooks?.onStart?.(def.id, state);
|
|
376
701
|
const maxRetries = def.maxRetries ?? 2;
|
|
702
|
+
const retryDelayMs = def.retryDelayMs ?? 0;
|
|
377
703
|
let lastError;
|
|
704
|
+
let lastAttempt = 0;
|
|
378
705
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
706
|
+
lastAttempt = attempt;
|
|
379
707
|
try {
|
|
708
|
+
// Get inbox and filter out already-consumed messages
|
|
709
|
+
const consumedIds = (state.context?.__consumedMsgIds ?? []);
|
|
710
|
+
const consumedSet = new Set(consumedIds);
|
|
711
|
+
const allInbox = getInbox(state.swarmMessages ?? [], def.id);
|
|
712
|
+
const inbox = allInbox.filter((m) => !consumedSet.has(m.id));
|
|
713
|
+
// Track consumed message IDs
|
|
714
|
+
const newConsumedIds = [...consumedIds, ...inbox.map((m) => m.id)];
|
|
380
715
|
const agentInput = {
|
|
381
716
|
...state,
|
|
382
717
|
context: {
|
|
383
718
|
...(state.context ?? {}),
|
|
384
|
-
inbox
|
|
719
|
+
inbox,
|
|
720
|
+
__consumedMsgIds: newConsumedIds,
|
|
385
721
|
},
|
|
386
722
|
};
|
|
387
|
-
|
|
723
|
+
let effectiveTimeout = def.timeout;
|
|
724
|
+
// Clamp agent timeout to remaining deadline (if set)
|
|
725
|
+
const deadlineAbs = state.context?.__deadlineAbsolute;
|
|
726
|
+
if (deadlineAbs != null) {
|
|
727
|
+
const remaining = deadlineAbs - Date.now();
|
|
728
|
+
if (remaining <= 0) {
|
|
729
|
+
throw new Error(`Agent "${def.id}" deadline expired`);
|
|
730
|
+
}
|
|
731
|
+
if (effectiveTimeout == null || remaining < effectiveTimeout) {
|
|
732
|
+
effectiveTimeout = remaining;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
const result = await runWithTimeout(() => def.skeleton.invoke(agentInput, {
|
|
388
736
|
...config,
|
|
389
737
|
agentId: def.id,
|
|
390
|
-
});
|
|
738
|
+
}), effectiveTimeout, () => new Error(`Agent "${def.id}" timed out after ${effectiveTimeout}ms`));
|
|
391
739
|
this.registry.markIdle(def.id);
|
|
392
|
-
console.log(`[swarm] agent="${def.id}" completed`);
|
|
393
740
|
// ---- Handoff detection ----
|
|
394
741
|
if (result instanceof Handoff || (result && result.isHandoff)) {
|
|
395
742
|
const handoff = result instanceof Handoff
|
|
396
743
|
? result
|
|
397
744
|
: new Handoff(result.opts);
|
|
745
|
+
// Fire onComplete for handoffs too
|
|
746
|
+
await def.hooks?.onComplete?.(def.id, result);
|
|
398
747
|
return new Command({
|
|
399
748
|
update: {
|
|
400
749
|
context: { ...(state.context ?? {}), ...(handoff.context ?? {}) },
|
|
@@ -411,9 +760,15 @@ export class SwarmGraph {
|
|
|
411
760
|
goto: handoff.to,
|
|
412
761
|
});
|
|
413
762
|
}
|
|
763
|
+
// Fire onComplete hook
|
|
764
|
+
await def.hooks?.onComplete?.(def.id, result);
|
|
414
765
|
// ---- Normal result ----
|
|
415
766
|
return {
|
|
416
767
|
...result,
|
|
768
|
+
context: {
|
|
769
|
+
...(result.context ?? {}),
|
|
770
|
+
__consumedMsgIds: newConsumedIds,
|
|
771
|
+
},
|
|
417
772
|
agentResults: {
|
|
418
773
|
...(state.agentResults ?? {}),
|
|
419
774
|
[def.id]: result,
|
|
@@ -433,21 +788,44 @@ export class SwarmGraph {
|
|
|
433
788
|
catch (err) {
|
|
434
789
|
lastError = err;
|
|
435
790
|
this.registry.markError(def.id);
|
|
436
|
-
console.warn(`[swarm] agent="${def.id}" attempt ${attempt + 1}/${maxRetries + 1} failed: ${err}`);
|
|
437
791
|
if (attempt < maxRetries) {
|
|
792
|
+
// Backoff delay between retries — clamped to remaining deadline
|
|
793
|
+
if (retryDelayMs > 0) {
|
|
794
|
+
let delay = retryDelayMs;
|
|
795
|
+
const dl = state.context?.__deadlineAbsolute;
|
|
796
|
+
if (dl != null) {
|
|
797
|
+
const remaining = dl - Date.now();
|
|
798
|
+
if (remaining <= 0)
|
|
799
|
+
break; // deadline expired, stop retrying
|
|
800
|
+
delay = Math.min(delay, remaining);
|
|
801
|
+
}
|
|
802
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
803
|
+
}
|
|
438
804
|
continue; // retry
|
|
439
805
|
}
|
|
440
806
|
}
|
|
441
807
|
}
|
|
442
|
-
// All retries exhausted —
|
|
443
|
-
|
|
444
|
-
|
|
808
|
+
// All retries exhausted — fire onError hook
|
|
809
|
+
await def.hooks?.onError?.(def.id, lastError);
|
|
810
|
+
// Keep agent in error status (don't reset to idle)
|
|
811
|
+
// Build structured error context
|
|
812
|
+
const errStr = String(lastError instanceof Error ? lastError.message : lastError);
|
|
813
|
+
const errType = errStr.includes("timeout") ? "timeout" :
|
|
814
|
+
errStr.includes("model") ? "model_error" :
|
|
815
|
+
errStr.includes("tool") ? "tool_error" :
|
|
816
|
+
"unknown";
|
|
445
817
|
if (this.hasSupervisor) {
|
|
446
818
|
return new Command({
|
|
447
819
|
update: {
|
|
448
820
|
context: {
|
|
449
821
|
...(state.context ?? {}),
|
|
450
|
-
lastAgentError: {
|
|
822
|
+
lastAgentError: {
|
|
823
|
+
agent: def.id,
|
|
824
|
+
error: errStr,
|
|
825
|
+
type: errType,
|
|
826
|
+
attempt: lastAttempt,
|
|
827
|
+
maxRetries,
|
|
828
|
+
},
|
|
451
829
|
},
|
|
452
830
|
},
|
|
453
831
|
goto: this.supervisorNodeName,
|
|
@@ -501,6 +879,32 @@ export class SwarmGraph {
|
|
|
501
879
|
this.inner.addEdge(from, to);
|
|
502
880
|
return this;
|
|
503
881
|
}
|
|
882
|
+
// ---- Topology validation ----
|
|
883
|
+
/**
|
|
884
|
+
* Check the swarm topology for common issues like orphan agents.
|
|
885
|
+
* Returns an array of issue strings (empty = valid).
|
|
886
|
+
*/
|
|
887
|
+
validateTopology() {
|
|
888
|
+
const issues = [];
|
|
889
|
+
// In supervised swarms, all agents are reachable via Command.goto
|
|
890
|
+
if (this.hasSupervisor)
|
|
891
|
+
return issues;
|
|
892
|
+
// For non-supervised swarms, check that every agent has at least one incoming edge
|
|
893
|
+
const edgeTargets = new Set();
|
|
894
|
+
for (const edge of this.inner.edges) {
|
|
895
|
+
if (edge.type === "static") {
|
|
896
|
+
edgeTargets.add(edge.to);
|
|
897
|
+
}
|
|
898
|
+
// Conditional edges: the 'from' node is reachable if it has incoming edges
|
|
899
|
+
edgeTargets.add(edge.from);
|
|
900
|
+
}
|
|
901
|
+
for (const agentId of this.agentIds) {
|
|
902
|
+
if (!edgeTargets.has(agentId)) {
|
|
903
|
+
issues.push(`Agent "${agentId}" is an orphan — no edges connect to or from it.`);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return issues;
|
|
907
|
+
}
|
|
504
908
|
// ---- Pipeline shorthand ----
|
|
505
909
|
/**
|
|
506
910
|
* Wire agents as a linear pipeline: A → B → C → END
|
|
@@ -522,13 +926,90 @@ export class SwarmGraph {
|
|
|
522
926
|
...(opts.interruptBefore ? { interruptBefore: opts.interruptBefore } : {}),
|
|
523
927
|
...(opts.interruptAfter ? { interruptAfter: opts.interruptAfter } : {}),
|
|
524
928
|
});
|
|
929
|
+
const registry = this.registry;
|
|
930
|
+
const inner = this.inner;
|
|
931
|
+
const hasSupervisor = this.hasSupervisor;
|
|
932
|
+
const supervisorNodeName = this.supervisorNodeName;
|
|
933
|
+
const self = this;
|
|
525
934
|
// Attach swarm-specific extensions
|
|
526
935
|
const extensions = {
|
|
527
|
-
registry
|
|
528
|
-
agentStats: () =>
|
|
529
|
-
toMermaid: () =>
|
|
936
|
+
registry,
|
|
937
|
+
agentStats: () => registry.stats(),
|
|
938
|
+
toMermaid: () => inner.toMermaid(),
|
|
939
|
+
spawnAgent(def) {
|
|
940
|
+
// Register in the registry
|
|
941
|
+
registry.register(def);
|
|
942
|
+
// Create the agent node function (same logic as addAgent)
|
|
943
|
+
const agentNode = async (state, config) => {
|
|
944
|
+
registry.markBusy(def.id);
|
|
945
|
+
await def.hooks?.onStart?.(def.id, state);
|
|
946
|
+
const maxRetries = def.maxRetries ?? 2;
|
|
947
|
+
let lastError;
|
|
948
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
949
|
+
try {
|
|
950
|
+
const result = await def.skeleton.invoke({ ...state, context: { ...(state.context ?? {}), inbox: getInbox(state.swarmMessages ?? [], def.id) } }, { ...config, agentId: def.id });
|
|
951
|
+
registry.markIdle(def.id);
|
|
952
|
+
await def.hooks?.onComplete?.(def.id, result);
|
|
953
|
+
return {
|
|
954
|
+
...result,
|
|
955
|
+
agentResults: { ...(state.agentResults ?? {}), [def.id]: result },
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
catch (err) {
|
|
959
|
+
lastError = err;
|
|
960
|
+
registry.markError(def.id);
|
|
961
|
+
if (attempt < maxRetries)
|
|
962
|
+
continue;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
await def.hooks?.onError?.(def.id, lastError);
|
|
966
|
+
// Keep agent in error status (don't reset to idle)
|
|
967
|
+
if (hasSupervisor) {
|
|
968
|
+
return new Command({
|
|
969
|
+
update: { context: { ...(state.context ?? {}), lastAgentError: { agent: def.id, error: String(lastError) } } },
|
|
970
|
+
goto: supervisorNodeName,
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
throw lastError;
|
|
974
|
+
};
|
|
975
|
+
// Add node to the compiled runner's nodes map
|
|
976
|
+
const runner = skeleton._runner;
|
|
977
|
+
if (runner?.nodes) {
|
|
978
|
+
runner.nodes.set(def.id, { name: def.id, fn: agentNode });
|
|
979
|
+
}
|
|
980
|
+
},
|
|
981
|
+
removeAgent(agentId) {
|
|
982
|
+
registry.deregister(agentId);
|
|
983
|
+
},
|
|
530
984
|
};
|
|
531
985
|
return Object.assign(skeleton, extensions);
|
|
532
986
|
}
|
|
533
987
|
}
|
|
988
|
+
// ----------------------------------------------------------------
|
|
989
|
+
// quickAgent — convenience factory for tests and simple swarms
|
|
990
|
+
// ----------------------------------------------------------------
|
|
991
|
+
/**
|
|
992
|
+
* Create a SwarmAgentDef from just an id and a handler function.
|
|
993
|
+
* Builds a single-node StateGraph internally so the agent is fully
|
|
994
|
+
* functional in any SwarmGraph topology.
|
|
995
|
+
*/
|
|
996
|
+
export function quickAgent(id, fn, opts) {
|
|
997
|
+
const g = new StateGraph({ channels: baseSwarmChannels });
|
|
998
|
+
g.addNode("work", async (state) => fn(state));
|
|
999
|
+
g.addEdge(START, "work");
|
|
1000
|
+
g.addEdge("work", END);
|
|
1001
|
+
const skeleton = g.compile();
|
|
1002
|
+
return {
|
|
1003
|
+
id,
|
|
1004
|
+
role: opts?.role ?? id,
|
|
1005
|
+
capabilities: opts?.capabilities ?? [],
|
|
1006
|
+
skeleton: skeleton,
|
|
1007
|
+
hooks: opts?.hooks,
|
|
1008
|
+
maxRetries: opts?.maxRetries,
|
|
1009
|
+
maxConcurrency: opts?.maxConcurrency,
|
|
1010
|
+
systemPrompt: opts?.systemPrompt,
|
|
1011
|
+
timeout: opts?.timeout,
|
|
1012
|
+
retryDelayMs: opts?.retryDelayMs,
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
534
1015
|
//# sourceMappingURL=graph.js.map
|