Skip to content

feat: channel-first workflow communication via Relaycast#446

Merged
khaliqgant merged 5 commits intomainfrom
channel-first-workflow
Feb 19, 2026
Merged

feat: channel-first workflow communication via Relaycast#446
khaliqgant merged 5 commits intomainfrom
channel-first-workflow

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

@khaliqgant khaliqgant commented Feb 19, 2026

Summary

  • Workflows now create a dedicated Relaycast channel from the YAML swarm.channel config and route all lifecycle events through it
  • Upgrades @relaycast/sdk from 0.2.5 to 0.3.0 for channel management APIs
  • Adds createChannel, joinChannel, inviteToChannel methods to RelaycastApi
  • All spawned agents are invited to the workflow channel automatically
  • Task assignments, step lifecycle events (started/completed/failed/retrying/skipped), and run completion/failure are posted to the channel
  • Channel posts are fire-and-forget so they never block workflow execution

Test plan

  • Run existing broker-sdk tests to verify no regressions
  • Run a workflow with swarm.channel set and verify the channel is created in Relaycast
  • Verify all agents appear in the channel member list
  • Confirm task assignments and step lifecycle events appear as channel messages
  • Verify workflow completes successfully even if Relaycast is temporarily unavailable

🤖 Generated with Claude Code


Open with Devin

Comment thread packages/broker-sdk/src/workflows/trajectory.ts Fixed
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 6 additional findings in Devin Review.

Open in Devin Review

Comment on lines +498 to +499
await this.relaycastApi.createChannel(channel, workflow.description);
await this.relaycastApi.joinChannel(channel);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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.
Open in Devin Review

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>
@khaliqgant khaliqgant force-pushed the channel-first-workflow branch from 13acd52 to d390575 Compare February 19, 2026 08:48
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>
@khaliqgant khaliqgant force-pushed the channel-first-workflow branch from d390575 to 8c90714 Compare February 19, 2026 08:50
devin-ai-integration[bot]

This comment was marked as resolved.

khaliqgant and others added 2 commits February 19, 2026 09:57
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>
devin-ai-integration[bot]

This comment was marked as resolved.

- 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>
@khaliqgant khaliqgant merged commit 7e54ca9 into main Feb 19, 2026
38 of 39 checks passed
@khaliqgant khaliqgant deleted the channel-first-workflow branch February 19, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants