t1305: OpenCode upstream issue — stream.delta + stream.aborted plugin hooks#2152
t1305: OpenCode upstream issue — stream.delta + stream.aborted plugin hooks#2152marcusquinn merged 2 commits intomainfrom
Conversation
… plugin hooks (t1305) Research completed: reviewed 12+ existing OpenCode issues, processor.ts source, plugin/Hooks interface. No overlap found for streaming-level plugin hooks. Draft includes code sketch, benchmark citations, and design considerations.
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sun Feb 22 16:41:37 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
….aborted hooks (t1305) Upstream issue: anomalyco/opencode#14691 Proposes two new plugin hooks for processor.ts streaming loop: - stream.delta: observe tokens, optionally abort - stream.aborted: handle abort with retry + steering injection Cites oh-my-pi benchmark data, references processor.ts source, includes code sketch (~30 lines change). No overlap with existing issues.
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a comprehensive proposal for enhancing the streaming capabilities of the OpenCode project by adding two new plugin hooks: Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sun Feb 22 16:42:29 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
Code Review
The pull request proposes two new plugin hooks for OpenCode: stream.delta and stream.aborted. These hooks enable real-time token observation, early aborting of generations, and programmatic handling of aborted streams (including retries with steering messages). The proposal is well-researched, citing benchmarks and existing issues. The provided code sketch for processor.ts demonstrates a feasible implementation path. My feedback focuses on ensuring the stream.aborted hook receives sufficient context (partial tool inputs) to be effective in all scenarios.
| messageID: string | ||
| reason: "user" | "plugin" | "error" | "timeout" | ||
| /** Accumulated text so far */ | ||
| partial: string |
There was a problem hiding this comment.
The partial field is currently defined as a string representing 'Accumulated text so far'. However, a stream can be aborted while the model is generating a tool call or a reasoning block. In these cases, providing only the accumulated text part of the message might be insufficient for a plugin to decide on a retry or steering strategy. Consider making this field more comprehensive (e.g., including partial tool arguments) or clarifying its scope in the interface definition.
| sessionID: input.sessionID, | ||
| messageID: input.assistantMessage.id, | ||
| reason: abortReason, | ||
| partial: currentText?.text ?? "", |
There was a problem hiding this comment.
In the code sketch, the partial field is populated using currentText?.text. If the abort occurs during a tool-input-delta (handled in the case block starting at line 157), currentText?.text will only contain the text generated before the tool call started. The plugin receiving the stream.aborted event would lose the partial tool arguments accumulated in toolMatch.state.raw (line 181), which are often critical for detecting why a model went off-track.
| /** Accumulated text so far */ | ||
| partial: string | ||
| /** If plugin-initiated, which plugin triggered the abort */ | ||
| source?: string |
There was a problem hiding this comment.
The source field is intended to identify which plugin triggered the abort. However, the code sketch (lines 133-185) sets abortReason = "plugin" but does not capture the specific plugin's name. OpenCode's Plugin.trigger typically returns the modified output object but not the identity of the plugin that performed the modification. To support this field, the implementation of Plugin.trigger or the abort signal mechanism in the processor would likely need adjustment to return the name of the plugin that signaled the abort.
|
Resolves #2174. |



Summary
stream.delta: observe individual streaming tokens, optionally signal abortstream.aborted: handle abort with optional retry and steering message injectionprocessor.ts), benchmark citations from oh-my-pi, and design considerationstodo/t1305-opencode-streaming-hooks-issue.mdUpstream Issue
anomalyco/opencode#14691
Key Findings
processor.tshas explicit no-ops fortool-input-deltaandtool-input-end(the exact insertion points)Hooksinterface follows a consistent(input, output) => Promise<void>patternPlugin.trigger()is already called in the streaming hot path (experimental.text.complete)Ref #2129