feat: channel-first workflow communication via Relaycast#446
feat: channel-first workflow communication via Relaycast#446khaliqgant merged 5 commits intomainfrom
Conversation
| await this.relaycastApi.createChannel(channel, workflow.description); | ||
| await this.relaycastApi.joinChannel(channel); |
There was a problem hiding this comment.
🔴 Channel creation/join calls are blocking and can crash the workflow when Relaycast is unavailable
The createChannel and joinChannel calls in both execute and resume are not wrapped in try-catch, so if the Relaycast API is unavailable or returns an unexpected error, the entire workflow fails.
Root Cause and Impact
In execute at packages/broker-sdk/src/workflows/runner.ts:498-499:
await this.relaycastApi.createChannel(channel, workflow.description);
await this.relaycastApi.joinChannel(channel);And in resume at packages/broker-sdk/src/workflows/runner.ts:636-637:
await this.relaycastApi.createChannel(resumeChannel);
await this.relaycastApi.joinChannel(resumeChannel);These calls are inside the try block but have no individual error handling. If Relaycast is temporarily unavailable (network error, auth failure, etc.), the exception propagates and the workflow is marked as failed.
This contradicts the PR's stated design goal ("Channel posts are fire-and-forget so they never block workflow execution") and the test plan ("Verify workflow completes successfully even if Relaycast is temporarily unavailable"). The postToChannel helper at line 1094 correctly wraps its call in try-catch, but the channel setup calls do not follow the same pattern.
Impact: Any Relaycast outage or connectivity issue will prevent all workflows from running, even though channel communication is supposed to be non-critical observability infrastructure.
Prompt for agents
In packages/broker-sdk/src/workflows/runner.ts, wrap the channel setup calls in try-catch blocks so they are non-blocking, matching the fire-and-forget pattern used by postToChannel(). There are two locations to fix:
1. In the execute() method around lines 497-499:
await this.relaycastApi.createChannel(channel, workflow.description);
await this.relaycastApi.joinChannel(channel);
2. In the resume() method around lines 635-637:
await this.relaycastApi.createChannel(resumeChannel);
await this.relaycastApi.joinChannel(resumeChannel);
Both should be wrapped in try-catch with empty catch blocks (or logging), similar to how postToChannel() handles errors at line 1094-1101. For example:
try {
await this.relaycastApi.createChannel(channel, workflow.description);
await this.relaycastApi.joinChannel(channel);
} catch {
// Non-critical — don't break workflow execution
}
This ensures workflows complete successfully even if Relaycast is temporarily unavailable.
Was this helpful? React with 👍 or 👎 to provide feedback.
Workflows now create a dedicated Relaycast channel from the YAML swarm.channel config and route all lifecycle events through it. This makes workflow execution fully observable via Relaycast instead of relying on DMs and summary files. - Upgrade @relaycast/sdk from 0.2.5 to 0.3.0 - Add createChannel, joinChannel, inviteToChannel to RelaycastApi - WorkflowRunner creates/joins the channel on start and resume - Spawned agents are invited to the workflow channel - Task assignments, step lifecycle (started/completed/failed/retrying/skipped), and run completion/failure all posted to the channel - Channel posts are fire-and-forget to never block workflow execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13acd52 to
d390575
Compare
Spawned workflow agents now get registered in Relaycast with identities, making them observable and messageable. Agents are instructed to self-terminate via /exit after completing their task, preventing the runner from blocking indefinitely on waitForExit(). - Add registerExternalAgent() to RelaycastApi for workspace-level agent registration - Append /exit self-termination instructions to every task - Pass task via initial_task spawn parameter for faster delivery - Register each spawned agent in Relaycast with name and persona - Spawn agents into the workflow channel instead of default channels - Safety net: check verification file on timeout before force-releasing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
d390575 to
8c90714
Compare
Wrap createChannel/joinChannel in try-catch so Relaycast outages don't crash workflows. Make postToChannel truly fire-and-forget by removing await — calls now return void and errors are swallowed silently. Addresses Devin review feedback on PR #446. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Channel setup (createChannel/joinChannel) should fail-fast since the workflow depends on Relaycast — silencing errors just delays failure. postToChannel remains truly fire-and-forget (no await) since those are observability messages that shouldn't block step execution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove sendMessage call since task is already delivered via spawnPty initial_task parameter (was sending task twice to agents) - Fix fallback output to say "Agent completed (released after idle timeout)" instead of misleading "Agent exited (timeout)" when the agent completed work but failed to self-terminate Addresses Devin review feedback on PR #446. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
swarm.channelconfig and route all lifecycle events through it@relaycast/sdkfrom 0.2.5 to 0.3.0 for channel management APIscreateChannel,joinChannel,inviteToChannelmethods toRelaycastApiTest plan
swarm.channelset and verify the channel is created in Relaycast🤖 Generated with Claude Code