Skip to content

feat: group session tool calls - #466

Merged
pedronauck merged 3 commits into
mainfrom
linear-eng-135
Aug 25, 2026
Merged

pedronauck merged 3 commits into
mainfrom
linear-eng-135

Conversation

@pedronauck

@pedronauck pedronauck commented Aug 25, 2026 •

Copy link
Copy Markdown
Member

Summary

Implements Linear issue ENG-135, “Group tool calls (Synara pattern)”, for the web session transcript.

The session timeline now groups consecutive tool calls within a turn while preserving the existing event projection and storage contracts. Ordinary single calls remain ordinary rows, non-tool boundaries split groups, failures stay standalone, and a still-growing trailing group remains visibly open until the turn settles.

Root cause

The timeline renderer treated every tool-call part as an independent row. That made tool-heavy turns noisy and prevented the transcript from communicating the higher-level work phase. The existing derived-row pipeline also needed a stable identity that survives streaming replacement, retries, deduplication, and arrival-order changes without changing the user’s local disclosure state.

Implementation

  • Added deterministic work-group identity based on the canonical tool-call IDs, with a persisted per-message anchor for groups already rendered during streaming.
  • Derived groups from consecutive tool calls in the same turn, splitting at non-tool entries and failed calls.
  • Kept the active trailing group open with a four-row visible budget and truthful remaining-count summaries.
  • Preserved the existing interrupted-turn expansion behavior and kept settled groups collapsed by default.
  • Added stable hidden disclosure targets and aria-controls links so keyboard and assistive-technology users can operate summaries before and after expansion.
  • Preserved the existing scroll anchoring behavior; grouping does not alter the underlying timeline scroll model.
  • Split group identity into its own module so production source files remain below the repository’s 500-line limit.
  • Kept the change web-local: no daemon, SQLite, ACP/JSON-RPC, HTTP/SSE, UDS, native-tool, or public API changes.

Verification

Focused checks completed:

  • bunx turbo run test --filter=./web --force -- --run src/components/assistant-ui/__tests__/session-timeline.logic.test.ts src/components/assistant-ui/__tests__/timeline-scroll-anchoring.test.ts src/components/assistant-ui/__tests__/session-thread.test.tsx
    • PASS: 3 files, 131 tests (including the review regression).
  • bunx turbo run typecheck --filter=./web
    • PASS.
  • Targeted oxfmt and oxlint for all changed source and test files
    • PASS with zero warnings/errors.
  • git diff --check
    • PASS.
  • Independent GPT-5.6-Sol review at high reasoning effort
    • No actionable findings after review fixes.
  • Greptile P1 review finding
    • Fixed in f0d07aa2c: work-group derivation now tracks IDs already assigned within the message, prevents retained-anchor reuse, and disambiguates a colliding fallback with a stable part suffix. The regression is in the canonical timeline logic suite and passes.
  • CodeRabbit review artifact
    • .codex/artifacts/coderabbit/pr-466-review.json was refreshed repeatedly; no actionable CodeRabbit findings were available because the bot reported Review limit reached. A /review request was also posted and remained rate-limited.

Focused gate and QA notes

make gate was run twice as required for focused gates. Both runs reached the web lane but were blocked by unrelated existing failures outside this diff:

  1. The first run had a single failure in web/src/systems/os/hooks/__tests__/use-window-manager-stream.test.tsx (expected null, received workspace:home); the lane otherwise passed 713/714 files. Re-running the exact test through Turbo reproduced it.
  2. The second run passed lint, typecheck, and codegen but timed out in the unrelated Storybook visual-contract test src/storybook/__tests__/web-storybook-visual-contract.test.ts.

Per the task instruction, make verify and make gate-full were not run.

The isolated real-user QA walk was attempted with a fresh QA lab and was torn down cleanly. It is blocked before the transcript can be exercised because the unrelated demo seed does not compile: internal/demoseed/seed.go:79:33: db.ListPresets undefined. Evidence and teardown details are recorded in docs/qa/reports/2026-08-24-eng-135-session-groups.md.

CI monitoring

The post-push CI run was monitored through completion:

  • Run 32803898802, attempt 1: web/Desktop/Preflight/Build and race shard 2/2 passed; Go (format, lint) hit its fixed 10-minute golangci-lint timeout; race shard 1/2 reported 648 failures across internal/store/globaldb.
  • The failed jobs were retried once, as 32803898802, attempt 2. Go (format, lint) passed on retry, while race shard 1/2 reproduced the unrelated globaldb failure with 729 failures after 2,922 seconds. All other checks passed.
  • No ENG-135 source path appears in either failing job; no out-of-scope daemon or database change was made to silence the external blocker.
  • CodeRabbit has no unresolved comments but cannot approve the latest commit because its review limit is exhausted. Greptile's P1 identity-collision finding was fixed and its thread is resolved.

Risks and follow-up

  • The implementation is isolated to the session timeline projection and renderer; the main residual risk is integration behavior under the repository’s existing web gate failures.
  • CI should provide the authoritative full-repository validation.
  • The local QA scenario remains blocked-verify until the unrelated demo-seed compile failure is fixed.

Compozy Impact Audit

  • Native tools: no impact. No compozy__* tool IDs, toolsets, descriptors, schemas, digests, risk flags, capability gates, diagnostics, or CLI/API fallbacks changed; only the web session projection and disclosure renderer were checked.
  • Extensibility and hooks: no impact. No extensions, hooks, skills/capabilities, tools/resources, registries, bridge SDKs, MCP sidecars, or config.toml lifecycle changed; the existing event-to-row path remains the source of truth.
  • Workspace data isolation: no impact. Group identity is session-message scoped in the existing local XState timeline store; no global/workspace/session/agent ownership, storage queries, SSE/event propagation, cache keys, or cross-workspace list/read paths changed.
  • Official Compozy skill: no impact. No public tool IDs, CLI paths, hook events, capabilities, extension resources, or memory/network/task semantics changed.

Closes ENG-135.

@vercel

vercel Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
compozy-site Ready Ready Preview Aug 25, 2026 3:08am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Approval pending

CodeRabbit has no unresolved comments, but it could not review the latest commit because the review limit was reached. Follow the review guidance in this comment to continue.

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch linear-eng-135

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.

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit 2097433.

@greptile-apps

greptile-apps Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Greptile Summary

The PR groups consecutive session tool calls while preserving stable disclosure identity during streaming, reordering, deduplication, and failure splits.

  • Adds message-local work-group anchors and collision-resistant group IDs.
  • Adds grouped settled summaries and bounded live-tail disclosure.
  • Adds stable accessible disclosure targets for work groups, folded turns, and changed files.
  • Extends timeline and component regression coverage for identity and interaction behavior.

Confidence Score: 5/5

The PR appears safe to merge because the previously reported group-identity collision is resolved and no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
web/src/components/assistant-ui/session-timeline-group-identity.ts Derives deterministic group identities, prevents retained-anchor reuse within a derivation, and disambiguates fallback collisions.
web/src/components/assistant-ui/session-timeline.logic.ts Groups live and settled tool-call clusters while tracking group IDs already assigned within each message derivation.
web/src/components/assistant-ui/hooks/use-assistant-message-timeline.ts Persists observed work-group anchors and aligns active-turn detection with part-level turn IDs.
web/src/components/assistant-ui/session-timeline-render.tsx Renders grouped work disclosures and stable ARIA-controlled detail containers.
web/src/components/assistant-ui/tests/session-timeline.logic.test.ts Covers stable identities across replacement, reorder, duplicate events, lower-sorting arrivals, and failure splits.

Reviews (2): Last reviewed commit: "docs: refresh eng-135 QA evidence" | Re-trigger Greptile

Comment thread web/src/components/assistant-ui/session-timeline-group-identity.ts

Copy link
Copy Markdown
Member Author

/review

Copy link
Copy Markdown
Member Author

/review

@pedronauck
pedronauck merged commit 16b0969 into main Aug 25, 2026
42 of 47 checks passed
@pedronauck
pedronauck deleted the linear-eng-135 branch August 25, 2026 13:06
This was referenced Aug 25, 2026
This was referenced Sep 1, 2026
This was referenced Sep 27, 2026

This branch was successfully deployed

1 active deployment
Preview — 20974330 Deployed Aug 25, 2026 by vercel[bot]
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