Skip to content

fix(sdk): expose camelCase types for agent exit and node status - #505

Open
willwashburn wants to merge 1 commit into
fix/sdk-on-before-connect-492from
fix/sdk-camel-ws-events-491
Open

willwashburn wants to merge 1 commit into
fix/sdk-on-before-connect-492from
fix/sdk-camel-ws-events-491

Conversation

@willwashburn

@willwashburn willwashburn commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

AgentExitedEvent, NodeStatusOnlineEvent, and NodeStatusOfflineEvent are the camelCase SDK types for agent.exited, node.status.online, and node.status.offline. on.agentExited, on.nodeOnline, and on.nodeOffline deliver those payloads. Wire event type strings stay snake_case.

Stacks on #504.

Fixes #491

Replaces draft #496.

Checks

  • npm run test:types in packages/sdk-typescript — pass
  • npx vitest run src/__tests__/agent-ws.test.ts in packages/sdk-typescript — 42 passed

Note

Low Risk
Additive SDK types and event handlers with tests; no server or auth changes.

Overview
Fixes a TypeScript SDK gap where agent.exited, node.status.online, and node.status.offline WebSocket frames were delivered with camelCase fields but had no matching SDK surface—callers who typed handlers with snake_case @relaycast/types aliases could compile yet read undefined on every property.

The PR adds camelCase exports AgentExitedEvent, NodeStatusOnlineEvent, and NodeStatusOfflineEvent, plus on.agentExited, on.nodeOnline, and on.nodeOffline on both AgentClient and RelayCast. Wire event type strings stay snake_case. Changelog entries document the fix, and agent-ws.test.ts asserts camelization against captured wire shapes.

Reviewed by Cursor Bugbot for commit 47fc500. Bugbot is set up for automated code reviews on this repo. Configure here.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…vents

agent.exited, node.status.online, and node.status.offline are valid
ServerEvent/WsClientEvent members that the engine emits, but
@relaycast/sdk exposed no Camelize<Raw.X> type or on.* handler for any
of them. Since @relaycast/types is a runtime dependency of the SDK,
the only reachable type named AgentExitedEvent was the raw snake_case
one, which type-checks against code but silently reads undefined
against the camelized payload the WsClient actually delivers.

Add the missing camelCase types and on.agentExited/on.nodeOnline/
on.nodeOffline handlers, plus regression tests that round-trip real
captured snake_case frames through the typed handlers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T09:55:47.295882Z 47fc500 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 205ea39e-20d3-4db5-87a4-7b487c9d2fe3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47fc500d64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +455 to +456
nodeOnline: (handler: (e: NodeStatusOnlineEvent) => void): (() => void) => this.onEvent('node.status.online', handler),
nodeOffline: (handler: (e: NodeStatusOfflineEvent) => void): (() => void) => this.onEvent('node.status.offline', handler),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route node status events to AgentClient

When consumers register these callbacks on AgentClient, they can never fire in production: AgentClient connects exclusively through /v1/node/ws, while the canonical engine's emitNodeStatusEffects sends node.status.online and node.status.offline only to the workspace stream and webhook outbox, with no node/agent audience. The new test bypasses that routing by injecting a synthetic node frame directly. Either route these events to the direct-node client or expose these handlers only on RelayCast; otherwise the advertised agent.on.nodeOnline/nodeOffline API silently does nothing.

AGENTS.md reference: AGENTS.md:L10-L12

Useful? React with 👍 / 👎.

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

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.

Devin Review found 1 potential issue.

Devin Review

Comment on lines +455 to +456
nodeOnline: (handler: (e: NodeStatusOnlineEvent) => void): (() => void) => this.onEvent('node.status.online', handler),
nodeOffline: (handler: (e: NodeStatusOfflineEvent) => void): (() => void) => this.onEvent('node.status.offline', handler),

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.

🟡 Agent node-status handlers never fire

AgentClient.on.nodeOnline and nodeOffline listen on the direct-node socket. emitNodeStatusEffects sends these events only to workspace observers and webhooks, so both callbacks remain silent.

Learn more

Node-status transitions are workspace-wide events. AgentClient connects through /v1/node/ws, which carries node control frames and events explicitly delivered to an agent. The engine's emitNodeStatusEffects publishes each transition to the workspace stream and webhook queue, but never calls sendNodeDeliveriesToAgents. The test injects a workspace-stream event directly into the node socket, a frame the engine does not produce on that transport.

Example: A node times out and the engine emits node.status.offline. RelayCast.on.nodeOffline can receive it through /v1/ws, but an AgentClient.on.nodeOffline callback never runs.

Recommended fix: Remove nodeOnline and nodeOffline from AgentClient.on, or add an intentional server delivery path for node-status events to defined agent recipients. If these remain workspace-only, move their runtime coverage to RelayCast tests using /v1/ws.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant