Return LiveAgent records from agent listing (#46553)

## What changed

Return thread IDs, metadata, and status from `LocalAgentControl::list_agents` using the shared `LiveAgent` type. Move conversion to `ListedAgent` into the tool handler, preserving the `list_agents` response fields and the thread ID fallback for agents without a path.

GitOrigin-RevId: c935cf96ab2a370645a4b74e3306540fc2d168a5
This commit is contained in:
jif
2026-09-19 01:21:09 +00:00
committed by copyberry
parent 7a15548c6a
commit c6f5d9e9b5
2 changed files with 32 additions and 20 deletions
+14 -19
View File
@@ -7,6 +7,7 @@ use crate::agent::role::DEFAULT_ROLE_NAME;
use crate::agent::role::resolve_role_config;
use crate::agent::status::is_final;
use crate::agent::types::AgentMetadata;
use crate::agent::types::LiveAgent;
use crate::agent_communication::AgentCommunicationContext;
use crate::agent_communication::AgentCommunicationKind;
use crate::codex_thread::ThreadConfigSnapshot;
@@ -54,7 +55,6 @@ use codex_protocol::protocol::ThreadSource;
use codex_protocol::user_input::UserInput;
use codex_thread_store::LoadThreadHistoryParams;
use codex_thread_store::ReadThreadParams;
use serde::Serialize;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;
@@ -84,12 +84,6 @@ mod user_authorization;
const MAX_ENVIRONMENT_SUBAGENTS: usize = 8;
const MAX_ENVIRONMENT_SUBAGENT_BYTES: usize = 1_024;
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
pub(crate) struct ListedAgent {
pub(crate) agent_name: String,
pub(crate) agent_status: AgentStatus,
}
/// Control-plane handle for multi-agent operations.
/// `LocalAgentControl` is held by each session (via `SessionServices`). It provides capability to
/// spawn new agents and the inter-agent communication layer.
@@ -527,7 +521,7 @@ impl LocalAgentControl {
&self,
current_session_source: &SessionSource,
path_prefix: Option<&str>,
) -> CodexResult<Vec<ListedAgent>> {
) -> CodexResult<Vec<LiveAgent>> {
let state = self.upgrade()?;
let resolved_prefix = path_prefix
.map(|prefix| {
@@ -561,9 +555,14 @@ impl LocalAgentControl {
&& let Some(root_thread_id) = self.state.agent_id_for_path(&root_path)
&& let Ok(root_thread) = state.get_thread(root_thread_id).await
{
agents.push(ListedAgent {
agent_name: root_path.to_string(),
agent_status: root_thread.agent_status().await,
agents.push(LiveAgent {
thread_id: root_thread_id,
metadata: AgentMetadata {
agent_id: Some(root_thread_id),
agent_path: Some(root_path),
..Default::default()
},
status: root_thread.agent_status().await,
});
}
@@ -581,14 +580,10 @@ impl LocalAgentControl {
let Ok(thread) = state.get_thread(thread_id).await else {
continue;
};
let agent_name = metadata
.agent_path
.as_ref()
.map(ToString::to_string)
.unwrap_or_else(|| thread_id.to_string());
agents.push(ListedAgent {
agent_name,
agent_status: thread.agent_status().await,
agents.push(LiveAgent {
thread_id,
metadata,
status: thread.agent_status().await,
});
}
@@ -1,6 +1,5 @@
use super::analytics::ToolCallAnalytics;
use super::*;
use crate::agent::control::ListedAgent;
use crate::tools::handlers::multi_agents_spec::create_list_agents_tool;
use codex_tools::ToolSpec;
@@ -52,6 +51,18 @@ impl Handler {
.await
.map_err(collab_spawn_error)?;
let agents = agents
.into_iter()
.map(|agent| ListedAgent {
agent_name: agent
.metadata
.agent_path
.as_ref()
.map(ToString::to_string)
.unwrap_or_else(|| agent.thread_id.to_string()),
agent_status: agent.status,
})
.collect();
Ok(boxed_tool_output(ListAgentsResult { agents }))
}
}
@@ -68,6 +79,12 @@ struct ListAgentsArgs {
path_prefix: Option<String>,
}
#[derive(Debug, Serialize)]
struct ListedAgent {
agent_name: String,
agent_status: AgentStatus,
}
#[derive(Debug, Serialize)]
pub(crate) struct ListAgentsResult {
agents: Vec<ListedAgent>,