Skip to content

t1305: OpenCode upstream issue — stream.delta + stream.aborted plugin hooks#2152

Merged
marcusquinn merged 2 commits intomainfrom
feature/t1305
Feb 22, 2026
Merged

t1305: OpenCode upstream issue — stream.delta + stream.aborted plugin hooks#2152
marcusquinn merged 2 commits intomainfrom
feature/t1305

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 22, 2026

Summary

Upstream Issue

anomalyco/opencode#14691

Key Findings

  • processor.ts has explicit no-ops for tool-input-delta and tool-input-end (the exact insertion points)
  • Existing Hooks interface follows a consistent (input, output) => Promise<void> pattern
  • Plugin.trigger() is already called in the streaming hot path (experimental.text.complete)
  • Proposal subsumes #9737 (partial tool args) and complements #12472 (Claude Code hooks) and #13524 (centralized hooks)

Ref #2129

… 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.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 22, 2026

Warning

Rate limit exceeded

@marcusquinn has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 7 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t1305

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 and usage tips.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 16:41:34 UTC 2026: Code review monitoring started
Sun Feb 22 16:41:34 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

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.
@marcusquinn marcusquinn marked this pull request as ready for review February 22, 2026 16:42
@gemini-code-assist
Copy link

Summary of Changes

Hello @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: stream.delta and stream.aborted. These hooks are designed to provide granular control and observability over the token streaming process, allowing for dynamic intervention, improved error recovery, and advanced analytics. The changes aim to significantly boost the efficiency and performance of large language models by enabling sophisticated 'harness engineering' techniques.

Highlights

  • New Plugin Hooks Proposed: Introduced two new plugin hooks, stream.delta and stream.aborted, to enhance streaming token observation and abort handling within the OpenCode project.
  • Stream Delta Observation: The stream.delta hook allows plugins to observe individual streaming tokens/chunks, enabling real-time pattern matching, token counting, and progressive UI rendering, with an option to abort the stream.
  • Stream Abort Handling: The stream.aborted hook provides a mechanism to handle stream aborts (user, plugin, error, timeout), allowing for retries, injection of steering messages, and detailed abort analytics.
  • Motivation and Impact: The proposal is motivated by 'The Harness Problem' research, aiming to improve LLM performance, reduce token usage, and enable new harness optimizations like Time-To-Stream Rules (TTSR) and early abort on wasteful generation.
  • Code Sketch and Design Considerations: A code sketch for processor.ts demonstrates the modest implementation changes (~30 lines) and addresses design considerations such as performance, backward compatibility, and how these hooks complement existing features and issues (e.g., #9737, #12472).
Changelog
  • todo/t1305-opencode-streaming-hooks-issue.md
    • Added a new markdown document detailing the proposal for stream.delta and stream.aborted plugin hooks.
    • Included a research summary of existing related issues, key findings, and the current hook system.
    • Provided motivation for the new hooks based on benchmark data and 'The Harness Problem'.
    • Defined the proposed interfaces and use cases for both stream.delta and stream.aborted hooks.
    • Presented a code sketch illustrating how these hooks would integrate into processor.ts.
    • Outlined design considerations regarding performance, backward compatibility, and how the new hooks subsume or complement existing issues.
Activity
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 40 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 16:42:26 UTC 2026: Code review monitoring started
Sun Feb 22 16:42:27 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 40

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 40
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 16:42:29 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

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

Choose a reason for hiding this comment

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

medium

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 ?? "",

Choose a reason for hiding this comment

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

medium

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

Choose a reason for hiding this comment

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

medium

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.

@marcusquinn marcusquinn merged commit 2846ed6 into main Feb 22, 2026
19 checks passed
@marcusquinn marcusquinn deleted the feature/t1305 branch February 22, 2026 20:23
@marcusquinn
Copy link
Owner Author

Resolves #2174.

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