remote-session: show agent output in attach (STU-1696)#3366
Merged
Conversation
Persist conversation events (progress, info, error, replies, questions) to the daemon log file so `studio code remote-session attach` replays them alongside the existing daemon polling logs. Previously these only reached stdout in foreground mode. Adds an `event` shape to the persisted log lines and teaches the stdout formatter to render them as `[time] kind content`.
Adds per-message `agent.step` event lines (text snippets, tool_use with input preview, tool_result, thinking) so the full agent reasoning shows on attach. Adds diagnostic fields to the `Turn outcome` info log (`event_counts`, `result_event_seen`, `result_event_empty_reply`, `turn_completed_seen`, `non_json_stdout_lines`) and surfaces `subtype` / `stop_reason` / `num_turns` when the SDK result event has an empty reply. Adds a warn line in the poll loop when the fallback "did not return a result" message is about to be posted, so the cause is visible in the log file. Workaround: when the SDK result arrives with an empty `result` field on a successful turn but an assistant text block was streamed earlier, post that captured text as the reply instead of the user-facing "did not return a result" fallback. The pi runtime hardcodes the result text to '' on agent_end; once that is fixed at the source the workaround can be removed.
Collaborator
📊 Performance Test ResultsComparing 8ee3159 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Related issues
How AI was used in this PR
Implementation, tests, and commit messages drafted with Claude Code. I drove the design (what to log, log shape, where the fallback goes), reproduced the empty-SDK-result bug live against the daemon to confirm the diagnosis, and reviewed each diff before committing. Reviewers should focus on the persisted-event log shape (
logger.ts), the diagnostic fields onTurn outcome, and the empty-result workaround inturn-runner.ts.Proposed Changes
1. Show agent output on
studio code remote-session attach(commit 1)RemoteSessionLogger.event()now persists conversation events (progress, info, error, replies, questions) to the daemon log file in addition to the existing stdout-mirror path.formatLogLineForStdout()recognizes the new{ t, event, content }shape and renders it as[time] kind content. Result: when you attach to a running daemon, the conversation flow is visible alongside the polling logs.2. Diagnostics for "no response" turns (commit 2)
Each non-result
messageevent emits oneagent.stepline per content block (text snippet,tool_usewith input preview,tool_result,thinking) so you can see exactly what the agent did. TheTurn outcomeinfo log gainedevent_counts,result_event_seen,result_event_empty_reply,turn_completed_seen,non_json_stdout_lines, plussubtype/stop_reason/num_turnson the newResult event had empty replywarn. The poll loop logsNo reply produced; posting fallbackbefore sending the user-facing fallback so the cause is captured in the log file.3. Workaround for empty SDK result (commit 2)
While testing the new attach output, reproduced an issue where the agent finishes cleanly (⚠️ Local agent did not return a result." to Telegram even though the agent did answer. Root cause is in the pi runtime (it hardcodes the result text to
status: success,stop_reason: end_turn,num_turns: 1) but the SDKresultevent arrives withresult: "", even though an assistant text block was streamed earlier in the turn. The remote-session loop was posting "''onagent_end). As a guard, the turn runner now captures the last assistant text seen during the turn and uses it as the reply when the result event has emptyreplyTextand no error. The proper fix at the runtime source will follow.Testing Instructions
Automated:
npm test -- apps/cli/remote-session— 111 tests pass (110 existing + 1 new for the empty-result fallback).npm run typecheck— clean.Manual:
npm run cli:build && node apps/cli/dist/cli/main.mjs code remote-session start --detach(with a configured bot/chat).node apps/cli/dist/cli/main.mjs code remote-session attach.Polled message, then a stream ofprogress/agent.step/replyevent lines, thenTurn outcomeandPosting reply.Turn outcomeline will showresult_event_empty_reply: trueandused_assistant_text_fallback: true.Pre-merge Checklist