Repository navigation
feat(opencode): add STEER support for busy TUI sessions - #14813
dhiyaancnirmal wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
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}/steerAPI 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 |
There was a problem hiding this comment.
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.
| text?: string | |
| text: string |
| await writeSteer({ | ||
| sessionID: input.sessionID, | ||
| queued, | ||
| }) | ||
| match.steerQueue.push(queued) | ||
| return { | ||
| accepted: true, | ||
| queued, | ||
| } |
There was a problem hiding this comment.
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.
| config: { | ||
| agent: { | ||
| build: { | ||
| model: "openai/gpt-5.2", |
There was a problem hiding this comment.
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.
| model: "openai/gpt-5.2", | |
| model: "test/fake-model", |
|
Superseded by #14815 (same STEER feature, rebased onto latest dev with a clean branch/commit history). |
Issue for this PR
Closes #9454
Type of change
What does this PR do?
Adds STEER support for busy sessions in
opencode(TUI + API path).Included in this PR:
session.steerserver route / SDK generation support used by the TUIinput_steer_submit)tmuxTUI E2E harness + basic coverageHow did you verify your code works?
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.tscd packages/opencode && OPENCODE_TUI_E2E=1 ~/.bun/bin/bun test --timeout 60000 test/cli/tui/tmux.e2e.test.tsPATH="$HOME/.bun/bin:$PATH" ~/.bun/bin/bun turbo typecheckScreenshots / recordings
Not included (TUI keyboard/timing behavior change).
Checklist
If you do not follow this template your PR will be automatically rejected.