Skip to content

Track OpenCode child sessions under root sessions#343

Open
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:fix/opencode-child-session-traversal
Open

Track OpenCode child sessions under root sessions#343
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:fix/opencode-child-session-traversal

Conversation

@ozymandiashh
Copy link
Copy Markdown
Contributor

Summary

Addresses the OpenCode portion of #336 by tracking agent/subagent work that OpenCode stores in child sessions.

OpenCode records sessions in SQLite with a session.parent_id hierarchy. Before this PR, CodeBurn discovered only root sessions and then parsed only messages whose message.session_id matched that root. That meant work done by OpenCode child or grandchild sessions could be invisible in CodeBurn, including token usage, tool calls, bash commands, and costs.

This PR keeps discovery root-only to avoid double counting, but changes parsing so a root session includes its unarchived child-session subtree.

Root cause

The existing parser used root-session queries like this:

SELECT id, time_created, data
FROM message
WHERE session_id = ?

That works for a flat session, but not for OpenCode's parent-child session shape:

root session
├─ root message rows
└─ child session
   ├─ child message rows
   └─ grandchild session
      └─ grandchild message rows

Because the query only matched the root session id, CodeBurn ignored the child and grandchild rows even though they belong to the same user-visible OpenCode task.

What changed

  • message and part reads now use a recursive session_tree CTE starting from the discovered root session.
  • The recursive walk includes only unarchived descendants, so archived child sessions remain excluded.
  • Child sessions are still excluded from top-level discovery via the existing parent_id IS NULL discovery query. This prevents double counting.
  • Parsed child/grandchild assistant calls are attributed back to the root sessionId, so downstream session summaries stay grouped under the root task.
  • Deduplication keys now use the real message session id: opencode:<message-session-id>:<message-id>. This avoids collisions between root and child messages.
  • The preceding user prompt is tracked per message session, not in one global string. This prevents an interleaved root/child timeline from assigning the wrong prompt to a child assistant call.
  • OpenCode provider docs and changelog now describe the root-only discovery plus subtree parsing behavior.

Example behavior

Given this SQLite session tree:

root
└─ child
   └─ grandchild

Before:

CodeBurn parsed: root assistant calls only
Missing: child tools, grandchild bash commands, child/grandchild token usage

After:

CodeBurn parses: root + child + grandchild assistant calls
Top-level sessions shown: root only
Call attribution: all calls grouped under root session
Dedup keys: preserve the real source session for each message

Tests added

  • Root + child + grandchild fixture where all three sessions contain assistant calls.
  • Verifies all calls are attributed to the root sessionId.
  • Verifies dedup keys preserve the real source session ids.
  • Verifies per-session user prompts do not leak across root/child/grandchild messages.
  • Verifies child tools such as task and grandchild bash commands are surfaced.
  • Verifies archived child sessions are excluded from the recursive subtree.

Validation

  • npx vitest run tests/providers/opencode.test.ts tests/provider-registry.test.ts - 49/49 tests passed.
  • npx tsc --noEmit --pretty false - passed.
  • npm run build - passed.
  • git diff --check - passed.
  • Argus-style strict review - PASS.
  • Claude Opus 4.7 effort max review - PASS.
  • Gemini 3.1 Pro Preview review - PASS.

Scope and privacy notes

I did not use real local OpenCode history or reporter data. The validation uses synthetic SQLite fixtures only, so no local project names, prompts, paths, session IDs, usage values, or private product details are included.

This PR intentionally does not change OpenCode zero-usage router-call handling from #342. If #342 merges first, this branch may need a small rebase because both PRs touch src/providers/opencode.ts, but the behaviors are separate.

@ozymandiashh ozymandiashh marked this pull request as ready for review May 17, 2026 19:32
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