Fix APP-4853: restore subagent chips and agent names after session reopen#13664
Draft
seemeroland wants to merge 1 commit into
Draft
Fix APP-4853: restore subagent chips and agent names after session reopen#13664seemeroland wants to merge 1 commit into
seemeroland wants to merge 1 commit into
Conversation
The TUI startup speedup (commit 0ac6f59) changed startup to deliver conversations with empty task lists, then load full task payloads lazily from the local DB on demand. The eager orchestration-child hydration path in `initialize_historical_conversations` was updated to call `load_conversation_from_db` when `agent_conversation.tasks.is_empty()`, but without a fallback: if the RO DB connection cannot be established (or any other read error occurs), the function returns `None` and the child is never inserted into `conversations_by_id`. That missing insertion caused the regression: - `OrchestrationPillBar::pill_specs` filters descendant IDs through `history.conversation(&id)`, so unhydrated children produce an empty pill list → no chips at the top of the conversation. - `participant_for_agent_id` resolves an agent ID to a conversation, then looks it up in `conversations_by_id`. When the lookup fails it falls back to `OrchestrationParticipant::unknown_child()` → "Unknown agent" in send_message / messages_received transcript rows. The fix: when `agent_conversation.tasks.is_empty()`, try `load_conversation_from_db` first (to get full task data for rich display) and fall back to `convert_persisted_conversation_to_ai_conversation_with_metadata` if that fails. The fallback synthesizes a minimal `AIConversation` from the `conversation_data` column already in memory — same as the pre-TUI- speedup code path in QUALITY-768. The synthesized conversation carries the correct `task_id` (run_id), `agent_name`, and parent linkage, which is all the pill bar and name resolution need. A new test, `…with_empty_tasks`, exercises the production code path (tasks == []) to pin the fallback behaviour. The existing test `test_initialize_historical_conversations_eagerly_hydrates_orchestration_children` used non-empty tasks, so it took the direct-conversion branch and missed the regression entirely. CHANGELOG-BUG-FIX: Fixed subagent chips being missing and 'Unknown agent' displayed when reopening a session that used orchestrated subagents. Co-Authored-By: Oz <oz-agent@warp.dev>
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.
Description
Fixes APP-4853: subagent chips are missing and "Unknown agent" is displayed when reopening a session that used orchestrated child agents.
Root Cause
The TUI startup speedup (PR #13449 / commit 0ac6f59) changed the app to load
agent_conversationsmetadata-only at startup —agent_conversation.tasksis always empty. Theinitialize_historical_conversationseager child-hydration path was updated to callload_conversation_from_db(&conversation_id)whentasks.is_empty(), but without a fallback: if the read-only DB connection cannot be established (or any read error occurs), the call returnsNoneand the child is never inserted intoconversations_by_id.That missing insertion caused two visible regressions after an app restart:
OrchestrationPillBar::pill_specsfilters descendant IDs throughhistory.conversation(&id), so unhydrated children produce an empty pill list → no chips.participant_for_agent_idresolves the agent ID to a conversation, then looks it up inconversations_by_id. When that lookup returnsNone, it falls back toOrchestrationParticipant::unknown_child().The pre-regression code (
QUALITY-768 / #11722) always calledconvert_persisted_conversation_to_ai_conversation_with_metadata(agent_conversation.clone())directly, which synthesises a minimalAIConversationfromconversation_data(task_id/run_id, agent_name, parent linkage) even whentasksis empty. The TUI speedup PR replaced this direct call with a DB load and dropped the fallback.Fix
In
conversation_loader.rs, whenagent_conversation.tasks.is_empty(), tryload_conversation_from_dbfirst (to get full task data for rich display), and fall back toconvert_persisted_conversation_to_ai_conversation_with_metadataif the DB load fails. The fallback synthesises a minimalAIConversationcarrying the correcttask_id,agent_name, and parent linkage — exactly what the pill bar and name resolution need.A new regression test
…with_empty_tasksexercises this production code path (tasks == []) to pin the fallback behaviour. The existing testtest_initialize_historical_conversations_eagerly_hydrates_orchestration_childrenpassed non-empty tasks, so it always took the direct-conversion branch and missed the regression.Linked Issue
Fixes APP-4853
The linked issue is labeled
ready-to-specorready-to-implement.Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).
Testing
Added
test_initialize_historical_conversations_eagerly_hydrates_orchestration_children_with_empty_taskswhich:tasks: vecconversations_by_idvia the fallbackagent_nameandrun_idare correctly restoredchildren_by_parentandagent_id_to_conversation_idindices are populatedcargo check --testsandcargo clippy --tests -- -D warningsboth pass../script/runAgent Mode
CHANGELOG-BUG-FIX: Fixed subagent chips missing and "Unknown agent" shown when reopening a session that used orchestrated child agents.
Conversation: https://staging.warp.dev/conversation/4e5df828-99f9-412c-bdf9-b73408bf1141
Run: https://oz.staging.warp.dev/runs/019f5cde-754c-7ebb-bd3e-f487495818ca
This PR was generated with Oz.