refactor(runtime): add OpenCode ndjson stream parser - #6147
Conversation
E2E tests did not runE2E tests run automatically for org/repo members and collaborators on pull requests. For other contributors, a maintainer must add the See E2E testing guide for details. |
PR Summary by Qodoruntime: add OpenCode NDJSON stream parser for normalized AgentEvent output
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1.
|
waynesun09
left a comment
There was a problem hiding this comment.
Review squad pass (Claude x2 + Grok, cross-verified against the actual anomalyco/opencode emitter source). Posting the unique medium+ findings not already covered by the existing qodo-code-review comments (unredacted ToolUseEvent.Summary and dropped reasoning tokens are already flagged there and not re-posted here).
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
20358e8 to
7e2b84a
Compare
|
Addressed all review findings from @qodo-code-review, @waynesun09, and @maruiz93 in two fix commits: Commit d78f037 —
Commit 7e2b84a —
Side note: the Go convention pack ( |
The referenced Qodo findings are addressed: Yes—filing an issue for an external contributor would be worthwhile. The current TC-001/TC-002 guidance appears inconsistent with the repository’s established practice (
An external contributor could first confirm the intended policy with maintainers, then update the pack and add documentation/tests covering both stdlib-only and existing |
b240ead to
fa7fab8
Compare
waynesun09
left a comment
There was a problem hiding this comment.
Validated locally at fa7fab8: build, gofmt -l, and the full runtime/cli test surface pass. All review findings are resolved — secret redaction on tool summaries and error messages (test-covered), reasoning tokens threaded end-to-end (TokensEvent/ResultEvent/RunMetrics/aggregation/renderer/OTEL), step_finish.reason now carried as Subtype, the --thinking and schema-drift constraints recorded in code comments for the wiring PR, and the reasoning JSON tag made consistent with its siblings in fa7fab8. Truncation ambiguity and InitEvent are explicitly documented as OpenCodeRuntime.Run() wiring responsibilities, which is the right scope for this parser-only step. LGTM.
Implement parseOpenCodeStream() that maps OpenCode's --format json ndjson events (tool_use, text, reasoning, step_finish, step_start, error) to the normalized AgentEvent types. This enables real-time progress rendering and metrics capture for OpenCode agent runs. Key design decisions: - Returns sessionID from ndjson envelope (needed for opencode export) - Synthesizes ResultEvent at EOF from accumulated step_finish data - Only emits ToolUseEvent for terminal states (completed/error) - Maps reasoning events to ThinkingEvent (OpenCode naming difference) - Silently absorbs step_start events (no useful AgentEvent mapping) Known gaps: no InitEvent.Model from stream (populated by caller from RunParams.Model), no RetryEvent (OpenCode does not surface retries). Refs: fullsend-ai#1260 Signed-off-by: sonupreetam <spreetam@redhat.com>
- Add secret redaction to tool summaries via shared progressRedactor, preventing credential leaks to terminal and CI annotations - Track reasoning tokens through the full pipeline: TokensEvent, ResultEvent, RunMetrics, renderer, OTEL spans, and aggregation - Map step_finish reason to ResultEvent.Subtype for parity with Claude parser subtype field - Consolidate duplicate SecretRedactor instances (DRY) - Capture ReasoningTokens in ClaudeRuntime.Run handler and root OTEL span - Document truncated-stream false-success limitation - Fix variable shadowing (errors -> errEvents) - Add tests: secret redaction, clean passthrough, pending/running filtering, reasoning tokens in renderer/telemetry/aggregation Signed-off-by: sonupreetam <spreetam@redhat.com>
- Redact error messages through progressRedactor to prevent secret leakage via ErrorEvent.Message and ResultEvent.ErrorMessage - Document InitEvent caller responsibility (OpenCode wire format lacks model/version metadata) - Document --thinking flag requirement for reasoning event emission - Pin emitter source reference (anomalyco/opencode run.ts, pre-GA 2026-08) for fixture drift detection - Document silent-skip risk for unknown event types - Extract shared streamBufSize constant (1 MiB) used by both Claude and OpenCode parsers Signed-off-by: sonupreetam <spreetam@redhat.com>
Keep reasoning field consistent with sibling token fields (input,
output, cache_creation, cache_read) which all serialize zero values.
A zero is meaningful data ("no reasoning tokens used"), not absent
data.
Signed-off-by: sonupreetam <spreetam@redhat.com>
fa7fab8 to
6d7f987
Compare
|
🤖 Finished Retro · ✅ Success · Started 3:25 PM UTC · Completed 3:39 PM UTC Commit: |
Retro: PR #6147 —
|
Summary
Implement
parseOpenCodeStream()that maps OpenCode's--format jsonndjson events to the normalizedAgentEventtypes, enabling real-time progress rendering and metrics capture for OpenCode agent runs. This is the second step toward OpenCode runtime support, following the stub registration in #6035.Related Issue
Refs #1260
Changes
internal/runtime/opencode_progress.go— parser mapping 6 OpenCode ndjson event types (tool_use,text,reasoning,step_finish,step_start,error) to fullsendAgentEventtypessessionIDfrom the ndjson envelope (needed foropencode exportin transcript extraction)ResultEventat EOF from accumulatedstep_finishcost/token data (OpenCode has no explicit result event like Claude Code)ToolUseEventfor terminal states (completed/error), filtering intermediatepending/runningstatesinternal/runtime/testdata/opencode/Testing
make lintpasses (stage changes first, then run)Checklist
!for breaking changes)