Skip to content

fix: OpenCode event streaming + bypass permission mode#48

Closed
WellDunDun wants to merge 1 commit intorivet-dev:mainfrom
WellDunDun:fix/opencode-event-streaming
Closed

fix: OpenCode event streaming + bypass permission mode#48
WellDunDun wants to merge 1 commit intorivet-dev:mainfrom
WellDunDun:fix/opencode-event-streaming

Conversation

@WellDunDun
Copy link
Copy Markdown
Contributor

@WellDunDun WellDunDun commented Jan 31, 2026

Problem

The daemon cannot stream events from OpenCode >= 1.1.x, and permissionMode: "bypass" is rejected for OpenCode despite being documented. Three independent bugs:

  1. Wrong API endpoints: Daemon calls GET /event/subscribe and POST /session/{id}/prompt, but OpenCode serves GET /event and POST /session/{id}/message. Unrecognized routes return the SPA HTML catch-all, silently failing.

  2. Untagged enum mis-dispatch: The generated Event enum uses #[serde(untagged)]. EventServerConnected (variant bug(opencode): server spawns without being prompted #5) has empty properties, matching ANY event JSON before EventMessageUpdated (docs: documentation overhaul and universal schema reference #10) is tried. All events deserialize as ServerConnectedevent_to_universal() returns "unsupported opencode event".

  3. Bypass mode not wired for OpenCode: normalize_permission_mode() only allows "default" for OpenCode, and the spawn blocks don't pass --dangerously-skip-permissions. OpenCode has supported this flag since 1.1.x (see [FEATURE]: Add --dangerously-skip-permissions (aka YOLO mode) anomalyco/opencode#8463).

Fix

  • Correct the two endpoint paths (/event/subscribe/event, /session/{id}/prompt/session/{id}/message)
  • Replace serde_json::from_value::<Event>() with manual type-field dispatch that deserializes directly into the correct variant struct
  • Allow "bypass" in normalize_permission_mode() for OpenCode
  • Pass --dangerously-skip-permissions to OpenCode CLI when bypass mode is set (both spawn and spawn_streaming)

Testing

Tested with OpenCode 1.1.48 + Kimi K2.5:

  • Before: 0 events (HTML returned instead of JSON)
  • After endpoint fixes only: 41 events, ALL agent.unparsed
  • After all fixes: 50+ correctly parsed events (session.started, item.delta streaming, session.idle)
  • permissionMode: "bypass" now accepted — session.started metadata confirms "permissionMode":"bypass"

Files Changed

File Change
server/packages/sandbox-agent/src/router.rs Fix SSE + message endpoints, manual event dispatch, allow bypass mode
server/packages/agent-management/src/agents.rs Pass --dangerously-skip-permissions to OpenCode CLI

Notes

  • All npm versions (0.1.1 through 0.1.4-rc.6) ship the identical daemon binary, so these bugs exist in every released version
  • The untagged enum issue is a systemic risk — any agent whose generated Event enum has a variant with empty/loose properties will have the same problem

Three independent fixes for the OpenCode agent adapter:

1. Wrong API endpoints: /event/subscribe → /event, /session/{id}/prompt → /session/{id}/message
2. Untagged enum mis-dispatch: replace serde_json::from_value with manual type-field dispatch
3. Wire permissionMode "bypass" for OpenCode: allow in normalize_permission_mode() and pass
   --dangerously-skip-permissions to CLI (both spawn and spawn_streaming)

Tested with OpenCode 1.1.48 + Kimi K2.5.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@WellDunDun WellDunDun force-pushed the fix/opencode-event-streaming branch from c5893f2 to ecb8fcd Compare February 1, 2026 08:59
@WellDunDun WellDunDun changed the title fix: OpenCode event streaming — wrong endpoints + untagged enum dispatch fix: OpenCode event streaming + bypass permission mode Feb 1, 2026
@NathanFlurry
Copy link
Copy Markdown
Member

thank you! i'm going to take a pass on our test suite to make sure we're covering this edge case for all agents correctly before merging.

@WellDunDun
Copy link
Copy Markdown
Contributor Author

@NathanFlurry My absolute pleasure! Hope this helps.

@NathanFlurry
Copy link
Copy Markdown
Member

Merged manually after resolving conflicts with main.

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