Skip to content

Commit e2e1898

Browse files
kjankovoz-agent
andcommitted
Update orchestration message transcript UI
Co-Authored-By: Oz <oz-agent@warp.dev>
1 parent d2f26ae commit e2e1898

21 files changed

Lines changed: 803 additions & 158 deletions

app/src/ai/agent/api/convert_conversation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ pub fn convert_conversation_data_to_ai_conversation(
8181
artifacts_json: None,
8282
parent_agent_id: None,
8383
agent_name: None,
84+
orchestration_harness_type: None,
8485
parent_conversation_id: None,
8586
is_remote_child: false,
8687
run_id: None,
@@ -97,6 +98,7 @@ pub fn convert_conversation_data_to_ai_conversation(
9798
artifacts_json: serde_json::to_string(&metadata.artifacts).ok(),
9899
parent_agent_id: None,
99100
agent_name: None,
101+
orchestration_harness_type: None,
100102
parent_conversation_id: None,
101103
is_remote_child: false,
102104
// TODO: Populate run_id from server metadata once it is exposed

app/src/ai/agent/conversation.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use itertools::Itertools as _;
2323
use serde::{Deserialize, Serialize};
2424
use std::collections::HashSet;
2525
use std::{collections::HashMap, fmt::Display};
26+
use warp_cli::agent::Harness;
2627

2728
use super::task_store::TaskStore;
2829
use uuid::Uuid;
@@ -217,6 +218,8 @@ pub struct AIConversation {
217218
parent_agent_id: Option<String>,
218219
/// The display name for this agent (e.g. "Agent 1"), assigned by the orchestrator.
219220
agent_name: Option<String>,
221+
/// Harness used to render the child agent's shared agent/logo icon in orchestration UI.
222+
orchestration_harness_type: Option<String>,
220223
/// The local conversation ID of the parent that spawned this child, if any.
221224
parent_conversation_id: Option<AIConversationId>,
222225
/// True when this conversation is a placeholder for a child agent executing
@@ -282,6 +285,7 @@ impl AIConversation {
282285
artifacts: Vec::new(),
283286
parent_agent_id: None,
284287
agent_name: None,
288+
orchestration_harness_type: None,
285289
parent_conversation_id: None,
286290
is_remote_child: false,
287291
last_event_sequence: None,
@@ -364,6 +368,7 @@ impl AIConversation {
364368
artifacts,
365369
parent_agent_id,
366370
agent_name,
371+
orchestration_harness_type,
367372
parent_conversation_id,
368373
is_remote_child,
369374
run_id,
@@ -388,6 +393,7 @@ impl AIConversation {
388393
.unwrap_or_default();
389394
let parent_agent_id = data.parent_agent_id;
390395
let agent_name = data.agent_name;
396+
let orchestration_harness_type = data.orchestration_harness_type;
391397
let parent_conversation_id = data
392398
.parent_conversation_id
393399
.and_then(|id| AIConversationId::try_from(id).ok());
@@ -410,6 +416,7 @@ impl AIConversation {
410416
artifacts,
411417
parent_agent_id,
412418
agent_name,
419+
orchestration_harness_type,
413420
parent_conversation_id,
414421
is_remote_child,
415422
run_id,
@@ -426,6 +433,7 @@ impl AIConversation {
426433
None,
427434
None,
428435
None,
436+
None,
429437
false,
430438
None,
431439
AIConversationAutoexecuteMode::default(),
@@ -470,6 +478,7 @@ impl AIConversation {
470478
artifacts,
471479
parent_agent_id,
472480
agent_name,
481+
orchestration_harness_type,
473482
parent_conversation_id,
474483
is_remote_child,
475484
last_event_sequence,
@@ -808,6 +817,24 @@ impl AIConversation {
808817
pub fn set_agent_name(&mut self, name: String) {
809818
self.agent_name = Some(name);
810819
}
820+
pub fn orchestration_harness_type(&self) -> Option<&str> {
821+
self.orchestration_harness_type.as_deref()
822+
}
823+
824+
pub fn orchestration_harness(&self) -> Option<Harness> {
825+
self.orchestration_harness_type
826+
.as_deref()
827+
.map(parse_orchestration_harness_type)
828+
.or_else(|| {
829+
self.server_metadata
830+
.as_ref()
831+
.map(|metadata| Harness::from(metadata.harness))
832+
})
833+
}
834+
835+
pub fn set_orchestration_harness(&mut self, harness: Harness) {
836+
self.orchestration_harness_type = Some(harness.config_name().to_string());
837+
}
811838

812839
pub fn parent_conversation_id(&self) -> Option<AIConversationId> {
813840
self.parent_conversation_id
@@ -2909,6 +2936,7 @@ impl AIConversation {
29092936
artifacts_json,
29102937
parent_agent_id: self.parent_agent_id.clone(),
29112938
agent_name: self.agent_name.clone(),
2939+
orchestration_harness_type: self.orchestration_harness_type.clone(),
29122940
parent_conversation_id: self.parent_conversation_id.map(|id| id.to_string()),
29132941
is_remote_child: self.is_remote_child,
29142942
run_id: self.task_id.map(|id| id.to_string()),
@@ -3407,6 +3435,11 @@ impl AIConversation {
34073435
}
34083436
}
34093437

3438+
fn parse_orchestration_harness_type(value: &str) -> Harness {
3439+
Harness::from_config_name(value)
3440+
.or_else(|| Harness::parse_orchestration_harness(value))
3441+
.unwrap_or(Harness::Unknown)
3442+
}
34103443
pub(super) fn update_todo_list_from_todo_op(
34113444
todo_lists: &mut Vec<AIAgentTodoList>,
34123445
op: api::message::update_todos::Operation,

app/src/ai/agent_conversations_model_tests.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ fn test_display_status_uses_matching_conversation_for_in_progress_task() {
249249
artifacts_json: None,
250250
parent_agent_id: None,
251251
agent_name: None,
252+
orchestration_harness_type: None,
252253
parent_conversation_id: None,
253254
is_remote_child: false,
254255
run_id: Some(task_id.clone()),
@@ -303,6 +304,7 @@ fn test_display_status_uses_active_execution_over_previous_conversation_status()
303304
artifacts_json: None,
304305
parent_agent_id: None,
305306
agent_name: None,
307+
orchestration_harness_type: None,
306308
parent_conversation_id: None,
307309
is_remote_child: false,
308310
run_id: Some(task_id.clone()),
@@ -364,6 +366,7 @@ fn test_display_status_updates_when_blocked_conversation_resumes() {
364366
artifacts_json: None,
365367
parent_agent_id: None,
366368
agent_name: None,
369+
orchestration_harness_type: None,
367370
parent_conversation_id: None,
368371
is_remote_child: false,
369372
run_id: Some(task_id.clone()),
@@ -441,6 +444,7 @@ fn test_display_status_terminal_task_state_overrides_matching_conversation() {
441444
artifacts_json: None,
442445
parent_agent_id: None,
443446
agent_name: None,
447+
orchestration_harness_type: None,
444448
parent_conversation_id: None,
445449
is_remote_child: false,
446450
run_id: Some(task_id.clone()),
@@ -494,6 +498,7 @@ fn test_status_filter_uses_display_status_for_task_backed_conversations() {
494498
artifacts_json: None,
495499
parent_agent_id: None,
496500
agent_name: None,
501+
orchestration_harness_type: None,
497502
parent_conversation_id: None,
498503
is_remote_child: false,
499504
run_id: Some(task_id.clone()),
@@ -787,6 +792,7 @@ fn test_get_entries_merges_task_and_local_conversation_by_run_id() {
787792
artifacts_json: None,
788793
parent_agent_id: None,
789794
agent_name: None,
795+
orchestration_harness_type: None,
790796
parent_conversation_id: None,
791797
is_remote_child: false,
792798
run_id: Some(task_id.clone()),
@@ -839,6 +845,7 @@ fn test_get_entries_merges_task_and_local_conversation_by_server_token() {
839845
artifacts_json: None,
840846
parent_agent_id: None,
841847
agent_name: None,
848+
orchestration_harness_type: None,
842849
parent_conversation_id: None,
843850
is_remote_child: false,
844851
run_id: None,
@@ -1006,6 +1013,7 @@ fn test_resolve_open_action_falls_back_to_local_conversation_for_invalid_session
10061013
artifacts_json: None,
10071014
parent_agent_id: None,
10081015
agent_name: None,
1016+
orchestration_harness_type: None,
10091017
parent_conversation_id: None,
10101018
is_remote_child: false,
10111019
run_id: Some(task_id.clone()),
@@ -1392,6 +1400,7 @@ fn test_get_tasks_and_conversations_prefers_task_when_task_id_matches_conversati
13921400
artifacts_json: None,
13931401
parent_agent_id: None,
13941402
agent_name: None,
1403+
orchestration_harness_type: None,
13951404
parent_conversation_id: None,
13961405
is_remote_child: false,
13971406
run_id: Some(task_id.clone()),
@@ -1450,6 +1459,7 @@ fn test_get_tasks_and_conversations_prefers_task_when_server_token_matches() {
14501459
artifacts_json: None,
14511460
parent_agent_id: None,
14521461
agent_name: None,
1462+
orchestration_harness_type: None,
14531463
parent_conversation_id: None,
14541464
is_remote_child: false,
14551465
run_id: None,
@@ -1507,6 +1517,7 @@ fn test_get_tasks_and_conversations_keeps_unrelated_tasks_and_conversations() {
15071517
artifacts_json: None,
15081518
parent_agent_id: None,
15091519
agent_name: None,
1520+
orchestration_harness_type: None,
15101521
parent_conversation_id: None,
15111522
is_remote_child: false,
15121523
run_id: None,

app/src/ai/blocklist/action_model/execute/start_agent_tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ fn execute_returns_error_when_child_startup_is_blocked_before_initialization() {
6666
terminal_view_id,
6767
"Agent 1".to_string(),
6868
parent_conversation_id,
69+
None,
6970
ctx,
7071
)
7172
});
@@ -154,6 +155,7 @@ fn execute_returns_detailed_error_when_child_startup_fails_before_initialization
154155
terminal_view_id,
155156
"Agent 1".to_string(),
156157
parent_conversation_id,
158+
None,
157159
ctx,
158160
)
159161
});
@@ -410,6 +412,7 @@ fn parallel_pendings_each_resolve_independently_via_recorded_child_id() {
410412
terminal_view_id,
411413
"Agent A".to_string(),
412414
parent_conversation_id,
415+
None,
413416
ctx,
414417
)
415418
});
@@ -418,6 +421,7 @@ fn parallel_pendings_each_resolve_independently_via_recorded_child_id() {
418421
terminal_view_id,
419422
"Agent B".to_string(),
420423
parent_conversation_id,
424+
None,
421425
ctx,
422426
)
423427
});

app/src/ai/blocklist/agent_view/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod controller;
66
mod ephemeral_message_model;
77
mod inline_agent_view_header;
88
// TODO: Move orchestration_conversation_links module import elsewhere.
9+
pub(crate) mod orchestration_avatar;
910
pub(crate) mod orchestration_conversation_links;
1011
pub mod orchestration_pill_bar;
1112
pub mod shortcuts;

0 commit comments

Comments
 (0)