agent-relay 2.3.2 → 2.3.5
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 +1 -1
- package/dist/index.cjs +1 -1
- package/dist/src/cli/index.js +124 -7
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +20 -26
- package/packages/acp-bridge/package.json +2 -2
- package/packages/bridge/package.json +7 -7
- package/packages/config/dist/cloud-config.d.ts +1 -1
- package/packages/config/dist/cloud-config.d.ts.map +1 -1
- package/packages/config/dist/cloud-config.js.map +1 -1
- package/packages/config/dist/schemas.d.ts +5 -5
- package/packages/config/dist/schemas.js +1 -1
- package/packages/config/dist/schemas.js.map +1 -1
- package/packages/config/package.json +2 -2
- package/packages/config/src/cloud-config.ts +2 -2
- package/packages/config/src/schemas.test.ts +48 -0
- package/packages/config/src/schemas.ts +1 -1
- package/packages/continuity/package.json +2 -2
- package/packages/daemon/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/package.json +5 -5
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/index.d.ts +1 -29
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +1 -38
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/package.json +4 -25
- package/packages/sdk/src/index.ts +1 -69
- package/packages/sdk-py/README.md +56 -0
- package/packages/sdk-py/pyproject.toml +23 -0
- package/packages/sdk-py/src/agent_relay/__init__.py +27 -0
- package/packages/sdk-py/src/agent_relay/builder.py +367 -0
- package/packages/sdk-py/src/agent_relay/types.py +92 -0
- package/packages/sdk-py/tests/__init__.py +0 -0
- package/packages/sdk-py/tests/test_builder.py +101 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.d.ts +2 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.d.ts.map +1 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.js +257 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.js.map +1 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.d.ts +2 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.d.ts.map +1 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.js +124 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.js.map +1 -0
- package/packages/sdk-ts/dist/client.d.ts +2 -0
- package/packages/sdk-ts/dist/client.d.ts.map +1 -1
- package/packages/sdk-ts/dist/client.js +2 -0
- package/packages/sdk-ts/dist/client.js.map +1 -1
- package/packages/sdk-ts/dist/index.d.ts +1 -0
- package/packages/sdk-ts/dist/index.d.ts.map +1 -1
- package/packages/sdk-ts/dist/index.js +1 -0
- package/packages/sdk-ts/dist/index.js.map +1 -1
- package/packages/sdk-ts/dist/protocol.d.ts +1 -0
- package/packages/sdk-ts/dist/protocol.d.ts.map +1 -1
- package/packages/sdk-ts/dist/relay.d.ts +44 -0
- package/packages/sdk-ts/dist/relay.d.ts.map +1 -1
- package/packages/sdk-ts/dist/relay.js +89 -11
- package/packages/sdk-ts/dist/relay.js.map +1 -1
- package/packages/sdk-ts/dist/relaycast.js +2 -2
- package/packages/sdk-ts/dist/relaycast.js.map +1 -1
- package/packages/sdk-ts/dist/workflows/barrier.d.ts +72 -0
- package/packages/sdk-ts/dist/workflows/barrier.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/barrier.js +162 -0
- package/packages/sdk-ts/dist/workflows/barrier.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/builder.d.ts +101 -0
- package/packages/sdk-ts/dist/workflows/builder.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/builder.js +179 -0
- package/packages/sdk-ts/dist/workflows/builder.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/cli.d.ts +10 -0
- package/packages/sdk-ts/dist/workflows/cli.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/cli.js +82 -0
- package/packages/sdk-ts/dist/workflows/cli.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/coordinator.d.ts +68 -0
- package/packages/sdk-ts/dist/workflows/coordinator.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/coordinator.js +353 -0
- package/packages/sdk-ts/dist/workflows/coordinator.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/index.d.ts +10 -0
- package/packages/sdk-ts/dist/workflows/index.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/index.js +10 -0
- package/packages/sdk-ts/dist/workflows/index.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/memory-db.d.ts +17 -0
- package/packages/sdk-ts/dist/workflows/memory-db.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/memory-db.js +33 -0
- package/packages/sdk-ts/dist/workflows/memory-db.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/run.d.ts +31 -0
- package/packages/sdk-ts/dist/workflows/run.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/run.js +24 -0
- package/packages/sdk-ts/dist/workflows/run.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/runner.d.ts +119 -0
- package/packages/sdk-ts/dist/workflows/runner.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/runner.js +650 -0
- package/packages/sdk-ts/dist/workflows/runner.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/state.d.ts +77 -0
- package/packages/sdk-ts/dist/workflows/state.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/state.js +140 -0
- package/packages/sdk-ts/dist/workflows/state.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/templates.d.ts +47 -0
- package/packages/sdk-ts/dist/workflows/templates.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/templates.js +395 -0
- package/packages/sdk-ts/dist/workflows/templates.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/types.d.ts +126 -0
- package/packages/sdk-ts/dist/workflows/types.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/types.js +8 -0
- package/packages/sdk-ts/dist/workflows/types.js.map +1 -0
- package/packages/sdk-ts/package.json +9 -3
- package/packages/sdk-ts/src/__tests__/error-scenarios.test.ts +682 -0
- package/packages/sdk-ts/src/__tests__/facade.test.ts +296 -0
- package/packages/sdk-ts/src/__tests__/swarm-coordinator.test.ts +416 -0
- package/packages/sdk-ts/src/__tests__/unit.test.ts +152 -0
- package/packages/sdk-ts/src/__tests__/workflow-runner.test.ts +333 -0
- package/packages/sdk-ts/src/client.ts +4 -0
- package/packages/sdk-ts/src/index.ts +1 -0
- package/packages/sdk-ts/src/protocol.ts +1 -1
- package/packages/sdk-ts/src/relay.ts +112 -11
- package/packages/sdk-ts/src/relaycast.ts +2 -2
- package/packages/sdk-ts/src/workflows/README.md +450 -0
- package/packages/sdk-ts/src/workflows/barrier.ts +254 -0
- package/packages/sdk-ts/src/workflows/builder.ts +241 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/bug-fix.yaml +75 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/code-review.yaml +82 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/documentation.yaml +70 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/feature-dev.yaml +76 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/refactor.yaml +82 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/security-audit.yaml +84 -0
- package/packages/sdk-ts/src/workflows/cli.ts +93 -0
- package/packages/sdk-ts/src/workflows/coordinator.ts +520 -0
- package/packages/sdk-ts/src/workflows/index.ts +9 -0
- package/packages/sdk-ts/src/workflows/memory-db.ts +39 -0
- package/packages/sdk-ts/src/workflows/run.ts +47 -0
- package/packages/sdk-ts/src/workflows/runner.ts +873 -0
- package/packages/sdk-ts/src/workflows/schema.json +321 -0
- package/packages/sdk-ts/src/workflows/state.ts +279 -0
- package/packages/sdk-ts/src/workflows/templates.ts +544 -0
- package/packages/sdk-ts/src/workflows/types.ts +178 -0
- package/packages/sdk-ts/tsconfig.json +6 -1
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +3 -3
- package/packages/wrapper/package.json +5 -6
- package/scripts/postinstall.js +106 -2
- package/packages/api-types/.trajectories/active/traj_xbsvuzogscey.json +0 -15
- package/packages/api-types/.trajectories/index.json +0 -12
- package/packages/api-types/dist/index.d.ts +0 -21
- package/packages/api-types/dist/index.d.ts.map +0 -1
- package/packages/api-types/dist/index.js +0 -22
- package/packages/api-types/dist/index.js.map +0 -1
- package/packages/api-types/dist/schemas/agent.d.ts +0 -259
- package/packages/api-types/dist/schemas/agent.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/agent.js +0 -102
- package/packages/api-types/dist/schemas/agent.js.map +0 -1
- package/packages/api-types/dist/schemas/api.d.ts +0 -290
- package/packages/api-types/dist/schemas/api.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/api.js +0 -162
- package/packages/api-types/dist/schemas/api.js.map +0 -1
- package/packages/api-types/dist/schemas/decision.d.ts +0 -230
- package/packages/api-types/dist/schemas/decision.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/decision.js +0 -104
- package/packages/api-types/dist/schemas/decision.js.map +0 -1
- package/packages/api-types/dist/schemas/fleet.d.ts +0 -615
- package/packages/api-types/dist/schemas/fleet.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/fleet.js +0 -71
- package/packages/api-types/dist/schemas/fleet.js.map +0 -1
- package/packages/api-types/dist/schemas/history.d.ts +0 -180
- package/packages/api-types/dist/schemas/history.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/history.js +0 -72
- package/packages/api-types/dist/schemas/history.js.map +0 -1
- package/packages/api-types/dist/schemas/index.d.ts +0 -14
- package/packages/api-types/dist/schemas/index.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/index.js +0 -22
- package/packages/api-types/dist/schemas/index.js.map +0 -1
- package/packages/api-types/dist/schemas/message.d.ts +0 -456
- package/packages/api-types/dist/schemas/message.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/message.js +0 -88
- package/packages/api-types/dist/schemas/message.js.map +0 -1
- package/packages/api-types/dist/schemas/session.d.ts +0 -60
- package/packages/api-types/dist/schemas/session.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/session.js +0 -36
- package/packages/api-types/dist/schemas/session.js.map +0 -1
- package/packages/api-types/dist/schemas/task.d.ts +0 -111
- package/packages/api-types/dist/schemas/task.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/task.js +0 -64
- package/packages/api-types/dist/schemas/task.js.map +0 -1
- package/packages/api-types/package.json +0 -61
- package/packages/api-types/scripts/generate-openapi.ts +0 -106
- package/packages/api-types/src/index.ts +0 -22
- package/packages/api-types/src/schemas/agent.test.ts +0 -164
- package/packages/api-types/src/schemas/agent.ts +0 -110
- package/packages/api-types/src/schemas/api.test.ts +0 -372
- package/packages/api-types/src/schemas/api.ts +0 -194
- package/packages/api-types/src/schemas/decision.test.ts +0 -324
- package/packages/api-types/src/schemas/decision.ts +0 -136
- package/packages/api-types/src/schemas/fleet.test.ts +0 -212
- package/packages/api-types/src/schemas/fleet.ts +0 -83
- package/packages/api-types/src/schemas/history.test.ts +0 -242
- package/packages/api-types/src/schemas/history.ts +0 -84
- package/packages/api-types/src/schemas/index.ts +0 -148
- package/packages/api-types/src/schemas/message.test.ts +0 -192
- package/packages/api-types/src/schemas/message.ts +0 -98
- package/packages/api-types/src/schemas/session.test.ts +0 -104
- package/packages/api-types/src/schemas/session.ts +0 -40
- package/packages/api-types/src/schemas/task.test.ts +0 -192
- package/packages/api-types/src/schemas/task.ts +0 -78
- package/packages/api-types/tsconfig.json +0 -19
- package/packages/api-types/vitest.config.ts +0 -9
- package/packages/benchmark/README.md +0 -200
- package/packages/benchmark/datasets/coding-tasks.yaml +0 -127
- package/packages/benchmark/datasets/coordination-tasks.yaml +0 -122
- package/packages/benchmark/datasets/quick-test.yaml +0 -20
- package/packages/benchmark/dist/benchmark.d.ts +0 -47
- package/packages/benchmark/dist/benchmark.d.ts.map +0 -1
- package/packages/benchmark/dist/benchmark.js +0 -224
- package/packages/benchmark/dist/benchmark.js.map +0 -1
- package/packages/benchmark/dist/cli.d.ts +0 -8
- package/packages/benchmark/dist/cli.d.ts.map +0 -1
- package/packages/benchmark/dist/cli.js +0 -185
- package/packages/benchmark/dist/cli.js.map +0 -1
- package/packages/benchmark/dist/harbor.d.ts +0 -53
- package/packages/benchmark/dist/harbor.d.ts.map +0 -1
- package/packages/benchmark/dist/harbor.js +0 -127
- package/packages/benchmark/dist/harbor.js.map +0 -1
- package/packages/benchmark/dist/index.d.ts +0 -48
- package/packages/benchmark/dist/index.d.ts.map +0 -1
- package/packages/benchmark/dist/index.js +0 -50
- package/packages/benchmark/dist/index.js.map +0 -1
- package/packages/benchmark/dist/runners/base.d.ts +0 -63
- package/packages/benchmark/dist/runners/base.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/base.js +0 -156
- package/packages/benchmark/dist/runners/base.js.map +0 -1
- package/packages/benchmark/dist/runners/index.d.ts +0 -10
- package/packages/benchmark/dist/runners/index.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/index.js +0 -10
- package/packages/benchmark/dist/runners/index.js.map +0 -1
- package/packages/benchmark/dist/runners/single.d.ts +0 -19
- package/packages/benchmark/dist/runners/single.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/single.js +0 -111
- package/packages/benchmark/dist/runners/single.js.map +0 -1
- package/packages/benchmark/dist/runners/subagent.d.ts +0 -32
- package/packages/benchmark/dist/runners/subagent.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/subagent.js +0 -212
- package/packages/benchmark/dist/runners/subagent.js.map +0 -1
- package/packages/benchmark/dist/runners/swarm.d.ts +0 -36
- package/packages/benchmark/dist/runners/swarm.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/swarm.js +0 -273
- package/packages/benchmark/dist/runners/swarm.js.map +0 -1
- package/packages/benchmark/dist/types.d.ts +0 -178
- package/packages/benchmark/dist/types.d.ts.map +0 -1
- package/packages/benchmark/dist/types.js +0 -16
- package/packages/benchmark/dist/types.js.map +0 -1
- package/packages/benchmark/package.json +0 -80
- package/packages/benchmark/src/benchmark.ts +0 -298
- package/packages/benchmark/src/cli.ts +0 -240
- package/packages/benchmark/src/harbor.ts +0 -170
- package/packages/benchmark/src/index.ts +0 -73
- package/packages/benchmark/src/runners/base.ts +0 -205
- package/packages/benchmark/src/runners/index.ts +0 -10
- package/packages/benchmark/src/runners/single.ts +0 -121
- package/packages/benchmark/src/runners/subagent.ts +0 -240
- package/packages/benchmark/src/runners/swarm.ts +0 -326
- package/packages/benchmark/src/types.ts +0 -205
- package/packages/benchmark/tsconfig.json +0 -20
- package/packages/cli-tester/README.md +0 -277
- package/packages/cli-tester/dist/index.d.ts +0 -21
- package/packages/cli-tester/dist/index.d.ts.map +0 -1
- package/packages/cli-tester/dist/index.js +0 -21
- package/packages/cli-tester/dist/index.js.map +0 -1
- package/packages/cli-tester/dist/utils/credential-check.d.ts +0 -56
- package/packages/cli-tester/dist/utils/credential-check.d.ts.map +0 -1
- package/packages/cli-tester/dist/utils/credential-check.js +0 -230
- package/packages/cli-tester/dist/utils/credential-check.js.map +0 -1
- package/packages/cli-tester/dist/utils/socket-client.d.ts +0 -76
- package/packages/cli-tester/dist/utils/socket-client.d.ts.map +0 -1
- package/packages/cli-tester/dist/utils/socket-client.js +0 -153
- package/packages/cli-tester/dist/utils/socket-client.js.map +0 -1
- package/packages/cli-tester/docker/Dockerfile +0 -61
- package/packages/cli-tester/docker/docker-compose.yml +0 -71
- package/packages/cli-tester/docker/entrypoint.sh +0 -58
- package/packages/cli-tester/package.json +0 -32
- package/packages/cli-tester/scripts/clear-auth.sh +0 -101
- package/packages/cli-tester/scripts/inject-message.sh +0 -42
- package/packages/cli-tester/scripts/start.sh +0 -71
- package/packages/cli-tester/scripts/test-cli.sh +0 -56
- package/packages/cli-tester/scripts/test-full-spawn.sh +0 -238
- package/packages/cli-tester/scripts/test-registration.sh +0 -182
- package/packages/cli-tester/scripts/test-setup-flow.sh +0 -202
- package/packages/cli-tester/scripts/test-spawn.sh +0 -140
- package/packages/cli-tester/scripts/test-with-daemon.sh +0 -247
- package/packages/cli-tester/scripts/verify-auth.sh +0 -112
- package/packages/cli-tester/src/index.ts +0 -40
- package/packages/cli-tester/src/utils/credential-check.ts +0 -284
- package/packages/cli-tester/src/utils/socket-client.ts +0 -211
- package/packages/cli-tester/tests/credential-check.test.ts +0 -56
- package/packages/cli-tester/tsconfig.json +0 -11
- package/packages/sdk/dist/browser-client.d.ts +0 -212
- package/packages/sdk/dist/browser-client.d.ts.map +0 -1
- package/packages/sdk/dist/browser-client.js +0 -750
- package/packages/sdk/dist/browser-client.js.map +0 -1
- package/packages/sdk/dist/browser-framing.d.ts +0 -46
- package/packages/sdk/dist/browser-framing.d.ts.map +0 -1
- package/packages/sdk/dist/browser-framing.js +0 -122
- package/packages/sdk/dist/browser-framing.js.map +0 -1
- package/packages/sdk/dist/standalone.d.ts +0 -89
- package/packages/sdk/dist/standalone.d.ts.map +0 -1
- package/packages/sdk/dist/standalone.js +0 -131
- package/packages/sdk/dist/standalone.js.map +0 -1
- package/packages/sdk/dist/transports/index.d.ts +0 -92
- package/packages/sdk/dist/transports/index.d.ts.map +0 -1
- package/packages/sdk/dist/transports/index.js +0 -129
- package/packages/sdk/dist/transports/index.js.map +0 -1
- package/packages/sdk/dist/transports/socket-transport.d.ts +0 -30
- package/packages/sdk/dist/transports/socket-transport.d.ts.map +0 -1
- package/packages/sdk/dist/transports/socket-transport.js +0 -94
- package/packages/sdk/dist/transports/socket-transport.js.map +0 -1
- package/packages/sdk/dist/transports/types.d.ts +0 -69
- package/packages/sdk/dist/transports/types.d.ts.map +0 -1
- package/packages/sdk/dist/transports/types.js +0 -10
- package/packages/sdk/dist/transports/types.js.map +0 -1
- package/packages/sdk/dist/transports/websocket-transport.d.ts +0 -55
- package/packages/sdk/dist/transports/websocket-transport.d.ts.map +0 -1
- package/packages/sdk/dist/transports/websocket-transport.js +0 -180
- package/packages/sdk/dist/transports/websocket-transport.js.map +0 -1
- package/packages/sdk/src/browser-client.ts +0 -985
- package/packages/sdk/src/browser-framing.test.ts +0 -115
- package/packages/sdk/src/browser-framing.ts +0 -150
- package/packages/sdk/src/standalone.ts +0 -183
- package/packages/sdk/src/transports/index.ts +0 -197
- package/packages/sdk/src/transports/socket-transport.ts +0 -115
- package/packages/sdk/src/transports/types.ts +0 -77
- package/packages/sdk/src/transports/websocket-transport.ts +0 -245
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single Agent Runner
|
|
3
|
-
*
|
|
4
|
-
* Runs tasks using a single agent with no delegation.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Task, RunResult, ConfigurationType } from '../types.js';
|
|
8
|
-
import { ConfigurationRunner } from './base.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Runner for single-agent configuration
|
|
12
|
-
*/
|
|
13
|
-
export class SingleAgentRunner extends ConfigurationRunner {
|
|
14
|
-
get configurationType(): ConfigurationType {
|
|
15
|
-
return 'single';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async run(task: Task): Promise<RunResult> {
|
|
19
|
-
const startTime = Date.now();
|
|
20
|
-
let firstActionTime = 0;
|
|
21
|
-
let success = false;
|
|
22
|
-
|
|
23
|
-
this.resetMetrics();
|
|
24
|
-
this.log(`Starting task: ${task.id}`);
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
// Spawn single agent with full task
|
|
28
|
-
const result = await this.orchestrator.spawn({
|
|
29
|
-
name: 'SoloAgent',
|
|
30
|
-
cli: this.config.cli,
|
|
31
|
-
task: this.buildTaskPrompt(task),
|
|
32
|
-
cwd: this.config.cwd,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (!result.success) {
|
|
36
|
-
this.metrics.errors.push(result.error || 'Spawn failed');
|
|
37
|
-
return this.buildFailedResult(task, startTime, this.metrics.errors);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.metrics.spawnedAgents.push('SoloAgent');
|
|
41
|
-
firstActionTime = Date.now() - startTime;
|
|
42
|
-
this.log(`Agent spawned in ${firstActionTime}ms`);
|
|
43
|
-
|
|
44
|
-
// Wait for completion signal
|
|
45
|
-
success = await this.waitForCompletion('SoloAgent', task);
|
|
46
|
-
|
|
47
|
-
if (success) {
|
|
48
|
-
this.log('Task completed successfully');
|
|
49
|
-
} else {
|
|
50
|
-
this.log('Task failed or timed out');
|
|
51
|
-
}
|
|
52
|
-
} catch (err) {
|
|
53
|
-
this.metrics.errors.push((err as Error).message);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Collect final metrics
|
|
57
|
-
let totalTokens = 0;
|
|
58
|
-
let peakMemory = 0;
|
|
59
|
-
try {
|
|
60
|
-
const metrics = await this.orchestrator.getMetrics();
|
|
61
|
-
totalTokens = this.extractTokens(metrics);
|
|
62
|
-
peakMemory = this.extractMemory(metrics);
|
|
63
|
-
} catch {
|
|
64
|
-
// Metrics collection failed, use defaults
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const completedAt = Date.now();
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
taskId: task.id,
|
|
71
|
-
configuration: 'single',
|
|
72
|
-
totalTimeMs: completedAt - startTime,
|
|
73
|
-
timeToFirstActionMs: firstActionTime,
|
|
74
|
-
messageCount: 0, // No inter-agent communication
|
|
75
|
-
avgLatencyMs: 0,
|
|
76
|
-
latencyP50Ms: 0,
|
|
77
|
-
latencyP99Ms: 0,
|
|
78
|
-
coordinationRounds: 0,
|
|
79
|
-
agentCount: 1,
|
|
80
|
-
totalTokensUsed: totalTokens,
|
|
81
|
-
peakMemoryMb: peakMemory,
|
|
82
|
-
success,
|
|
83
|
-
completionRate: success ? 1.0 : 0.0,
|
|
84
|
-
errors: this.metrics.errors,
|
|
85
|
-
startedAt: startTime,
|
|
86
|
-
completedAt,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Build the task prompt for a single agent
|
|
92
|
-
*/
|
|
93
|
-
private buildTaskPrompt(task: Task): string {
|
|
94
|
-
return `Complete this task entirely on your own:
|
|
95
|
-
|
|
96
|
-
## Task
|
|
97
|
-
${task.description}
|
|
98
|
-
|
|
99
|
-
## Files to Work On
|
|
100
|
-
${task.files.map((f) => `- ${f}`).join('\n')}
|
|
101
|
-
|
|
102
|
-
## Success Criteria
|
|
103
|
-
${task.expectedOutcome}
|
|
104
|
-
|
|
105
|
-
## Instructions
|
|
106
|
-
1. Analyze the task requirements
|
|
107
|
-
2. Plan your approach
|
|
108
|
-
3. Implement the solution
|
|
109
|
-
4. Verify your work meets the success criteria
|
|
110
|
-
|
|
111
|
-
When complete, send a message to Orchestrator:
|
|
112
|
-
\`\`\`
|
|
113
|
-
DONE: <brief summary of what you accomplished>
|
|
114
|
-
\`\`\`
|
|
115
|
-
|
|
116
|
-
If you encounter an error you cannot resolve:
|
|
117
|
-
\`\`\`
|
|
118
|
-
ERROR: <description of the problem>
|
|
119
|
-
\`\`\``;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sub-Agent Runner
|
|
3
|
-
*
|
|
4
|
-
* Runs tasks using a lead agent that spawns and coordinates workers hierarchically.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Task, RunResult, ConfigurationType } from '../types.js';
|
|
8
|
-
import { ConfigurationRunner } from './base.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Runner for sub-agent (hierarchical) configuration
|
|
12
|
-
*/
|
|
13
|
-
export class SubAgentRunner extends ConfigurationRunner {
|
|
14
|
-
private workerCount = 0;
|
|
15
|
-
|
|
16
|
-
get configurationType(): ConfigurationType {
|
|
17
|
-
return 'subagent';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async run(task: Task): Promise<RunResult> {
|
|
21
|
-
const startTime = Date.now();
|
|
22
|
-
let firstActionTime = 0;
|
|
23
|
-
let success = false;
|
|
24
|
-
|
|
25
|
-
this.resetMetrics();
|
|
26
|
-
this.workerCount = 0;
|
|
27
|
-
this.log(`Starting task: ${task.id}`);
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
// Set up message monitoring before spawning
|
|
31
|
-
this.setupMessageMonitoring();
|
|
32
|
-
|
|
33
|
-
// Spawn lead agent that will delegate to workers
|
|
34
|
-
const leadResult = await this.orchestrator.spawn({
|
|
35
|
-
name: 'Lead',
|
|
36
|
-
cli: this.config.cli,
|
|
37
|
-
task: this.buildLeadPrompt(task),
|
|
38
|
-
cwd: this.config.cwd,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
if (!leadResult.success) {
|
|
42
|
-
this.metrics.errors.push(leadResult.error || 'Lead spawn failed');
|
|
43
|
-
return this.buildFailedResult(task, startTime, this.metrics.errors);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
this.metrics.spawnedAgents.push('Lead');
|
|
47
|
-
firstActionTime = Date.now() - startTime;
|
|
48
|
-
this.log(`Lead agent spawned in ${firstActionTime}ms`);
|
|
49
|
-
|
|
50
|
-
// Wait for lead to complete (including all worker coordination)
|
|
51
|
-
success = await this.waitForLeadCompletion(task);
|
|
52
|
-
|
|
53
|
-
if (success) {
|
|
54
|
-
this.log(`Task completed with ${this.workerCount} workers`);
|
|
55
|
-
} else {
|
|
56
|
-
this.log('Task failed or timed out');
|
|
57
|
-
}
|
|
58
|
-
} catch (err) {
|
|
59
|
-
this.metrics.errors.push((err as Error).message);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Collect final metrics
|
|
63
|
-
let totalTokens = 0;
|
|
64
|
-
let peakMemory = 0;
|
|
65
|
-
try {
|
|
66
|
-
const metrics = await this.orchestrator.getMetrics();
|
|
67
|
-
totalTokens = this.extractTokens(metrics);
|
|
68
|
-
peakMemory = this.extractMemory(metrics);
|
|
69
|
-
} catch {
|
|
70
|
-
// Metrics collection failed
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const completedAt = Date.now();
|
|
74
|
-
const agentCount = 1 + this.workerCount;
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
taskId: task.id,
|
|
78
|
-
configuration: 'subagent',
|
|
79
|
-
totalTimeMs: completedAt - startTime,
|
|
80
|
-
timeToFirstActionMs: firstActionTime,
|
|
81
|
-
messageCount: this.metrics.messages,
|
|
82
|
-
avgLatencyMs:
|
|
83
|
-
this.metrics.latencies.length > 0
|
|
84
|
-
? this.metrics.latencies.reduce((a, b) => a + b, 0) /
|
|
85
|
-
this.metrics.latencies.length
|
|
86
|
-
: 0,
|
|
87
|
-
latencyP50Ms: this.percentile(this.metrics.latencies, 50),
|
|
88
|
-
latencyP99Ms: this.percentile(this.metrics.latencies, 99),
|
|
89
|
-
coordinationRounds: Math.ceil(
|
|
90
|
-
this.metrics.messages / Math.max(1, this.workerCount)
|
|
91
|
-
),
|
|
92
|
-
agentCount,
|
|
93
|
-
totalTokensUsed: totalTokens,
|
|
94
|
-
peakMemoryMb: peakMemory,
|
|
95
|
-
success,
|
|
96
|
-
completionRate: success ? 1.0 : this.workerCount > 0 ? 0.5 : 0.0,
|
|
97
|
-
errors: this.metrics.errors,
|
|
98
|
-
startedAt: startTime,
|
|
99
|
-
completedAt,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Set up message monitoring to track worker spawns and coordination
|
|
105
|
-
*/
|
|
106
|
-
private setupMessageMonitoring(): void {
|
|
107
|
-
this.orchestrator.onMessage = (from, payload, id, meta) => {
|
|
108
|
-
this.metrics.messages++;
|
|
109
|
-
|
|
110
|
-
// Track when lead spawns workers
|
|
111
|
-
if (from === 'Lead') {
|
|
112
|
-
// Check for spawn patterns in messages
|
|
113
|
-
if (
|
|
114
|
-
payload.body.includes('->relay-file:spawn') ||
|
|
115
|
-
typeof payload.data?.name === 'string'
|
|
116
|
-
) {
|
|
117
|
-
this.workerCount++;
|
|
118
|
-
const workerName =
|
|
119
|
-
(payload.data?.name as string) || `Worker${this.workerCount}`;
|
|
120
|
-
this.metrics.spawnedAgents.push(workerName);
|
|
121
|
-
this.log(`Worker spawned: ${workerName}`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Track latencies if we have sync metadata
|
|
126
|
-
if (meta?.sync?.correlationId) {
|
|
127
|
-
// This would require tracking send times, simplified here
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Wait for the lead agent to signal completion
|
|
134
|
-
*/
|
|
135
|
-
private waitForLeadCompletion(task: Task): Promise<boolean> {
|
|
136
|
-
const timeoutMs = task.timeoutMs || 300000;
|
|
137
|
-
|
|
138
|
-
return new Promise((resolve) => {
|
|
139
|
-
const timeout = setTimeout(() => {
|
|
140
|
-
this.metrics.errors.push('Timeout waiting for Lead completion');
|
|
141
|
-
resolve(false);
|
|
142
|
-
}, timeoutMs);
|
|
143
|
-
|
|
144
|
-
const originalHandler = this.orchestrator.onMessage;
|
|
145
|
-
this.orchestrator.onMessage = (from, payload, id, meta, originalTo) => {
|
|
146
|
-
// Call existing handler for tracking
|
|
147
|
-
if (originalHandler) {
|
|
148
|
-
originalHandler(from, payload, id, meta, originalTo);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Check for completion from Lead
|
|
152
|
-
if (from === 'Lead' && payload.body.startsWith('DONE:')) {
|
|
153
|
-
clearTimeout(timeout);
|
|
154
|
-
resolve(true);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Check for fatal errors
|
|
158
|
-
if (from === 'Lead' && payload.body.startsWith('ERROR:')) {
|
|
159
|
-
this.metrics.errors.push(payload.body);
|
|
160
|
-
clearTimeout(timeout);
|
|
161
|
-
resolve(false);
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Build the task prompt for the lead agent
|
|
169
|
-
*/
|
|
170
|
-
private buildLeadPrompt(task: Task): string {
|
|
171
|
-
const suggestedWorkers = this.suggestWorkerCount(task);
|
|
172
|
-
|
|
173
|
-
return `You are the Lead agent. Your job is to delegate subtasks to workers and coordinate their efforts.
|
|
174
|
-
|
|
175
|
-
## Task
|
|
176
|
-
${task.description}
|
|
177
|
-
|
|
178
|
-
## Files to Work On
|
|
179
|
-
${task.files.map((f) => `- ${f}`).join('\n')}
|
|
180
|
-
|
|
181
|
-
## Success Criteria
|
|
182
|
-
${task.expectedOutcome}
|
|
183
|
-
|
|
184
|
-
## Your Responsibilities
|
|
185
|
-
|
|
186
|
-
1. **Analyze the task** and break it into subtasks
|
|
187
|
-
2. **Spawn workers** for each subtask (suggested: ${suggestedWorkers} workers)
|
|
188
|
-
3. **Coordinate** their work and handle dependencies
|
|
189
|
-
4. **Aggregate results** and verify success criteria are met
|
|
190
|
-
|
|
191
|
-
## Spawning Workers
|
|
192
|
-
|
|
193
|
-
Use the relay protocol to spawn workers:
|
|
194
|
-
|
|
195
|
-
\`\`\`bash
|
|
196
|
-
cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF'
|
|
197
|
-
KIND: spawn
|
|
198
|
-
NAME: Worker1
|
|
199
|
-
CLI: ${this.config.cli}
|
|
200
|
-
|
|
201
|
-
<Task description for this worker>
|
|
202
|
-
EOF
|
|
203
|
-
\`\`\`
|
|
204
|
-
Then output: ->relay-file:spawn
|
|
205
|
-
|
|
206
|
-
## Communication Protocol
|
|
207
|
-
|
|
208
|
-
- Workers will send you status updates
|
|
209
|
-
- Monitor for "DONE:" messages from workers
|
|
210
|
-
- Handle "BLOCKED:" or "ERROR:" messages by reassigning or helping
|
|
211
|
-
|
|
212
|
-
## Completion
|
|
213
|
-
|
|
214
|
-
When ALL subtasks are complete and verified:
|
|
215
|
-
\`\`\`
|
|
216
|
-
DONE: <summary of what was accomplished, including worker contributions>
|
|
217
|
-
\`\`\`
|
|
218
|
-
|
|
219
|
-
If you encounter an unrecoverable error:
|
|
220
|
-
\`\`\`
|
|
221
|
-
ERROR: <description of the problem>
|
|
222
|
-
\`\`\``;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Suggest number of workers based on task complexity
|
|
227
|
-
*/
|
|
228
|
-
private suggestWorkerCount(task: Task): number {
|
|
229
|
-
switch (task.complexity) {
|
|
230
|
-
case 'low':
|
|
231
|
-
return Math.min(2, task.files.length);
|
|
232
|
-
case 'medium':
|
|
233
|
-
return Math.min(3, task.files.length);
|
|
234
|
-
case 'high':
|
|
235
|
-
return Math.min(5, task.files.length, this.config.maxSwarmSize);
|
|
236
|
-
default:
|
|
237
|
-
return 2;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swarm Runner
|
|
3
|
-
*
|
|
4
|
-
* Runs tasks using peer agents that coordinate as equals via messaging.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Task, RunResult, ConfigurationType } from '../types.js';
|
|
8
|
-
import { ConfigurationRunner } from './base.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Runner for swarm (peer-to-peer) configuration
|
|
12
|
-
*/
|
|
13
|
-
export class SwarmRunner extends ConfigurationRunner {
|
|
14
|
-
private completedPeers = new Set<string>();
|
|
15
|
-
|
|
16
|
-
get configurationType(): ConfigurationType {
|
|
17
|
-
return 'swarm';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async run(task: Task): Promise<RunResult> {
|
|
21
|
-
const startTime = Date.now();
|
|
22
|
-
let firstActionTime = 0;
|
|
23
|
-
let success = false;
|
|
24
|
-
|
|
25
|
-
this.resetMetrics();
|
|
26
|
-
this.completedPeers.clear();
|
|
27
|
-
this.log(`Starting task: ${task.id}`);
|
|
28
|
-
|
|
29
|
-
// Determine swarm size based on task complexity
|
|
30
|
-
const agentCount = this.determineSwarmSize(task);
|
|
31
|
-
const peerNames: string[] = [];
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
// Set up channel monitoring
|
|
35
|
-
this.setupChannelMonitoring();
|
|
36
|
-
|
|
37
|
-
// Partition task among peers
|
|
38
|
-
const subtasks = this.partitionTask(task, agentCount);
|
|
39
|
-
|
|
40
|
-
// Spawn peer agents simultaneously
|
|
41
|
-
this.log(`Spawning ${agentCount} peer agents...`);
|
|
42
|
-
const spawnPromises = subtasks.map((subtask, i) =>
|
|
43
|
-
this.orchestrator.spawn({
|
|
44
|
-
name: `Peer${i}`,
|
|
45
|
-
cli: this.config.cli,
|
|
46
|
-
task: this.buildPeerPrompt(subtask, i, agentCount, task),
|
|
47
|
-
cwd: this.config.cwd,
|
|
48
|
-
team: 'swarm',
|
|
49
|
-
})
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
const results = await Promise.all(spawnPromises);
|
|
53
|
-
firstActionTime = Date.now() - startTime;
|
|
54
|
-
this.log(`Peers spawned in ${firstActionTime}ms`);
|
|
55
|
-
|
|
56
|
-
// Track successful spawns
|
|
57
|
-
for (let i = 0; i < results.length; i++) {
|
|
58
|
-
if (results[i].success) {
|
|
59
|
-
peerNames.push(`Peer${i}`);
|
|
60
|
-
this.metrics.spawnedAgents.push(`Peer${i}`);
|
|
61
|
-
} else {
|
|
62
|
-
this.metrics.errors.push(
|
|
63
|
-
`Peer${i} spawn failed: ${results[i].error}`
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (peerNames.length === 0) {
|
|
69
|
-
return this.buildFailedResult(task, startTime, this.metrics.errors);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Have orchestrator join #swarm channel to monitor
|
|
73
|
-
this.orchestrator.joinChannel('#swarm');
|
|
74
|
-
|
|
75
|
-
// Wait for swarm consensus on completion
|
|
76
|
-
success = await this.waitForSwarmCompletion(peerNames, task);
|
|
77
|
-
|
|
78
|
-
if (success) {
|
|
79
|
-
this.log(
|
|
80
|
-
`Task completed by swarm of ${peerNames.length} peers`
|
|
81
|
-
);
|
|
82
|
-
} else {
|
|
83
|
-
this.log(
|
|
84
|
-
`Swarm completed ${this.completedPeers.size}/${peerNames.length} subtasks`
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
} catch (err) {
|
|
88
|
-
this.metrics.errors.push((err as Error).message);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Collect final metrics
|
|
92
|
-
let totalTokens = 0;
|
|
93
|
-
let peakMemory = 0;
|
|
94
|
-
try {
|
|
95
|
-
const metrics = await this.orchestrator.getMetrics();
|
|
96
|
-
totalTokens = this.extractTokens(metrics);
|
|
97
|
-
peakMemory = this.extractMemory(metrics);
|
|
98
|
-
} catch {
|
|
99
|
-
// Metrics collection failed
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const completedAt = Date.now();
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
taskId: task.id,
|
|
106
|
-
configuration: 'swarm',
|
|
107
|
-
totalTimeMs: completedAt - startTime,
|
|
108
|
-
timeToFirstActionMs: firstActionTime,
|
|
109
|
-
messageCount: this.metrics.messages,
|
|
110
|
-
avgLatencyMs:
|
|
111
|
-
this.metrics.latencies.length > 0
|
|
112
|
-
? this.metrics.latencies.reduce((a, b) => a + b, 0) /
|
|
113
|
-
this.metrics.latencies.length
|
|
114
|
-
: 0,
|
|
115
|
-
latencyP50Ms: this.percentile(this.metrics.latencies, 50),
|
|
116
|
-
latencyP99Ms: this.percentile(this.metrics.latencies, 99),
|
|
117
|
-
coordinationRounds: Math.ceil(
|
|
118
|
-
this.metrics.messages / Math.max(1, peerNames.length)
|
|
119
|
-
),
|
|
120
|
-
agentCount: peerNames.length,
|
|
121
|
-
totalTokensUsed: totalTokens,
|
|
122
|
-
peakMemoryMb: peakMemory,
|
|
123
|
-
success,
|
|
124
|
-
completionRate: this.completedPeers.size / Math.max(1, peerNames.length),
|
|
125
|
-
errors: this.metrics.errors,
|
|
126
|
-
startedAt: startTime,
|
|
127
|
-
completedAt,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Set up channel message monitoring
|
|
133
|
-
*/
|
|
134
|
-
private setupChannelMonitoring(): void {
|
|
135
|
-
this.orchestrator.onChannelMessage = (from, channel, body, envelope) => {
|
|
136
|
-
this.metrics.messages++;
|
|
137
|
-
|
|
138
|
-
// Track completion announcements
|
|
139
|
-
if (channel === '#swarm' && body.startsWith('DONE:')) {
|
|
140
|
-
this.completedPeers.add(from);
|
|
141
|
-
this.log(`${from} completed: ${body.substring(5).trim()}`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Track errors
|
|
145
|
-
if (body.startsWith('ERROR:') || body.startsWith('BLOCKED:')) {
|
|
146
|
-
this.metrics.errors.push(`${from}: ${body}`);
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
this.orchestrator.onMessage = (from, payload, id, meta, originalTo) => {
|
|
151
|
-
this.metrics.messages++;
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Determine swarm size based on task complexity and files
|
|
157
|
-
*/
|
|
158
|
-
private determineSwarmSize(task: Task): number {
|
|
159
|
-
let baseSize: number;
|
|
160
|
-
switch (task.complexity) {
|
|
161
|
-
case 'low':
|
|
162
|
-
baseSize = 2;
|
|
163
|
-
break;
|
|
164
|
-
case 'medium':
|
|
165
|
-
baseSize = 3;
|
|
166
|
-
break;
|
|
167
|
-
case 'high':
|
|
168
|
-
baseSize = 5;
|
|
169
|
-
break;
|
|
170
|
-
default:
|
|
171
|
-
baseSize = 3;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Don't have more agents than files
|
|
175
|
-
const fileCount = task.files.length;
|
|
176
|
-
const size = Math.min(baseSize, fileCount, this.config.maxSwarmSize);
|
|
177
|
-
|
|
178
|
-
return Math.max(2, size); // At least 2 for swarm
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Partition task files among agents
|
|
183
|
-
*/
|
|
184
|
-
private partitionTask(task: Task, count: number): Task[] {
|
|
185
|
-
const filesPerAgent = Math.ceil(task.files.length / count);
|
|
186
|
-
const subtasks: Task[] = [];
|
|
187
|
-
|
|
188
|
-
for (let i = 0; i < count; i++) {
|
|
189
|
-
const start = i * filesPerAgent;
|
|
190
|
-
const files = task.files.slice(start, start + filesPerAgent);
|
|
191
|
-
|
|
192
|
-
// Handle case where we have more agents than files
|
|
193
|
-
if (files.length === 0) continue;
|
|
194
|
-
|
|
195
|
-
subtasks.push({
|
|
196
|
-
...task,
|
|
197
|
-
id: `${task.id}-part${i}`,
|
|
198
|
-
files,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return subtasks;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Build prompt for a peer agent
|
|
207
|
-
*/
|
|
208
|
-
private buildPeerPrompt(
|
|
209
|
-
subtask: Task,
|
|
210
|
-
index: number,
|
|
211
|
-
totalPeers: number,
|
|
212
|
-
fullTask: Task
|
|
213
|
-
): string {
|
|
214
|
-
const otherPeers = Array.from({ length: totalPeers }, (_, i) => `Peer${i}`)
|
|
215
|
-
.filter((_, i) => i !== index)
|
|
216
|
-
.join(', ');
|
|
217
|
-
|
|
218
|
-
return `You are Peer${index} in a swarm of ${totalPeers} peer agents working together.
|
|
219
|
-
|
|
220
|
-
## Your Subtask
|
|
221
|
-
Work on these files: ${subtask.files.map((f) => `\`${f}\``).join(', ')}
|
|
222
|
-
|
|
223
|
-
## Full Task Context
|
|
224
|
-
${fullTask.description}
|
|
225
|
-
|
|
226
|
-
## Success Criteria (for full task)
|
|
227
|
-
${fullTask.expectedOutcome}
|
|
228
|
-
|
|
229
|
-
## Peer Coordination
|
|
230
|
-
|
|
231
|
-
You are working alongside: ${otherPeers}
|
|
232
|
-
|
|
233
|
-
**Communication via #swarm channel:**
|
|
234
|
-
|
|
235
|
-
Share your progress:
|
|
236
|
-
\`\`\`bash
|
|
237
|
-
cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
|
|
238
|
-
TO: #swarm
|
|
239
|
-
|
|
240
|
-
STATUS: Working on <what you're doing>
|
|
241
|
-
EOF
|
|
242
|
-
\`\`\`
|
|
243
|
-
Then: ->relay-file:msg
|
|
244
|
-
|
|
245
|
-
Ask questions to the swarm:
|
|
246
|
-
\`\`\`bash
|
|
247
|
-
cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
|
|
248
|
-
TO: #swarm
|
|
249
|
-
|
|
250
|
-
QUESTION: <your question>
|
|
251
|
-
EOF
|
|
252
|
-
\`\`\`
|
|
253
|
-
Then: ->relay-file:msg
|
|
254
|
-
|
|
255
|
-
Report blockers:
|
|
256
|
-
\`\`\`bash
|
|
257
|
-
cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
|
|
258
|
-
TO: #swarm
|
|
259
|
-
|
|
260
|
-
BLOCKED: <what's blocking you>
|
|
261
|
-
EOF
|
|
262
|
-
\`\`\`
|
|
263
|
-
Then: ->relay-file:msg
|
|
264
|
-
|
|
265
|
-
## Completion
|
|
266
|
-
|
|
267
|
-
When YOUR part is complete:
|
|
268
|
-
\`\`\`bash
|
|
269
|
-
cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
|
|
270
|
-
TO: #swarm
|
|
271
|
-
|
|
272
|
-
DONE: Peer${index} completed <brief summary>
|
|
273
|
-
EOF
|
|
274
|
-
\`\`\`
|
|
275
|
-
Then: ->relay-file:msg
|
|
276
|
-
|
|
277
|
-
## Guidelines
|
|
278
|
-
|
|
279
|
-
1. Focus on your assigned files
|
|
280
|
-
2. Coordinate with peers on shared interfaces/dependencies
|
|
281
|
-
3. Don't duplicate work - check the channel for updates
|
|
282
|
-
4. Help peers if they're blocked and you can assist`;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Wait for all peers to complete
|
|
287
|
-
*/
|
|
288
|
-
private waitForSwarmCompletion(
|
|
289
|
-
peers: string[],
|
|
290
|
-
task: Task
|
|
291
|
-
): Promise<boolean> {
|
|
292
|
-
const timeoutMs = task.timeoutMs || 300000;
|
|
293
|
-
|
|
294
|
-
return new Promise((resolve) => {
|
|
295
|
-
const timeout = setTimeout(() => {
|
|
296
|
-
this.metrics.errors.push(
|
|
297
|
-
`Swarm timeout: ${this.completedPeers.size}/${peers.length} completed`
|
|
298
|
-
);
|
|
299
|
-
resolve(false);
|
|
300
|
-
}, timeoutMs);
|
|
301
|
-
|
|
302
|
-
// Check periodically if all peers are done
|
|
303
|
-
const checkInterval = setInterval(() => {
|
|
304
|
-
if (this.completedPeers.size >= peers.length) {
|
|
305
|
-
clearInterval(checkInterval);
|
|
306
|
-
clearTimeout(timeout);
|
|
307
|
-
resolve(true);
|
|
308
|
-
}
|
|
309
|
-
}, 1000);
|
|
310
|
-
|
|
311
|
-
// Also check on each channel message
|
|
312
|
-
const originalHandler = this.orchestrator.onChannelMessage;
|
|
313
|
-
this.orchestrator.onChannelMessage = (from, channel, body, envelope) => {
|
|
314
|
-
if (originalHandler) {
|
|
315
|
-
originalHandler(from, channel, body, envelope);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (this.completedPeers.size >= peers.length) {
|
|
319
|
-
clearInterval(checkInterval);
|
|
320
|
-
clearTimeout(timeout);
|
|
321
|
-
resolve(true);
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
}
|