agent-relay 3.2.2 → 3.2.4
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/bin/agent-relay-broker-darwin-arm64 +0 -0
- package/bin/agent-relay-broker-darwin-x64 +0 -0
- package/bin/agent-relay-broker-linux-arm64 +0 -0
- package/bin/agent-relay-broker-linux-x64 +0 -0
- package/dist/index.cjs +1358 -941
- package/dist/src/cli/commands/agent-management.d.ts +2 -2
- package/dist/src/cli/commands/agent-management.d.ts.map +1 -1
- package/dist/src/cli/commands/agent-management.js +41 -240
- package/dist/src/cli/commands/agent-management.js.map +1 -1
- package/dist/src/cli/commands/messaging.d.ts +1 -1
- package/dist/src/cli/commands/messaging.d.ts.map +1 -1
- package/dist/src/cli/commands/messaging.js +14 -5
- package/dist/src/cli/commands/messaging.js.map +1 -1
- package/dist/src/cli/lib/agent-management-listing.d.ts +4 -1
- package/dist/src/cli/lib/agent-management-listing.d.ts.map +1 -1
- package/dist/src/cli/lib/agent-management-listing.js +27 -2
- package/dist/src/cli/lib/agent-management-listing.js.map +1 -1
- package/package.json +11 -10
- package/packages/acp-bridge/package.json +2 -2
- package/packages/config/package.json +1 -1
- package/packages/hooks/package.json +4 -4
- package/packages/memory/package.json +2 -2
- package/packages/openclaw/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/sdk/ADAPTER_REVIEW.md +109 -0
- package/packages/sdk/dist/client.d.ts +66 -0
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +230 -0
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/communicate/a2a-bridge.d.ts +25 -0
- package/packages/sdk/dist/communicate/a2a-bridge.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/a2a-bridge.js +89 -0
- package/packages/sdk/dist/communicate/a2a-bridge.js.map +1 -0
- package/packages/sdk/dist/communicate/a2a-server.d.ts +31 -0
- package/packages/sdk/dist/communicate/a2a-server.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/a2a-server.js +220 -0
- package/packages/sdk/dist/communicate/a2a-server.js.map +1 -0
- package/packages/sdk/dist/communicate/a2a-transport.d.ts +48 -0
- package/packages/sdk/dist/communicate/a2a-transport.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/a2a-transport.js +302 -0
- package/packages/sdk/dist/communicate/a2a-transport.js.map +1 -0
- package/packages/sdk/dist/communicate/a2a-types.d.ts +107 -0
- package/packages/sdk/dist/communicate/a2a-types.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/a2a-types.js +209 -0
- package/packages/sdk/dist/communicate/a2a-types.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/claude-sdk.d.ts +28 -0
- package/packages/sdk/dist/communicate/adapters/claude-sdk.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/claude-sdk.js +47 -0
- package/packages/sdk/dist/communicate/adapters/claude-sdk.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/crewai.d.ts +42 -0
- package/packages/sdk/dist/communicate/adapters/crewai.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/crewai.js +95 -0
- package/packages/sdk/dist/communicate/adapters/crewai.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/google-adk.d.ts +53 -0
- package/packages/sdk/dist/communicate/adapters/google-adk.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/google-adk.js +77 -0
- package/packages/sdk/dist/communicate/adapters/google-adk.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/index.d.ts +7 -0
- package/packages/sdk/dist/communicate/adapters/index.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/index.js +7 -0
- package/packages/sdk/dist/communicate/adapters/index.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/langgraph.d.ts +40 -0
- package/packages/sdk/dist/communicate/adapters/langgraph.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/langgraph.js +77 -0
- package/packages/sdk/dist/communicate/adapters/langgraph.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/openai-agents.d.ts +25 -0
- package/packages/sdk/dist/communicate/adapters/openai-agents.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/openai-agents.js +70 -0
- package/packages/sdk/dist/communicate/adapters/openai-agents.js.map +1 -0
- package/packages/sdk/dist/communicate/adapters/pi.d.ts +45 -0
- package/packages/sdk/dist/communicate/adapters/pi.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/adapters/pi.js +59 -0
- package/packages/sdk/dist/communicate/adapters/pi.js.map +1 -0
- package/packages/sdk/dist/communicate/core.d.ts +58 -0
- package/packages/sdk/dist/communicate/core.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/core.js +128 -0
- package/packages/sdk/dist/communicate/core.js.map +1 -0
- package/packages/sdk/dist/communicate/index.d.ts +4 -0
- package/packages/sdk/dist/communicate/index.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/index.js +4 -0
- package/packages/sdk/dist/communicate/index.js.map +1 -0
- package/packages/sdk/dist/communicate/transport.d.ts +36 -0
- package/packages/sdk/dist/communicate/transport.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/transport.js +371 -0
- package/packages/sdk/dist/communicate/transport.js.map +1 -0
- package/packages/sdk/dist/communicate/types.d.ts +58 -0
- package/packages/sdk/dist/communicate/types.d.ts.map +1 -0
- package/packages/sdk/dist/communicate/types.js +66 -0
- package/packages/sdk/dist/communicate/types.js.map +1 -0
- package/packages/sdk/dist/workflows/builder.d.ts +35 -5
- package/packages/sdk/dist/workflows/builder.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/builder.js +81 -7
- package/packages/sdk/dist/workflows/builder.js.map +1 -1
- package/packages/sdk/dist/workflows/cli.js +14 -1
- package/packages/sdk/dist/workflows/cli.js.map +1 -1
- package/packages/sdk/dist/workflows/runner.d.ts +10 -2
- package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/runner.js +95 -1
- package/packages/sdk/dist/workflows/runner.js.map +1 -1
- package/packages/sdk/dist/workflows/types.d.ts +11 -0
- package/packages/sdk/dist/workflows/types.d.ts.map +1 -1
- package/packages/sdk/examples/communicate/claude_sdk_example.ts +5 -0
- package/packages/sdk/examples/communicate/pi_example.ts +8 -0
- package/packages/sdk/package.json +48 -2
- package/packages/sdk/src/__tests__/builder-deterministic.test.ts +132 -0
- package/packages/sdk/src/__tests__/communicate/a2a-bridge.test.ts +211 -0
- package/packages/sdk/src/__tests__/communicate/a2a-server.test.ts +359 -0
- package/packages/sdk/src/__tests__/communicate/a2a-transport.test.ts +537 -0
- package/packages/sdk/src/__tests__/communicate/a2a-types.test.ts +297 -0
- package/packages/sdk/src/__tests__/communicate/adapters/claude-sdk.test.ts +163 -0
- package/packages/sdk/src/__tests__/communicate/adapters/crewai.test.ts +219 -0
- package/packages/sdk/src/__tests__/communicate/adapters/e2e-crewai.test.ts +101 -0
- package/packages/sdk/src/__tests__/communicate/adapters/e2e-google-adk.test.ts +166 -0
- package/packages/sdk/src/__tests__/communicate/adapters/e2e-langgraph.test.ts +181 -0
- package/packages/sdk/src/__tests__/communicate/adapters/e2e-openai-agents.test.ts +137 -0
- package/packages/sdk/src/__tests__/communicate/adapters/e2e-pi.test.ts +140 -0
- package/packages/sdk/src/__tests__/communicate/adapters/google-adk.test.ts +200 -0
- package/packages/sdk/src/__tests__/communicate/adapters/langgraph.test.ts +162 -0
- package/packages/sdk/src/__tests__/communicate/adapters/openai-agents.test.ts +166 -0
- package/packages/sdk/src/__tests__/communicate/adapters/pi.test.ts +140 -0
- package/packages/sdk/src/__tests__/communicate/core.test.ts +574 -0
- package/packages/sdk/src/__tests__/communicate/integration/cross-framework.test.ts +353 -0
- package/packages/sdk/src/__tests__/communicate/transport.test.ts +613 -0
- package/packages/sdk/src/__tests__/start-from.test.ts +346 -0
- package/packages/sdk/src/client.ts +301 -0
- package/packages/sdk/src/communicate/a2a-bridge.ts +111 -0
- package/packages/sdk/src/communicate/a2a-server.ts +277 -0
- package/packages/sdk/src/communicate/a2a-transport.ts +395 -0
- package/packages/sdk/src/communicate/a2a-types.ts +338 -0
- package/packages/sdk/src/communicate/adapters/claude-sdk.ts +85 -0
- package/packages/sdk/src/communicate/adapters/crewai.ts +141 -0
- package/packages/sdk/src/communicate/adapters/google-adk.ts +139 -0
- package/packages/sdk/src/communicate/adapters/index.ts +6 -0
- package/packages/sdk/src/communicate/adapters/langgraph.ts +112 -0
- package/packages/sdk/src/communicate/adapters/openai-agents.ts +113 -0
- package/packages/sdk/src/communicate/adapters/pi.ts +105 -0
- package/packages/sdk/src/communicate/core.ts +157 -0
- package/packages/sdk/src/communicate/index.ts +3 -0
- package/packages/sdk/src/communicate/transport.ts +489 -0
- package/packages/sdk/src/communicate/types.ts +106 -0
- package/packages/sdk/src/examples/workflows/fix-dashboard-user-registration.yaml +182 -0
- package/packages/sdk/src/workflows/builder.ts +97 -9
- package/packages/sdk/src/workflows/cli.ts +16 -1
- package/packages/sdk/src/workflows/runner.ts +110 -1
- package/packages/sdk/src/workflows/types.ts +14 -0
- package/packages/sdk/tsconfig.build.json +1 -7
- package/packages/sdk/tsconfig.json +1 -7
- package/packages/sdk-py/README.md +67 -25
- package/packages/sdk-py/examples/communicate/agno_example.py +8 -0
- package/packages/sdk-py/examples/communicate/claude_sdk_example.py +6 -0
- package/packages/sdk-py/examples/communicate/crewai_example.py +7 -0
- package/packages/sdk-py/examples/communicate/google_adk_example.py +7 -0
- package/packages/sdk-py/examples/communicate/openai_agents_example.py +8 -0
- package/packages/sdk-py/examples/communicate/swarms_example.py +7 -0
- package/packages/sdk-py/pyproject.toml +12 -1
- package/packages/sdk-py/src/agent_relay/__init__.py +8 -0
- package/packages/sdk-py/src/agent_relay/builder.py +65 -26
- package/packages/sdk-py/src/agent_relay/communicate/__init__.py +6 -0
- package/packages/sdk-py/src/agent_relay/communicate/a2a_bridge.py +138 -0
- package/packages/sdk-py/src/agent_relay/communicate/a2a_server.py +242 -0
- package/packages/sdk-py/src/agent_relay/communicate/a2a_transport.py +366 -0
- package/packages/sdk-py/src/agent_relay/communicate/a2a_types.py +294 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/__init__.py +10 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/agno.py +74 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/claude_sdk.py +78 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/crewai.py +143 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/google_adk.py +69 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/openai_agents.py +86 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/pi.py +175 -0
- package/packages/sdk-py/src/agent_relay/communicate/adapters/swarms.py +44 -0
- package/packages/sdk-py/src/agent_relay/communicate/core.py +293 -0
- package/packages/sdk-py/src/agent_relay/communicate/transport.py +502 -0
- package/packages/sdk-py/src/agent_relay/communicate/types.py +89 -0
- package/packages/sdk-py/src/agent_relay/types.py +2 -1
- package/packages/sdk-py/tests/communicate/__init__.py +0 -0
- package/packages/sdk-py/tests/communicate/adapters/__init__.py +0 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_agno.py +154 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_claude_sdk.py +428 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_crewai.py +234 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_google_adk.py +182 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_langgraph.py +262 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_openai_agents.py +88 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_pi.py +156 -0
- package/packages/sdk-py/tests/communicate/adapters/e2e_test_swarms.py +239 -0
- package/packages/sdk-py/tests/communicate/adapters/test_agno.py +140 -0
- package/packages/sdk-py/tests/communicate/adapters/test_claude_sdk.py +147 -0
- package/packages/sdk-py/tests/communicate/adapters/test_crewai.py +136 -0
- package/packages/sdk-py/tests/communicate/adapters/test_google_adk.py +125 -0
- package/packages/sdk-py/tests/communicate/adapters/test_openai_agents.py +99 -0
- package/packages/sdk-py/tests/communicate/adapters/test_pi.py +270 -0
- package/packages/sdk-py/tests/communicate/adapters/test_swarms.py +113 -0
- package/packages/sdk-py/tests/communicate/conftest.py +555 -0
- package/packages/sdk-py/tests/communicate/integration/__init__.py +1 -0
- package/packages/sdk-py/tests/communicate/integration/test_cross_framework.py +331 -0
- package/packages/sdk-py/tests/communicate/integration/test_end_to_end.py +151 -0
- package/packages/sdk-py/tests/communicate/test_a2a_bridge.py +363 -0
- package/packages/sdk-py/tests/communicate/test_a2a_server.py +346 -0
- package/packages/sdk-py/tests/communicate/test_a2a_transport.py +561 -0
- package/packages/sdk-py/tests/communicate/test_a2a_types.py +342 -0
- package/packages/sdk-py/tests/communicate/test_auto_detect.py +67 -0
- package/packages/sdk-py/tests/communicate/test_core.py +331 -0
- package/packages/sdk-py/tests/communicate/test_transport.py +373 -0
- package/packages/sdk-py/tests/communicate/test_types.py +285 -0
- package/packages/sdk-py/tests/test_builder_deterministic.py +118 -0
- 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 +2 -2
- package/packages/sdk/dist/__tests__/completion-pipeline.test.d.ts +0 -14
- package/packages/sdk/dist/__tests__/completion-pipeline.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/completion-pipeline.test.js +0 -1476
- package/packages/sdk/dist/__tests__/completion-pipeline.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/contract-fixtures.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/contract-fixtures.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/contract-fixtures.test.js +0 -152
- package/packages/sdk/dist/__tests__/contract-fixtures.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/e2e-owner-review.test.d.ts +0 -16
- package/packages/sdk/dist/__tests__/e2e-owner-review.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/e2e-owner-review.test.js +0 -640
- package/packages/sdk/dist/__tests__/e2e-owner-review.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/facade.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/facade.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/facade.test.js +0 -305
- package/packages/sdk/dist/__tests__/facade.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/integration.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/integration.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/integration.test.js +0 -205
- package/packages/sdk/dist/__tests__/integration.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/pty.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/pty.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/pty.test.js +0 -20
- package/packages/sdk/dist/__tests__/pty.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/quickstart.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/quickstart.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/quickstart.test.js +0 -176
- package/packages/sdk/dist/__tests__/quickstart.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/spawn-from-env.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/spawn-from-env.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/spawn-from-env.test.js +0 -222
- package/packages/sdk/dist/__tests__/spawn-from-env.test.js.map +0 -1
- package/packages/sdk/dist/__tests__/unit.test.d.ts +0 -2
- package/packages/sdk/dist/__tests__/unit.test.d.ts.map +0 -1
- package/packages/sdk/dist/__tests__/unit.test.js +0 -357
- package/packages/sdk/dist/__tests__/unit.test.js.map +0 -1
- package/packages/sdk-py/agent_relay/__init__.py +0 -21
- package/packages/sdk-py/agent_relay/models.py +0 -398
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
version: '1.0'
|
|
2
|
+
name: fix-dashboard-user-registration
|
|
3
|
+
description: >
|
|
4
|
+
Fixes the dashboard agent registration so the user registers as the current
|
|
5
|
+
system user (whoami / os.userInfo().username) instead of the cwd directory name.
|
|
6
|
+
|
|
7
|
+
Currently, both relaycast-provider.ts and proxy-server.ts in relay-dashboard
|
|
8
|
+
derive projectIdentity from path.basename(path.resolve(dataDir, '..')) — which
|
|
9
|
+
gives the working directory name. This workflow changes both to use
|
|
10
|
+
os.userInfo().username so the registered name reflects the actual user.
|
|
11
|
+
|
|
12
|
+
swarm:
|
|
13
|
+
pattern: pipeline
|
|
14
|
+
channel: wf-fix-dashboard-user-reg
|
|
15
|
+
maxConcurrency: 3
|
|
16
|
+
timeoutMs: 1200000 # 20 min
|
|
17
|
+
|
|
18
|
+
agents:
|
|
19
|
+
- name: implementer
|
|
20
|
+
cli: claude
|
|
21
|
+
preset: worker
|
|
22
|
+
role: 'Makes targeted edits to two dashboard-server files to use os.userInfo().username instead of path.basename(cwd).'
|
|
23
|
+
constraints:
|
|
24
|
+
model: sonnet
|
|
25
|
+
|
|
26
|
+
- name: reviewer
|
|
27
|
+
cli: claude
|
|
28
|
+
preset: reviewer
|
|
29
|
+
role: 'Reviews the diff to confirm correctness and no unintended side effects.'
|
|
30
|
+
constraints:
|
|
31
|
+
model: sonnet
|
|
32
|
+
|
|
33
|
+
workflows:
|
|
34
|
+
- name: default
|
|
35
|
+
onError: fail-fast
|
|
36
|
+
|
|
37
|
+
steps:
|
|
38
|
+
# ── Phase 1: Capture current code for context injection ──────────────────
|
|
39
|
+
|
|
40
|
+
- name: read-relaycast-provider
|
|
41
|
+
type: deterministic
|
|
42
|
+
command: >
|
|
43
|
+
sed -n '1,15p' ../relay-dashboard/packages/dashboard-server/src/relaycast-provider.ts &&
|
|
44
|
+
echo "---" &&
|
|
45
|
+
sed -n '80,100p' ../relay-dashboard/packages/dashboard-server/src/relaycast-provider.ts
|
|
46
|
+
captureOutput: true
|
|
47
|
+
failOnError: true
|
|
48
|
+
|
|
49
|
+
- name: read-proxy-server
|
|
50
|
+
type: deterministic
|
|
51
|
+
command: >
|
|
52
|
+
grep -n "^import" ../relay-dashboard/packages/dashboard-server/src/proxy-server.ts | head -20 &&
|
|
53
|
+
echo "---" &&
|
|
54
|
+
sed -n '205,220p' ../relay-dashboard/packages/dashboard-server/src/proxy-server.ts
|
|
55
|
+
captureOutput: true
|
|
56
|
+
failOnError: true
|
|
57
|
+
|
|
58
|
+
# ── Phase 2: Implement the fix ───────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
- name: implement
|
|
61
|
+
type: agent
|
|
62
|
+
agent: implementer
|
|
63
|
+
dependsOn: [read-relaycast-provider, read-proxy-server]
|
|
64
|
+
task: |
|
|
65
|
+
Fix two files in the relay-dashboard package so the dashboard user registers
|
|
66
|
+
with the system username instead of the cwd directory name.
|
|
67
|
+
|
|
68
|
+
── File 1: ../relay-dashboard/packages/dashboard-server/src/relaycast-provider.ts ──
|
|
69
|
+
|
|
70
|
+
Current imports and loadRelaycastConfig function:
|
|
71
|
+
{{steps.read-relaycast-provider.output}}
|
|
72
|
+
|
|
73
|
+
Changes required:
|
|
74
|
+
1. Add `import os from 'node:os';` after the existing `import path from 'path';` line.
|
|
75
|
+
2. In the `loadRelaycastConfig` function, replace:
|
|
76
|
+
const projectDir = path.basename(path.resolve(dataDir, '..'));
|
|
77
|
+
with:
|
|
78
|
+
const projectIdentity = os.userInfo().username;
|
|
79
|
+
3. Remove the line `const projectIdentity = projectDir.trim();` (it's now set above).
|
|
80
|
+
4. The return statement `return { apiKey: envApiKey, baseUrl, projectIdentity };` stays the same.
|
|
81
|
+
|
|
82
|
+
── File 2: ../relay-dashboard/packages/dashboard-server/src/proxy-server.ts ──
|
|
83
|
+
|
|
84
|
+
Current imports and resolveRelaycastConfig function:
|
|
85
|
+
{{steps.read-proxy-server.output}}
|
|
86
|
+
|
|
87
|
+
Changes required:
|
|
88
|
+
1. Add `import os from 'node:os';` near the top of the file with the other imports.
|
|
89
|
+
2. In the `resolveRelaycastConfig` function, replace:
|
|
90
|
+
const projectDir = path.basename(path.resolve(dataDir, '..'));
|
|
91
|
+
with:
|
|
92
|
+
const projectIdentity = os.userInfo().username;
|
|
93
|
+
3. Update the `applyCachedAgentIdentity` call: change `projectIdentity: projectDir`
|
|
94
|
+
to `projectIdentity: projectIdentity` (variable is already named correctly).
|
|
95
|
+
|
|
96
|
+
IMPORTANT:
|
|
97
|
+
- Write both files to disk using your file-writing tools.
|
|
98
|
+
- Use `import os from 'node:os'` (Node.js built-in with node: prefix).
|
|
99
|
+
- Do not change anything else in either file.
|
|
100
|
+
- Preserve all existing imports, logic, and formatting.
|
|
101
|
+
verification:
|
|
102
|
+
type: exit_code
|
|
103
|
+
|
|
104
|
+
# ── Phase 3: Verify the changes look correct ─────────────────────────────
|
|
105
|
+
|
|
106
|
+
- name: verify-changes
|
|
107
|
+
type: deterministic
|
|
108
|
+
dependsOn: [implement]
|
|
109
|
+
command: |
|
|
110
|
+
echo "=== relaycast-provider.ts: os import ==="
|
|
111
|
+
grep -n "import os\|node:os" ../relay-dashboard/packages/dashboard-server/src/relaycast-provider.ts || echo "MISSING: os import"
|
|
112
|
+
|
|
113
|
+
echo ""
|
|
114
|
+
echo "=== relaycast-provider.ts: loadRelaycastConfig ==="
|
|
115
|
+
sed -n '85,96p' ../relay-dashboard/packages/dashboard-server/src/relaycast-provider.ts
|
|
116
|
+
|
|
117
|
+
echo ""
|
|
118
|
+
echo "=== proxy-server.ts: os import ==="
|
|
119
|
+
grep -n "import os\|node:os" ../relay-dashboard/packages/dashboard-server/src/proxy-server.ts || echo "MISSING: os import"
|
|
120
|
+
|
|
121
|
+
echo ""
|
|
122
|
+
echo "=== proxy-server.ts: resolveRelaycastConfig ==="
|
|
123
|
+
grep -n -A8 "const resolveRelaycastConfig" ../relay-dashboard/packages/dashboard-server/src/proxy-server.ts | head -15
|
|
124
|
+
|
|
125
|
+
echo ""
|
|
126
|
+
echo "=== Confirm no remaining path.basename(.*dataDir) calls ==="
|
|
127
|
+
grep -n "path.basename.*dataDir\|basename.*resolve.*dataDir" \
|
|
128
|
+
../relay-dashboard/packages/dashboard-server/src/relaycast-provider.ts \
|
|
129
|
+
../relay-dashboard/packages/dashboard-server/src/proxy-server.ts && echo "WARN: stale cwd reference found" || echo "OK: no stale cwd references"
|
|
130
|
+
captureOutput: true
|
|
131
|
+
failOnError: false
|
|
132
|
+
|
|
133
|
+
# ── Phase 4: Capture diff for review ─────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
- name: capture-diff
|
|
136
|
+
type: deterministic
|
|
137
|
+
dependsOn: [verify-changes]
|
|
138
|
+
command: >
|
|
139
|
+
cd ../relay-dashboard &&
|
|
140
|
+
git diff packages/dashboard-server/src/relaycast-provider.ts
|
|
141
|
+
packages/dashboard-server/src/proxy-server.ts
|
|
142
|
+
captureOutput: true
|
|
143
|
+
failOnError: false
|
|
144
|
+
|
|
145
|
+
# ── Phase 5: Code review ──────────────────────────────────────────────────
|
|
146
|
+
|
|
147
|
+
- name: review
|
|
148
|
+
type: agent
|
|
149
|
+
agent: reviewer
|
|
150
|
+
dependsOn: [capture-diff, verify-changes]
|
|
151
|
+
task: |
|
|
152
|
+
Review this change to the relay-dashboard dashboard-server package.
|
|
153
|
+
|
|
154
|
+
The goal: dashboard user now registers with os.userInfo().username (the system user
|
|
155
|
+
running the process) instead of path.basename(cwd) (the working directory name).
|
|
156
|
+
|
|
157
|
+
Verification output:
|
|
158
|
+
{{steps.verify-changes.output}}
|
|
159
|
+
|
|
160
|
+
Diff:
|
|
161
|
+
{{steps.capture-diff.output}}
|
|
162
|
+
|
|
163
|
+
Review checklist:
|
|
164
|
+
1. Both files now import `os` from `'node:os'` — correct prefix?
|
|
165
|
+
2. `os.userInfo().username` is used in both `loadRelaycastConfig` and
|
|
166
|
+
`resolveRelaycastConfig` — no leftover `path.basename` / `projectDir` references?
|
|
167
|
+
3. The `projectIdentity` variable name is preserved in both call sites?
|
|
168
|
+
4. No unintended whitespace, import order, or formatting changes?
|
|
169
|
+
5. The `path` import in relaycast-provider.ts is still present if used elsewhere in the file?
|
|
170
|
+
|
|
171
|
+
errorHandling:
|
|
172
|
+
strategy: fail-fast
|
|
173
|
+
maxRetries: 1
|
|
174
|
+
retryDelayMs: 5000
|
|
175
|
+
|
|
176
|
+
state:
|
|
177
|
+
backend: memory
|
|
178
|
+
ttlMs: 3600000 # 1 hour
|
|
179
|
+
|
|
180
|
+
trajectories:
|
|
181
|
+
enabled: true
|
|
182
|
+
autoDecisions: true
|
|
@@ -5,13 +5,18 @@ import type {
|
|
|
5
5
|
AgentCli,
|
|
6
6
|
AgentDefinition,
|
|
7
7
|
AgentPreset,
|
|
8
|
+
Barrier,
|
|
9
|
+
CoordinationConfig,
|
|
8
10
|
DryRunReport,
|
|
9
11
|
ErrorHandlingConfig,
|
|
10
12
|
IdleNudgeConfig,
|
|
11
13
|
RelayYamlConfig,
|
|
14
|
+
StateConfig,
|
|
12
15
|
SwarmPattern,
|
|
16
|
+
TrajectoryConfig,
|
|
13
17
|
VerificationCheck,
|
|
14
18
|
WorkflowDefinition,
|
|
19
|
+
WorkflowExecuteOptions,
|
|
15
20
|
WorkflowRunRow,
|
|
16
21
|
WorkflowStep,
|
|
17
22
|
} from './types.js';
|
|
@@ -52,15 +57,27 @@ export interface AgentStepOptions {
|
|
|
52
57
|
export interface DeterministicStepOptions {
|
|
53
58
|
type: 'deterministic';
|
|
54
59
|
command: string;
|
|
55
|
-
dependsOn?: string[];
|
|
56
|
-
/** Fail if command exit code is non-zero. Default: true. */
|
|
57
|
-
failOnError?: boolean;
|
|
58
60
|
/** Capture stdout as step output for downstream steps. Default: true. */
|
|
59
61
|
captureOutput?: boolean;
|
|
62
|
+
/** Fail if command exit code is non-zero. Default: true. */
|
|
63
|
+
failOnError?: boolean;
|
|
64
|
+
dependsOn?: string[];
|
|
65
|
+
verification?: VerificationCheck;
|
|
60
66
|
timeoutMs?: number;
|
|
61
67
|
}
|
|
62
68
|
|
|
63
|
-
|
|
69
|
+
/** Options for worktree steps (create/checkout git worktrees). */
|
|
70
|
+
export interface WorktreeStepOptions {
|
|
71
|
+
type: 'worktree';
|
|
72
|
+
branch: string;
|
|
73
|
+
baseBranch?: string;
|
|
74
|
+
path?: string;
|
|
75
|
+
createBranch?: boolean;
|
|
76
|
+
dependsOn?: string[];
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type StepOptions = AgentStepOptions | DeterministicStepOptions | WorktreeStepOptions;
|
|
64
81
|
|
|
65
82
|
export interface ErrorOptions {
|
|
66
83
|
maxRetries?: number;
|
|
@@ -83,6 +100,10 @@ export interface WorkflowRunOptions {
|
|
|
83
100
|
dryRun?: boolean;
|
|
84
101
|
/** External step executor (e.g. Daytona sandbox backend). */
|
|
85
102
|
executor?: StepExecutor;
|
|
103
|
+
/** Start from a specific step, skipping all predecessors. */
|
|
104
|
+
startFrom?: string;
|
|
105
|
+
/** Previous run ID whose cached outputs are used with startFrom. */
|
|
106
|
+
previousRunId?: string;
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
// ── WorkflowBuilder ─────────────────────────────────────────────────────────
|
|
@@ -113,6 +134,11 @@ export class WorkflowBuilder {
|
|
|
113
134
|
private _agents: AgentDefinition[] = [];
|
|
114
135
|
private _steps: WorkflowStep[] = [];
|
|
115
136
|
private _errorHandling?: ErrorHandlingConfig;
|
|
137
|
+
private _coordination?: CoordinationConfig;
|
|
138
|
+
private _state?: StateConfig;
|
|
139
|
+
private _trajectories?: TrajectoryConfig | false;
|
|
140
|
+
private _startFrom?: string;
|
|
141
|
+
private _previousRunId?: string;
|
|
116
142
|
|
|
117
143
|
constructor(name: string) {
|
|
118
144
|
this._name = name;
|
|
@@ -154,6 +180,36 @@ export class WorkflowBuilder {
|
|
|
154
180
|
return this;
|
|
155
181
|
}
|
|
156
182
|
|
|
183
|
+
/** Set workflow coordination settings (barriers, voting threshold, consensus strategy). */
|
|
184
|
+
coordination(config: CoordinationConfig): this {
|
|
185
|
+
this._coordination = config;
|
|
186
|
+
return this;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Configure shared workflow state backend settings. */
|
|
190
|
+
state(config: StateConfig): this {
|
|
191
|
+
this._state = config;
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Configure trajectory recording, or pass `false` to disable it. */
|
|
196
|
+
trajectories(config: TrajectoryConfig | false): this {
|
|
197
|
+
this._trajectories = config;
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Start execution from a specific step, skipping all predecessor steps. */
|
|
202
|
+
startFrom(stepName: string): this {
|
|
203
|
+
this._startFrom = stepName;
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Set the previous run ID whose cached step outputs should be used with startFrom. */
|
|
208
|
+
previousRunId(id: string): this {
|
|
209
|
+
this._previousRunId = id;
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
212
|
+
|
|
157
213
|
/** Add an agent definition. */
|
|
158
214
|
agent(name: string, options: AgentOptions): this {
|
|
159
215
|
const def: AgentDefinition = {
|
|
@@ -192,21 +248,44 @@ export class WorkflowBuilder {
|
|
|
192
248
|
const step: WorkflowStep = { name };
|
|
193
249
|
|
|
194
250
|
if ('type' in options && options.type === 'deterministic') {
|
|
251
|
+
if (!options.command) {
|
|
252
|
+
throw new Error('deterministic steps must have a command');
|
|
253
|
+
}
|
|
254
|
+
if ('agent' in options || 'task' in options) {
|
|
255
|
+
throw new Error('deterministic steps must not have agent or task');
|
|
256
|
+
}
|
|
195
257
|
step.type = 'deterministic';
|
|
196
258
|
step.command = options.command;
|
|
197
|
-
if (options.failOnError !== undefined) step.failOnError = options.failOnError;
|
|
198
259
|
if (options.captureOutput !== undefined) step.captureOutput = options.captureOutput;
|
|
260
|
+
if (options.failOnError !== undefined) step.failOnError = options.failOnError;
|
|
261
|
+
if (options.dependsOn !== undefined) step.dependsOn = options.dependsOn;
|
|
262
|
+
if (options.verification !== undefined) step.verification = options.verification;
|
|
263
|
+
if (options.timeoutMs !== undefined) step.timeoutMs = options.timeoutMs;
|
|
264
|
+
} else if ('type' in options && options.type === 'worktree') {
|
|
265
|
+
if ('agent' in options || 'task' in options) {
|
|
266
|
+
throw new Error('worktree steps must not have agent or task');
|
|
267
|
+
}
|
|
268
|
+
step.type = 'worktree';
|
|
269
|
+
step.branch = options.branch;
|
|
270
|
+
if (options.baseBranch !== undefined) step.baseBranch = options.baseBranch;
|
|
271
|
+
if (options.path !== undefined) step.path = options.path;
|
|
272
|
+
if (options.createBranch !== undefined) step.createBranch = options.createBranch;
|
|
273
|
+
if (options.dependsOn !== undefined) step.dependsOn = options.dependsOn;
|
|
274
|
+
if (options.timeoutMs !== undefined) step.timeoutMs = options.timeoutMs;
|
|
199
275
|
} else {
|
|
276
|
+
// Agent step
|
|
200
277
|
const agentOpts = options as AgentStepOptions;
|
|
278
|
+
if (!agentOpts.agent || !agentOpts.task) {
|
|
279
|
+
throw new Error('Agent steps must have both agent and task');
|
|
280
|
+
}
|
|
201
281
|
step.agent = agentOpts.agent;
|
|
202
282
|
step.task = agentOpts.task;
|
|
283
|
+
if (agentOpts.dependsOn !== undefined) step.dependsOn = agentOpts.dependsOn;
|
|
203
284
|
if (agentOpts.verification !== undefined) step.verification = agentOpts.verification;
|
|
285
|
+
if (agentOpts.timeoutMs !== undefined) step.timeoutMs = agentOpts.timeoutMs;
|
|
204
286
|
if (agentOpts.retries !== undefined) step.retries = agentOpts.retries;
|
|
205
287
|
}
|
|
206
288
|
|
|
207
|
-
if (options.dependsOn !== undefined) step.dependsOn = options.dependsOn;
|
|
208
|
-
if (options.timeoutMs !== undefined) step.timeoutMs = options.timeoutMs;
|
|
209
|
-
|
|
210
289
|
this._steps.push(step);
|
|
211
290
|
return this;
|
|
212
291
|
}
|
|
@@ -251,6 +330,9 @@ export class WorkflowBuilder {
|
|
|
251
330
|
if (this._channel !== undefined) config.swarm.channel = this._channel;
|
|
252
331
|
if (this._idleNudge !== undefined) config.swarm.idleNudge = this._idleNudge;
|
|
253
332
|
if (this._errorHandling !== undefined) config.errorHandling = this._errorHandling;
|
|
333
|
+
if (this._coordination !== undefined) config.coordination = this._coordination;
|
|
334
|
+
if (this._state !== undefined) config.state = this._state;
|
|
335
|
+
if (this._trajectories !== undefined) config.trajectories = this._trajectories;
|
|
254
336
|
|
|
255
337
|
return config;
|
|
256
338
|
}
|
|
@@ -285,7 +367,13 @@ export class WorkflowBuilder {
|
|
|
285
367
|
runner.on(options.onEvent);
|
|
286
368
|
}
|
|
287
369
|
|
|
288
|
-
|
|
370
|
+
const startFrom = this._startFrom ?? options.startFrom;
|
|
371
|
+
const previousRunId = this._previousRunId ?? options.previousRunId;
|
|
372
|
+
const executeOptions: WorkflowExecuteOptions | undefined = startFrom
|
|
373
|
+
? { startFrom, previousRunId }
|
|
374
|
+
: undefined;
|
|
375
|
+
|
|
376
|
+
return runner.execute(config, options.workflow, options.vars, executeOptions);
|
|
289
377
|
}
|
|
290
378
|
}
|
|
291
379
|
|
|
@@ -28,6 +28,8 @@ Arguments:
|
|
|
28
28
|
Options:
|
|
29
29
|
--workflow <name> Run a specific workflow by name (default: first)
|
|
30
30
|
--resume <run-id> Resume a failed or interrupted run by its run ID
|
|
31
|
+
--start-from <step> Start from a specific step, skipping predecessors
|
|
32
|
+
--previous-run-id <id> Use cached outputs from a specific prior run (with --start-from)
|
|
31
33
|
--validate Validate workflow YAML for common issues without running
|
|
32
34
|
--help Show this help message
|
|
33
35
|
|
|
@@ -136,6 +138,18 @@ async function main(): Promise<void> {
|
|
|
136
138
|
workflowName = args[workflowIdx + 1];
|
|
137
139
|
}
|
|
138
140
|
|
|
141
|
+
let startFromStep: string | undefined;
|
|
142
|
+
const startFromIdx = args.indexOf('--start-from');
|
|
143
|
+
if (startFromIdx !== -1 && args[startFromIdx + 1]) {
|
|
144
|
+
startFromStep = args[startFromIdx + 1];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let previousRunId: string | undefined;
|
|
148
|
+
const prevRunIdx = args.indexOf('--previous-run-id');
|
|
149
|
+
if (prevRunIdx !== -1 && args[prevRunIdx + 1]) {
|
|
150
|
+
previousRunId = args[prevRunIdx + 1];
|
|
151
|
+
}
|
|
152
|
+
|
|
139
153
|
const isValidate = args.includes('--validate');
|
|
140
154
|
|
|
141
155
|
console.log(`Running workflow from ${yamlPath}...`);
|
|
@@ -157,7 +171,8 @@ async function main(): Promise<void> {
|
|
|
157
171
|
}
|
|
158
172
|
|
|
159
173
|
runner.on((event) => console.log(formatEvent(event)));
|
|
160
|
-
const
|
|
174
|
+
const executeOptions = startFromStep ? { startFrom: startFromStep, previousRunId } : undefined;
|
|
175
|
+
const result = await runner.execute(config, workflowName, undefined, executeOptions);
|
|
161
176
|
|
|
162
177
|
if (result.status === 'completed') {
|
|
163
178
|
console.log(`\nWorkflow completed successfully.`);
|
|
@@ -59,6 +59,7 @@ import type {
|
|
|
59
59
|
WorkflowRunRow,
|
|
60
60
|
WorkflowRunStatus,
|
|
61
61
|
WorkflowStep,
|
|
62
|
+
WorkflowExecuteOptions,
|
|
62
63
|
WorkflowStepCompletionReason,
|
|
63
64
|
WorkflowStepRow,
|
|
64
65
|
WorkflowStepStatus,
|
|
@@ -1778,7 +1779,8 @@ export class WorkflowRunner {
|
|
|
1778
1779
|
async execute(
|
|
1779
1780
|
config: RelayYamlConfig,
|
|
1780
1781
|
workflowName?: string,
|
|
1781
|
-
vars?: VariableContext
|
|
1782
|
+
vars?: VariableContext,
|
|
1783
|
+
executeOptions?: WorkflowExecuteOptions
|
|
1782
1784
|
): Promise<WorkflowRunRow> {
|
|
1783
1785
|
// Set up abort controller early so callers can abort() even during setup
|
|
1784
1786
|
this.abortController = new AbortController();
|
|
@@ -1861,6 +1863,49 @@ export class WorkflowRunner {
|
|
|
1861
1863
|
stepStates.set(step.name, { row: stepRow });
|
|
1862
1864
|
}
|
|
1863
1865
|
|
|
1866
|
+
// Handle startFrom: skip all transitive dependencies of the target step
|
|
1867
|
+
if (executeOptions?.startFrom) {
|
|
1868
|
+
const startFromName = executeOptions.startFrom;
|
|
1869
|
+
const stepNames = new Set(resolvedWorkflow.steps.map((s) => s.name));
|
|
1870
|
+
if (!stepNames.has(startFromName)) {
|
|
1871
|
+
throw new Error(
|
|
1872
|
+
`startFrom step "${startFromName}" not found in workflow. Available steps: ${[...stepNames].join(', ')}`
|
|
1873
|
+
);
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
const transitiveDeps = this.collectTransitiveDeps(startFromName, resolvedWorkflow.steps);
|
|
1877
|
+
const skippedCount = transitiveDeps.size;
|
|
1878
|
+
|
|
1879
|
+
// Determine which run ID to load cached outputs from
|
|
1880
|
+
const cacheRunId = executeOptions.previousRunId
|
|
1881
|
+
?? this.findMostRecentRunWithSteps(transitiveDeps);
|
|
1882
|
+
|
|
1883
|
+
for (const depName of transitiveDeps) {
|
|
1884
|
+
const state = stepStates.get(depName);
|
|
1885
|
+
if (!state) continue;
|
|
1886
|
+
|
|
1887
|
+
// Load cached output from a previous run if available
|
|
1888
|
+
const cachedOutput = cacheRunId ? this.loadStepOutput(cacheRunId, depName) : undefined;
|
|
1889
|
+
if (!cachedOutput) {
|
|
1890
|
+
this.log(`[startFrom] No cached output for skipped step "${depName}" — using empty string`);
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
state.row.status = 'completed';
|
|
1894
|
+
state.row.output = cachedOutput ?? '';
|
|
1895
|
+
state.row.completedAt = now;
|
|
1896
|
+
await this.db.updateStep(state.row.id, {
|
|
1897
|
+
status: 'completed',
|
|
1898
|
+
output: state.row.output,
|
|
1899
|
+
completedAt: now,
|
|
1900
|
+
updatedAt: now,
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
if (skippedCount > 0) {
|
|
1905
|
+
this.log(`[startFrom] Skipping ${skippedCount} steps, starting from "${startFromName}"`);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1864
1909
|
return this.runWorkflowCore({
|
|
1865
1910
|
run,
|
|
1866
1911
|
workflow: resolvedWorkflow,
|
|
@@ -5719,6 +5764,35 @@ export class WorkflowRunner {
|
|
|
5719
5764
|
}
|
|
5720
5765
|
}
|
|
5721
5766
|
|
|
5767
|
+
// ── startFrom dependency resolution ─────────────────────────────────
|
|
5768
|
+
|
|
5769
|
+
/**
|
|
5770
|
+
* Walk the dependsOn graph backwards from a target step to collect ALL
|
|
5771
|
+
* transitive dependencies (i.e. every step that must complete before
|
|
5772
|
+
* the target step can run). The target step itself is NOT included.
|
|
5773
|
+
*/
|
|
5774
|
+
private collectTransitiveDeps(targetStep: string, steps: WorkflowStep[]): Set<string> {
|
|
5775
|
+
const stepMap = new Map<string, WorkflowStep>();
|
|
5776
|
+
for (const s of steps) stepMap.set(s.name, s);
|
|
5777
|
+
|
|
5778
|
+
const deps = new Set<string>();
|
|
5779
|
+
const queue = [...(stepMap.get(targetStep)?.dependsOn ?? [])];
|
|
5780
|
+
|
|
5781
|
+
while (queue.length > 0) {
|
|
5782
|
+
const current = queue.shift()!;
|
|
5783
|
+
if (deps.has(current)) continue;
|
|
5784
|
+
deps.add(current);
|
|
5785
|
+
const step = stepMap.get(current);
|
|
5786
|
+
if (step?.dependsOn) {
|
|
5787
|
+
for (const dep of step.dependsOn) {
|
|
5788
|
+
if (!deps.has(dep)) queue.push(dep);
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
|
|
5793
|
+
return deps;
|
|
5794
|
+
}
|
|
5795
|
+
|
|
5722
5796
|
// ── Control flow helpers ──────────────────────────────────────────────
|
|
5723
5797
|
|
|
5724
5798
|
private checkAborted(): void {
|
|
@@ -6203,6 +6277,41 @@ export class WorkflowRunner {
|
|
|
6203
6277
|
this.postToChannel(`**[${stepName}] Output:**\n\`\`\`\n${preview}\n\`\`\``, { stepName });
|
|
6204
6278
|
}
|
|
6205
6279
|
|
|
6280
|
+
/** Scan .agent-relay/step-outputs/ for the most recent run directory containing the needed steps. */
|
|
6281
|
+
private findMostRecentRunWithSteps(stepNames: Set<string>): string | undefined {
|
|
6282
|
+
try {
|
|
6283
|
+
const baseDir = path.join(this.cwd, '.agent-relay', 'step-outputs');
|
|
6284
|
+
if (!existsSync(baseDir)) return undefined;
|
|
6285
|
+
|
|
6286
|
+
const entries = readdirSync(baseDir);
|
|
6287
|
+
let best: { name: string; mtime: number } | undefined;
|
|
6288
|
+
|
|
6289
|
+
for (const entry of entries) {
|
|
6290
|
+
const dirPath = path.join(baseDir, entry);
|
|
6291
|
+
try {
|
|
6292
|
+
const stat = statSync(dirPath);
|
|
6293
|
+
if (!stat.isDirectory()) continue;
|
|
6294
|
+
|
|
6295
|
+
// Check if this directory has at least one of the needed step files
|
|
6296
|
+
const hasAny = [...stepNames].some(name =>
|
|
6297
|
+
existsSync(path.join(dirPath, `${name}.md`))
|
|
6298
|
+
);
|
|
6299
|
+
if (!hasAny) continue;
|
|
6300
|
+
|
|
6301
|
+
if (!best || stat.mtimeMs > best.mtime) {
|
|
6302
|
+
best = { name: entry, mtime: stat.mtimeMs };
|
|
6303
|
+
}
|
|
6304
|
+
} catch {
|
|
6305
|
+
continue;
|
|
6306
|
+
}
|
|
6307
|
+
}
|
|
6308
|
+
|
|
6309
|
+
return best?.name;
|
|
6310
|
+
} catch {
|
|
6311
|
+
return undefined;
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6314
|
+
|
|
6206
6315
|
/** Load persisted step output from disk. */
|
|
6207
6316
|
private loadStepOutput(runId: string, stepName: string): string | undefined {
|
|
6208
6317
|
try {
|
|
@@ -502,6 +502,20 @@ export interface DryRunReport {
|
|
|
502
502
|
estimatedTotalAgentSteps?: number;
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
+
// ── Workflow execution options ───────────────────────────────────────────────
|
|
506
|
+
|
|
507
|
+
/** Options that control how a workflow run executes. */
|
|
508
|
+
export interface WorkflowExecuteOptions {
|
|
509
|
+
/** Start execution from a specific step, skipping all predecessor steps.
|
|
510
|
+
* Predecessor outputs are loaded from cached step-outputs on disk when available. */
|
|
511
|
+
startFrom?: string;
|
|
512
|
+
/** Run ID of a previous execution whose cached step outputs should be used
|
|
513
|
+
* when skipping predecessor steps via `startFrom`. If omitted, the runner
|
|
514
|
+
* scans `.agent-relay/step-outputs/` for the most recent directory that
|
|
515
|
+
* contains the needed step files. */
|
|
516
|
+
previousRunId?: string;
|
|
517
|
+
}
|
|
518
|
+
|
|
505
519
|
// ── Database row types ──────────────────────────────────────────────────────
|
|
506
520
|
|
|
507
521
|
export type WorkflowRunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
@@ -14,12 +14,6 @@
|
|
|
14
14
|
},
|
|
15
15
|
"include": ["src/**/*.ts"],
|
|
16
16
|
"exclude": [
|
|
17
|
-
"src/__tests__
|
|
18
|
-
"src/__tests__/workflow-trajectory.test.ts",
|
|
19
|
-
"src/__tests__/swarm-coordinator.test.ts",
|
|
20
|
-
"src/__tests__/error-scenarios.test.ts",
|
|
21
|
-
"src/__tests__/idle-nudge.test.ts",
|
|
22
|
-
"src/__tests__/orchestration-upgrades.test.ts",
|
|
23
|
-
"src/__tests__/yaml-validation.test.ts"
|
|
17
|
+
"src/__tests__/**"
|
|
24
18
|
]
|
|
25
19
|
}
|
|
@@ -10,12 +10,6 @@
|
|
|
10
10
|
},
|
|
11
11
|
"include": ["src/**/*.ts"],
|
|
12
12
|
"exclude": [
|
|
13
|
-
"src/__tests__
|
|
14
|
-
"src/__tests__/workflow-trajectory.test.ts",
|
|
15
|
-
"src/__tests__/swarm-coordinator.test.ts",
|
|
16
|
-
"src/__tests__/error-scenarios.test.ts",
|
|
17
|
-
"src/__tests__/idle-nudge.test.ts",
|
|
18
|
-
"src/__tests__/orchestration-upgrades.test.ts",
|
|
19
|
-
"src/__tests__/yaml-validation.test.ts"
|
|
13
|
+
"src/__tests__/**"
|
|
20
14
|
]
|
|
21
15
|
}
|