Skip to content

Fix fresh-agent tool result attribution and adjacent tool grouping#474

Merged
danshapiro merged 2 commits into
mainfrom
freshagent-tool-attribution
Jun 23, 2026
Merged

Fix fresh-agent tool result attribution and adjacent tool grouping#474
danshapiro merged 2 commits into
mainfrom
freshagent-tool-attribution

Conversation

@danshapiro

Copy link
Copy Markdown
Owner

Problem

Claude Code skill payloads inject as synthetic user turns in the fresh-agent transcript, appearing as fake "You" messages. Additionally, adjacent tool-use/result exchanges render as separate entries instead of being grouped into the preceding assistant turn's activity strip.

What the fix does

Server-side (normalize.ts):

  • normalizeClaudeTurn now returns FreshAgentNormalizedTurn | null — user turns whose content is entirely system context (e.g. Claude skill instruction payloads starting with "Base directory for this skill:") are filtered out
  • normalizeClaudeItem extracts user-authored text via extractUserAuthoredText, stripping system context from user text blocks
  • isSyntheticUserTimelineItem filters synthetic user items from timeline pages
  • latestTurnId is derived from the last non-null turn instead of the raw resolution value
  • normalizeClaudeTurnBody returns null for synthetic turns

Client-side (FreshAgentTranscript.tsx):

  • isSyntheticToolResultTurn identifies user-role turns that are entirely tool results
  • coalesceSyntheticToolResultTurns folds synthetic tool result turns into the preceding assistant turn via appendTurnItems, or renders them as tool-role turns when no preceding assistant turn exists
  • Applied before filterTurnsForDisplay in the display pipeline

utils.ts:

  • isSystemContext now detects Claude Code skill payloads starting with "Base directory for this skill:"

Rebase notes

Reconciled with PR #452 (transcript contract) which rewrote normalizeClaudeTurn and FreshAgentTranscript.tsx:

  • Old coalesceActivityOnlyTurns/mergeActivityOnlyTurns removed on main; synthetic tool result coalescing reimplemented as a standalone coalesceSyntheticToolResultTurns step in the new displayTurns pipeline
  • Type renames adapted: AgentTimelineTurnClaudeFreshAgentHistoryTurn, AgentTimelinePageClaudeFreshAgentHistoryPage
  • Tests updated for main's per-turn activity strip rendering (multiple strips instead of one coalesced strip)

Tests

  • 6 new test cases: 2 transcript client tests, 1 normalize server test, 2 utils tests, 1 existing normalize test preserved
  • All 50 FreshAgentTranscript tests pass, all 40 server tests pass
  • Typecheck and lint clean

Closes kata jb5w.

@danshapiro danshapiro force-pushed the freshagent-tool-attribution branch from 002365f to c278ded Compare June 23, 2026 08:24
@danshapiro danshapiro merged commit 84e049b into main Jun 23, 2026
1 check passed
@danshapiro danshapiro deleted the freshagent-tool-attribution branch June 23, 2026 08:27
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.

2 participants