Skip to content

feat(opencode): add STEER support for busy TUI sessions - #14813

Closed
dhiyaancnirmal wants to merge 2 commits into
anomalyco:devfrom
dhiyaancnirmal:codex/steer-tui-hardening
Closed

dhiyaancnirmal wants to merge 2 commits into
anomalyco:devfrom
dhiyaancnirmal:codex/steer-tui-hardening

Conversation

@dhiyaancnirmal

@dhiyaancnirmal dhiyaancnirmal commented Feb 23, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #9454

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds STEER support for busy sessions in opencode (TUI + API path).

Included in this PR:

  • session.steer server route / SDK generation support used by the TUI
  • busy-session steer submission in the TUI with a configurable shortcut (input_steer_submit)
  • immediate steer message visibility in the transcript while the agent is still running
  • transcript export support for steer messages
  • prompt-dispatch fixes touched during STEER integration (Home->session transition timing and queued prompt input clearing)
  • opt-in local tmux TUI E2E harness + basic coverage

How did you verify your code works?

  • manual TUI verification of the busy-session STEER flow and related prompt-dispatch behavior touched by this change
  • cd packages/opencode && ~/.bun/bin/bun test --timeout 30000 test/cli/tui/prompt-submit-routing.test.ts test/cli/tui/transcript.test.ts test/session/prompt.test.ts test/config/config.test.ts test/cli/tui/tmux.e2e.test.ts
  • cd packages/opencode && OPENCODE_TUI_E2E=1 ~/.bun/bin/bun test --timeout 60000 test/cli/tui/tmux.e2e.test.ts
  • PATH="$HOME/.bun/bin:$PATH" ~/.bun/bin/bun turbo typecheck

Screenshots / recordings

Not included (TUI keyboard/timing behavior change).

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

If you do not follow this template your PR will be automatically rejected.

@dhiyaancnirmal dhiyaancnirmal changed the title feat(opencode): add STEER queueing and TUI steering workflow feat(opencode): add STEER support for busy TUI sessions Feb 23, 2026

Copilot AI 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.

Pull request overview

This PR adds STEER (steering) functionality to OpenCode, allowing users to queue guidance messages while a session is busy processing, without aborting the current execution. This addresses the feature request in issue #9454 for experimental steering capabilities.

Changes:

  • Added /session/{sessionID}/steer API endpoint that queues user guidance messages during active turns
  • Implemented TUI keybinding (alt+return, super+return, ctrl+return) to send steer messages when session is busy
  • Added visual indicators in the TUI to distinguish steer messages from regular messages (STEER badge)
  • Included tmux-based E2E test harness for TUI testing

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/sdk/js/src/v2/gen/types.gen.ts Added TypeScript types for session steer endpoint request/response
packages/sdk/js/src/v2/gen/sdk.gen.ts Generated SDK client method for steer endpoint
packages/opencode/src/server/routes/session.ts Implemented POST /session/{sessionID}/steer route handler
packages/opencode/src/session/prompt.ts Core steer logic: queueing, persistence, and draining of steer messages
packages/opencode/src/config/config.ts Added input_steer_submit keybinding configuration
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx TUI prompt component integration for steer submission
packages/opencode/src/cli/cmd/tui/component/prompt/submit-routing.ts Routing logic to determine when to send steer vs normal prompt
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx TUI session view changes to display steer messages with badges
packages/opencode/src/cli/cmd/tui/util/transcript.ts Transcript export formatting for steer messages
packages/opencode/test/session/prompt.test.ts Comprehensive unit tests for steer functionality
packages/opencode/test/cli/tui/prompt-submit-routing.test.ts Unit tests for submit routing logic
packages/opencode/test/cli/tui/transcript.test.ts Tests for transcript formatting of steer messages
packages/opencode/test/cli/tui/tmux-harness.ts Tmux-based E2E test harness for TUI testing
packages/opencode/test/cli/tui/tmux.e2e.test.ts E2E tests using tmux harness
packages/opencode/test/config/config.test.ts Test for default steer keybinding configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

parameters: {
sessionID: string
directory?: string
text?: string

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

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

The text parameter in the steer method is typed as optional (text?: string) but the server route validates it as required with .trim().min(1). This mismatch between client SDK and server validation could lead to runtime errors. The parameter should either be marked as required in the SDK types or the server validation should handle the optional case.

Suggested change
text?: string
text: string

Copilot uses AI. Check for mistakes.
Comment on lines +304 to +312
await writeSteer({
sessionID: input.sessionID,
queued,
})
match.steerQueue.push(queued)
return {
accepted: true,
queued,
}

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

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

If writeSteer throws an error (e.g., "No user message found to attach steer metadata"), the steer item will still be pushed to match.steerQueue (line 308), but the steer message won't be persisted to the database. This could lead to inconsistent state where the queue indicates a steer message exists but it's not in storage. Consider adding error handling to either rollback the queue update or retry the write operation.

Copilot uses AI. Check for mistakes.
config: {
agent: {
build: {
model: "openai/gpt-5.2",

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

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

The E2E test uses a non-existent model identifier "openai/gpt-5.2". While this works because the test uses noReply: true and never actually invokes the model, it could be confusing for future test authors. Consider using a clearly fake model name like "test/fake-model" or a comment explaining why a non-existent model is acceptable here.

Suggested change
model: "openai/gpt-5.2",
model: "test/fake-model",

Copilot uses AI. Check for mistakes.
@dhiyaancnirmal

Copy link
Copy Markdown
Author

Superseded by #14815 (same STEER feature, rebased onto latest dev with a clean branch/commit history).

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.

[FEATURE]: Codex CLi feature/harness compatibility when using codex models

2 participants