mirror of
https://github.com/openai/codex.git
synced 2026-05-07 04:47:13 +00:00
Compare commits
4 Commits
split-mcp-
...
aibrahim/c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a7907b3c8 | ||
|
|
1451f288b9 | ||
|
|
271b723b44 | ||
|
|
cfb3b3e56c |
@@ -3015,16 +3015,10 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"prompt": {
|
||||
"description": "Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning.",
|
||||
"type": "string"
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
"sender_thread_id": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -3043,9 +3037,7 @@
|
||||
},
|
||||
"required": [
|
||||
"call_id",
|
||||
"model",
|
||||
"prompt",
|
||||
"reasoning_effort",
|
||||
"sender_thread_id",
|
||||
"type"
|
||||
],
|
||||
@@ -3505,6 +3497,24 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"description": "Model configured for the receiver agent when available.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Reasoning effort configured for the receiver agent when available."
|
||||
},
|
||||
"receiver_agent_nickname": {
|
||||
"description": "Optional nickname assigned to the receiver agent.",
|
||||
"type": [
|
||||
@@ -9248,16 +9258,10 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"prompt": {
|
||||
"description": "Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning.",
|
||||
"type": "string"
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
"sender_thread_id": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -9276,9 +9280,7 @@
|
||||
},
|
||||
"required": [
|
||||
"call_id",
|
||||
"model",
|
||||
"prompt",
|
||||
"reasoning_effort",
|
||||
"sender_thread_id",
|
||||
"type"
|
||||
],
|
||||
@@ -9738,6 +9740,24 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"description": "Model configured for the receiver agent when available.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Reasoning effort configured for the receiver agent when available."
|
||||
},
|
||||
"receiver_agent_nickname": {
|
||||
"description": "Optional nickname assigned to the receiver agent.",
|
||||
"type": [
|
||||
|
||||
@@ -4378,16 +4378,10 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"prompt": {
|
||||
"description": "Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning.",
|
||||
"type": "string"
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"$ref": "#/definitions/v2/ReasoningEffort"
|
||||
},
|
||||
"sender_thread_id": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -4406,9 +4400,7 @@
|
||||
},
|
||||
"required": [
|
||||
"call_id",
|
||||
"model",
|
||||
"prompt",
|
||||
"reasoning_effort",
|
||||
"sender_thread_id",
|
||||
"type"
|
||||
],
|
||||
@@ -4868,6 +4860,24 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"description": "Model configured for the receiver agent when available.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ReasoningEffort"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Reasoning effort configured for the receiver agent when available."
|
||||
},
|
||||
"receiver_agent_nickname": {
|
||||
"description": "Optional nickname assigned to the receiver agent.",
|
||||
"type": [
|
||||
|
||||
@@ -6180,16 +6180,10 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"prompt": {
|
||||
"description": "Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning.",
|
||||
"type": "string"
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
"sender_thread_id": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -6208,9 +6202,7 @@
|
||||
},
|
||||
"required": [
|
||||
"call_id",
|
||||
"model",
|
||||
"prompt",
|
||||
"reasoning_effort",
|
||||
"sender_thread_id",
|
||||
"type"
|
||||
],
|
||||
@@ -6670,6 +6662,24 @@
|
||||
"description": "Identifier for the collab tool call.",
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"description": "Model configured for the receiver agent when available.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reasoning_effort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Reasoning effort configured for the receiver agent when available."
|
||||
},
|
||||
"receiver_agent_nickname": {
|
||||
"description": "Optional nickname assigned to the receiver agent.",
|
||||
"type": [
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ReasoningEffort } from "./ReasoningEffort";
|
||||
import type { ThreadId } from "./ThreadId";
|
||||
|
||||
export type CollabAgentSpawnBeginEvent = {
|
||||
@@ -17,4 +16,4 @@ sender_thread_id: ThreadId,
|
||||
* Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the
|
||||
* beginning.
|
||||
*/
|
||||
prompt: string, model: string, reasoning_effort: ReasoningEffort, };
|
||||
prompt: string, };
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AgentStatus } from "./AgentStatus";
|
||||
import type { ReasoningEffort } from "./ReasoningEffort";
|
||||
import type { ThreadId } from "./ThreadId";
|
||||
|
||||
export type CollabResumeEndEvent = {
|
||||
@@ -25,6 +26,14 @@ receiver_agent_nickname?: string | null,
|
||||
* Optional role assigned to the receiver agent.
|
||||
*/
|
||||
receiver_agent_role?: string | null,
|
||||
/**
|
||||
* Model configured for the receiver agent when available.
|
||||
*/
|
||||
model?: string | null,
|
||||
/**
|
||||
* Reasoning effort configured for the receiver agent when available.
|
||||
*/
|
||||
reasoning_effort?: ReasoningEffort | null,
|
||||
/**
|
||||
* Last known status of the receiver agent reported to the sender agent after
|
||||
* resume.
|
||||
|
||||
@@ -554,8 +554,8 @@ impl ThreadHistoryBuilder {
|
||||
sender_thread_id: payload.sender_thread_id.to_string(),
|
||||
receiver_thread_ids: Vec::new(),
|
||||
prompt: Some(payload.prompt.clone()),
|
||||
model: Some(payload.model.clone()),
|
||||
reasoning_effort: Some(payload.reasoning_effort),
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
agents_states: HashMap::new(),
|
||||
};
|
||||
self.upsert_item_in_current_turn(item);
|
||||
@@ -775,8 +775,8 @@ impl ThreadHistoryBuilder {
|
||||
sender_thread_id: payload.sender_thread_id.to_string(),
|
||||
receiver_thread_ids: vec![receiver_id],
|
||||
prompt: None,
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
model: payload.model.clone(),
|
||||
reasoning_effort: payload.reasoning_effort,
|
||||
agents_states,
|
||||
});
|
||||
}
|
||||
@@ -2325,6 +2325,8 @@ mod tests {
|
||||
.expect("valid receiver thread id"),
|
||||
receiver_agent_nickname: None,
|
||||
receiver_agent_role: None,
|
||||
model: Some("gpt-5.4-mini".into()),
|
||||
reasoning_effort: Some(codex_protocol::openai_models::ReasoningEffort::High),
|
||||
status: AgentStatus::Completed(None),
|
||||
}),
|
||||
];
|
||||
@@ -2345,8 +2347,8 @@ mod tests {
|
||||
sender_thread_id: "00000000-0000-0000-0000-000000000001".into(),
|
||||
receiver_thread_ids: vec!["00000000-0000-0000-0000-000000000002".into()],
|
||||
prompt: None,
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
model: Some("gpt-5.4-mini".into()),
|
||||
reasoning_effort: Some(codex_protocol::openai_models::ReasoningEffort::High),
|
||||
agents_states: [(
|
||||
"00000000-0000-0000-0000-000000000002".into(),
|
||||
CollabAgentState {
|
||||
@@ -2417,6 +2419,60 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reconstructs_collab_close_end_item_without_model_metadata() {
|
||||
let sender_thread_id = ThreadId::try_from("00000000-0000-0000-0000-000000000001")
|
||||
.expect("valid sender thread id");
|
||||
let receiver_thread_id = ThreadId::try_from("00000000-0000-0000-0000-000000000002")
|
||||
.expect("valid receiver thread id");
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
message: "close agent".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
local_images: Vec::new(),
|
||||
}),
|
||||
EventMsg::CollabCloseEnd(codex_protocol::protocol::CollabCloseEndEvent {
|
||||
call_id: "close-1".into(),
|
||||
sender_thread_id,
|
||||
receiver_thread_id,
|
||||
receiver_agent_nickname: Some("Scout".into()),
|
||||
receiver_agent_role: Some("explorer".into()),
|
||||
status: AgentStatus::Completed(None),
|
||||
}),
|
||||
];
|
||||
|
||||
let items = events
|
||||
.into_iter()
|
||||
.map(RolloutItem::EventMsg)
|
||||
.collect::<Vec<_>>();
|
||||
let turns = build_turns_from_rollout_items(&items);
|
||||
assert_eq!(turns.len(), 1);
|
||||
assert_eq!(turns[0].items.len(), 2);
|
||||
assert_eq!(
|
||||
turns[0].items[1],
|
||||
ThreadItem::CollabAgentToolCall {
|
||||
id: "close-1".into(),
|
||||
tool: CollabAgentTool::CloseAgent,
|
||||
status: CollabAgentToolCallStatus::Completed,
|
||||
sender_thread_id: "00000000-0000-0000-0000-000000000001".into(),
|
||||
receiver_thread_ids: vec!["00000000-0000-0000-0000-000000000002".into()],
|
||||
prompt: None,
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
agents_states: [(
|
||||
"00000000-0000-0000-0000-000000000002".into(),
|
||||
CollabAgentState {
|
||||
status: crate::protocol::v2::CollabAgentStatus::Completed,
|
||||
message: None,
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rollback_failed_error_does_not_mark_turn_failed() {
|
||||
let events = vec![
|
||||
|
||||
@@ -862,8 +862,8 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
sender_thread_id: begin_event.sender_thread_id.to_string(),
|
||||
receiver_thread_ids: Vec::new(),
|
||||
prompt: Some(begin_event.prompt),
|
||||
model: Some(begin_event.model),
|
||||
reasoning_effort: Some(begin_event.reasoning_effort),
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
agents_states: HashMap::new(),
|
||||
};
|
||||
let notification = ItemStartedNotification {
|
||||
@@ -2557,8 +2557,8 @@ fn collab_resume_end_item(end_event: codex_protocol::protocol::CollabResumeEndEv
|
||||
sender_thread_id: end_event.sender_thread_id.to_string(),
|
||||
receiver_thread_ids: vec![receiver_id],
|
||||
prompt: None,
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
model: end_event.model,
|
||||
reasoning_effort: end_event.reasoning_effort,
|
||||
agents_states,
|
||||
}
|
||||
}
|
||||
@@ -2946,6 +2946,8 @@ mod tests {
|
||||
receiver_thread_id: ThreadId::new(),
|
||||
receiver_agent_nickname: None,
|
||||
receiver_agent_role: None,
|
||||
model: Some("gpt-5.4-mini".to_string()),
|
||||
reasoning_effort: Some(codex_protocol::openai_models::ReasoningEffort::High),
|
||||
status: codex_protocol::protocol::AgentStatus::NotFound,
|
||||
};
|
||||
|
||||
@@ -2958,8 +2960,8 @@ mod tests {
|
||||
sender_thread_id: event.sender_thread_id.to_string(),
|
||||
receiver_thread_ids: vec![receiver_id.clone()],
|
||||
prompt: None,
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
model: Some("gpt-5.4-mini".to_string()),
|
||||
reasoning_effort: Some(codex_protocol::openai_models::ReasoningEffort::High),
|
||||
agents_states: [(
|
||||
receiver_id,
|
||||
V2CollabAgentStatus::from(codex_protocol::protocol::AgentStatus::NotFound),
|
||||
|
||||
@@ -1664,7 +1664,7 @@ async fn turn_start_file_change_approval_v2() -> Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_emits_spawn_agent_item_with_model_metadata_v2() -> Result<()> {
|
||||
async fn turn_start_omits_spawn_agent_model_metadata_until_completion_v2() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
const CHILD_PROMPT: &str = "child: do work";
|
||||
@@ -1777,8 +1777,8 @@ async fn turn_start_emits_spawn_agent_item_with_model_metadata_v2() -> Result<()
|
||||
sender_thread_id: thread.id.clone(),
|
||||
receiver_thread_ids: Vec::new(),
|
||||
prompt: Some(CHILD_PROMPT.to_string()),
|
||||
model: Some(REQUESTED_MODEL.to_string()),
|
||||
reasoning_effort: Some(REQUESTED_REASONING_EFFORT),
|
||||
model: None,
|
||||
reasoning_effort: None,
|
||||
agents_states: HashMap::new(),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -74,6 +74,14 @@ pub(crate) struct AgentControl {
|
||||
state: Arc<Guards>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct AgentMetadata {
|
||||
pub(crate) nickname: Option<String>,
|
||||
pub(crate) role: Option<String>,
|
||||
pub(crate) model: String,
|
||||
pub(crate) reasoning_effort: Option<codex_protocol::openai_models::ReasoningEffort>,
|
||||
}
|
||||
|
||||
impl AgentControl {
|
||||
/// Construct a new `AgentControl` that can spawn/message agents via the given manager state.
|
||||
pub(crate) fn new(manager: Weak<ThreadManagerState>) -> Self {
|
||||
@@ -347,17 +355,26 @@ impl AgentControl {
|
||||
&self,
|
||||
agent_id: ThreadId,
|
||||
) -> Option<(Option<String>, Option<String>)> {
|
||||
self.get_agent_metadata(agent_id)
|
||||
.await
|
||||
.map(|metadata| (metadata.nickname, metadata.role))
|
||||
}
|
||||
|
||||
pub(crate) async fn get_agent_metadata(&self, agent_id: ThreadId) -> Option<AgentMetadata> {
|
||||
let Ok(state) = self.upgrade() else {
|
||||
return None;
|
||||
};
|
||||
let Ok(thread) = state.get_thread(agent_id).await else {
|
||||
return None;
|
||||
};
|
||||
let session_source = thread.config_snapshot().await.session_source;
|
||||
Some((
|
||||
session_source.get_nickname(),
|
||||
session_source.get_agent_role(),
|
||||
))
|
||||
let snapshot = thread.config_snapshot().await;
|
||||
let session_source = snapshot.session_source;
|
||||
Some(AgentMetadata {
|
||||
nickname: session_source.get_nickname(),
|
||||
role: session_source.get_agent_role(),
|
||||
model: snapshot.model,
|
||||
reasoning_effort: snapshot.reasoning_effort,
|
||||
})
|
||||
}
|
||||
|
||||
/// Subscribe to status updates for `agent_id`, yielding the latest value and changes.
|
||||
|
||||
@@ -157,8 +157,6 @@ mod spawn {
|
||||
call_id: call_id.clone(),
|
||||
sender_thread_id: session.conversation_id,
|
||||
prompt: prompt.clone(),
|
||||
model: args.model.clone().unwrap_or_default(),
|
||||
reasoning_effort: args.reasoning_effort.unwrap_or_default(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
@@ -178,6 +176,8 @@ mod spawn {
|
||||
.map_err(FunctionCallError::RespondToModel)?;
|
||||
apply_spawn_agent_runtime_overrides(&mut config, turn.as_ref())?;
|
||||
apply_spawn_agent_overrides(&mut config, child_depth);
|
||||
let configured_model = config.model.clone().unwrap_or_default();
|
||||
let configured_reasoning_effort = config.model_reasoning_effort.unwrap_or_default();
|
||||
|
||||
let result = session
|
||||
.services
|
||||
@@ -203,15 +203,30 @@ mod spawn {
|
||||
),
|
||||
Err(_) => (None, AgentStatus::NotFound),
|
||||
};
|
||||
let (new_agent_nickname, new_agent_role) = match new_thread_id {
|
||||
Some(thread_id) => session
|
||||
.services
|
||||
.agent_control
|
||||
.get_agent_nickname_and_role(thread_id)
|
||||
.await
|
||||
.unwrap_or((None, None)),
|
||||
None => (None, None),
|
||||
let agent_metadata = match new_thread_id {
|
||||
Some(thread_id) => {
|
||||
session
|
||||
.services
|
||||
.agent_control
|
||||
.get_agent_metadata(thread_id)
|
||||
.await
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
let new_agent_nickname = agent_metadata
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.nickname.clone());
|
||||
let new_agent_role = agent_metadata
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.role.clone());
|
||||
let spawned_model = agent_metadata
|
||||
.as_ref()
|
||||
.map(|metadata| metadata.model.clone())
|
||||
.unwrap_or(configured_model);
|
||||
let spawned_reasoning_effort = agent_metadata
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.reasoning_effort)
|
||||
.unwrap_or(configured_reasoning_effort);
|
||||
let nickname = new_agent_nickname.clone();
|
||||
session
|
||||
.send_event(
|
||||
@@ -223,8 +238,8 @@ mod spawn {
|
||||
new_agent_nickname,
|
||||
new_agent_role,
|
||||
prompt,
|
||||
model: args.model.clone().unwrap_or_default(),
|
||||
reasoning_effort: args.reasoning_effort.unwrap_or_default(),
|
||||
model: spawned_model,
|
||||
reasoning_effort: spawned_reasoning_effort,
|
||||
status,
|
||||
}
|
||||
.into(),
|
||||
@@ -360,12 +375,25 @@ mod resume_agent {
|
||||
) -> Result<FunctionToolOutput, FunctionCallError> {
|
||||
let args: ResumeAgentArgs = parse_arguments(&arguments)?;
|
||||
let receiver_thread_id = agent_id(&args.id)?;
|
||||
let (receiver_agent_nickname, receiver_agent_role) = session
|
||||
let receiver_agent_metadata = session
|
||||
.services
|
||||
.agent_control
|
||||
.get_agent_nickname_and_role(receiver_thread_id)
|
||||
.get_agent_metadata(receiver_thread_id)
|
||||
.await
|
||||
.unwrap_or((None, None));
|
||||
.map(|metadata| {
|
||||
let nickname = metadata.nickname;
|
||||
let role = metadata.role;
|
||||
let model = Some(metadata.model);
|
||||
let reasoning_effort = metadata.reasoning_effort;
|
||||
(nickname, role, model, reasoning_effort)
|
||||
})
|
||||
.unwrap_or((None, None, None, None));
|
||||
let (
|
||||
receiver_agent_nickname,
|
||||
receiver_agent_role,
|
||||
receiver_model,
|
||||
receiver_reasoning_effort,
|
||||
) = receiver_agent_metadata;
|
||||
let child_depth = next_thread_spawn_depth(&turn.session_source);
|
||||
let max_depth = turn.config.agent_max_depth;
|
||||
if exceeds_thread_spawn_depth_limit(child_depth, max_depth) {
|
||||
@@ -413,12 +441,30 @@ mod resume_agent {
|
||||
None
|
||||
};
|
||||
|
||||
let (receiver_agent_nickname, receiver_agent_role) = session
|
||||
let (
|
||||
receiver_agent_nickname,
|
||||
receiver_agent_role,
|
||||
receiver_model,
|
||||
receiver_reasoning_effort,
|
||||
) = session
|
||||
.services
|
||||
.agent_control
|
||||
.get_agent_nickname_and_role(receiver_thread_id)
|
||||
.get_agent_metadata(receiver_thread_id)
|
||||
.await
|
||||
.unwrap_or((receiver_agent_nickname, receiver_agent_role));
|
||||
.map(|metadata| {
|
||||
(
|
||||
metadata.nickname,
|
||||
metadata.role,
|
||||
Some(metadata.model),
|
||||
metadata.reasoning_effort,
|
||||
)
|
||||
})
|
||||
.unwrap_or((
|
||||
receiver_agent_nickname,
|
||||
receiver_agent_role,
|
||||
receiver_model,
|
||||
receiver_reasoning_effort,
|
||||
));
|
||||
session
|
||||
.send_event(
|
||||
&turn,
|
||||
@@ -428,6 +474,8 @@ mod resume_agent {
|
||||
receiver_thread_id,
|
||||
receiver_agent_nickname,
|
||||
receiver_agent_role,
|
||||
model: receiver_model,
|
||||
reasoning_effort: receiver_reasoning_effort,
|
||||
status: status.clone(),
|
||||
}
|
||||
.into(),
|
||||
|
||||
@@ -548,8 +548,6 @@ fn collab_spawn_begin_and_end_emit_item_events() {
|
||||
call_id: "call-10".to_string(),
|
||||
sender_thread_id,
|
||||
prompt: prompt.clone(),
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::default(),
|
||||
}),
|
||||
);
|
||||
let begin_events = ep.collect_thread_events(&begin);
|
||||
|
||||
@@ -3132,8 +3132,6 @@ pub struct CollabAgentSpawnBeginEvent {
|
||||
/// Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the
|
||||
/// beginning.
|
||||
pub prompt: String,
|
||||
pub model: String,
|
||||
pub reasoning_effort: ReasoningEffortConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
@@ -3306,6 +3304,12 @@ pub struct CollabResumeEndEvent {
|
||||
/// Optional role assigned to the receiver agent.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub receiver_agent_role: Option<String>,
|
||||
/// Model configured for the receiver agent when available.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub model: Option<String>,
|
||||
/// Reasoning effort configured for the receiver agent when available.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub reasoning_effort: Option<ReasoningEffortConfig>,
|
||||
/// Last known status of the receiver agent reported to the sender agent after
|
||||
/// resume.
|
||||
pub status: AgentStatus,
|
||||
|
||||
@@ -580,7 +580,6 @@ pub(crate) struct ChatWidget {
|
||||
// Latest completed user-visible Codex output that `/copy` should place on the clipboard.
|
||||
last_copyable_output: Option<String>,
|
||||
running_commands: HashMap<String, RunningCommand>,
|
||||
pending_collab_spawn_requests: HashMap<String, multi_agents::SpawnRequestSummary>,
|
||||
suppressed_exec_calls: HashSet<String>,
|
||||
skills_all: Vec<ProtocolSkillMetadata>,
|
||||
skills_initial_state: Option<HashMap<PathBuf, bool>>,
|
||||
@@ -3257,7 +3256,6 @@ impl ChatWidget {
|
||||
plan_stream_controller: None,
|
||||
last_copyable_output: None,
|
||||
running_commands: HashMap::new(),
|
||||
pending_collab_spawn_requests: HashMap::new(),
|
||||
suppressed_exec_calls: HashSet::new(),
|
||||
last_unified_wait: None,
|
||||
unified_exec_wait_streak: None,
|
||||
@@ -3442,7 +3440,6 @@ impl ChatWidget {
|
||||
plan_stream_controller: None,
|
||||
last_copyable_output: None,
|
||||
running_commands: HashMap::new(),
|
||||
pending_collab_spawn_requests: HashMap::new(),
|
||||
suppressed_exec_calls: HashSet::new(),
|
||||
last_unified_wait: None,
|
||||
unified_exec_wait_streak: None,
|
||||
@@ -3619,7 +3616,6 @@ impl ChatWidget {
|
||||
plan_stream_controller: None,
|
||||
last_copyable_output: None,
|
||||
running_commands: HashMap::new(),
|
||||
pending_collab_spawn_requests: HashMap::new(),
|
||||
suppressed_exec_calls: HashSet::new(),
|
||||
last_unified_wait: None,
|
||||
unified_exec_wait_streak: None,
|
||||
@@ -5020,23 +5016,9 @@ impl ChatWidget {
|
||||
}
|
||||
EventMsg::ExitedReviewMode(review) => self.on_exited_review_mode(review),
|
||||
EventMsg::ContextCompacted(_) => self.on_agent_message("Context compacted".to_owned()),
|
||||
EventMsg::CollabAgentSpawnBegin(CollabAgentSpawnBeginEvent {
|
||||
call_id,
|
||||
model,
|
||||
reasoning_effort,
|
||||
..
|
||||
}) => {
|
||||
self.pending_collab_spawn_requests.insert(
|
||||
call_id,
|
||||
multi_agents::SpawnRequestSummary {
|
||||
model,
|
||||
reasoning_effort,
|
||||
},
|
||||
);
|
||||
}
|
||||
EventMsg::CollabAgentSpawnBegin(CollabAgentSpawnBeginEvent { .. }) => {}
|
||||
EventMsg::CollabAgentSpawnEnd(ev) => {
|
||||
let spawn_request = self.pending_collab_spawn_requests.remove(&ev.call_id);
|
||||
self.on_collab_event(multi_agents::spawn_end(ev, spawn_request.as_ref()));
|
||||
self.on_collab_event(multi_agents::spawn_end(ev));
|
||||
}
|
||||
EventMsg::CollabAgentInteractionBegin(_) => {}
|
||||
EventMsg::CollabAgentInteractionEnd(ev) => {
|
||||
|
||||
@@ -1841,7 +1841,6 @@ async fn make_chatwidget_manual(
|
||||
plan_stream_controller: None,
|
||||
last_copyable_output: None,
|
||||
running_commands: HashMap::new(),
|
||||
pending_collab_spawn_requests: HashMap::new(),
|
||||
suppressed_exec_calls: HashSet::new(),
|
||||
skills_all: Vec::new(),
|
||||
skills_initial_state: None,
|
||||
@@ -2027,8 +2026,6 @@ async fn collab_spawn_end_shows_requested_model_and_effort() {
|
||||
call_id: "call-spawn".to_string(),
|
||||
sender_thread_id,
|
||||
prompt: "Explore the repo".to_string(),
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
}),
|
||||
});
|
||||
chat.handle_codex_event(Event {
|
||||
|
||||
@@ -171,10 +171,7 @@ fn next_agent_word_motion_fallback(
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn spawn_end(
|
||||
ev: CollabAgentSpawnEndEvent,
|
||||
spawn_request: Option<&SpawnRequestSummary>,
|
||||
) -> PlainHistoryCell {
|
||||
pub(crate) fn spawn_end(ev: CollabAgentSpawnEndEvent) -> PlainHistoryCell {
|
||||
let CollabAgentSpawnEndEvent {
|
||||
call_id: _,
|
||||
sender_thread_id: _,
|
||||
@@ -182,9 +179,14 @@ pub(crate) fn spawn_end(
|
||||
new_agent_nickname,
|
||||
new_agent_role,
|
||||
prompt,
|
||||
model,
|
||||
reasoning_effort,
|
||||
status: _,
|
||||
..
|
||||
} = ev;
|
||||
let spawn_summary = SpawnRequestSummary {
|
||||
model,
|
||||
reasoning_effort,
|
||||
};
|
||||
|
||||
let title = match new_thread_id {
|
||||
Some(thread_id) => title_with_agent(
|
||||
@@ -194,7 +196,7 @@ pub(crate) fn spawn_end(
|
||||
nickname: new_agent_nickname.as_deref(),
|
||||
role: new_agent_role.as_deref(),
|
||||
},
|
||||
spawn_request,
|
||||
Some(&spawn_summary),
|
||||
),
|
||||
None => title_text("Agent spawn failed"),
|
||||
};
|
||||
@@ -327,6 +329,7 @@ pub(crate) fn resume_end(ev: CollabResumeEndEvent) -> PlainHistoryCell {
|
||||
receiver_agent_nickname,
|
||||
receiver_agent_role,
|
||||
status,
|
||||
..
|
||||
} = ev;
|
||||
|
||||
collab_event(
|
||||
@@ -594,23 +597,17 @@ mod tests {
|
||||
let bob_id = ThreadId::from_string("00000000-0000-0000-0000-000000000003")
|
||||
.expect("valid bob thread id");
|
||||
|
||||
let spawn = spawn_end(
|
||||
CollabAgentSpawnEndEvent {
|
||||
call_id: "call-spawn".to_string(),
|
||||
sender_thread_id,
|
||||
new_thread_id: Some(robie_id),
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: "Compute 11! and reply with just the integer result.".to_string(),
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
},
|
||||
Some(&SpawnRequestSummary {
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
}),
|
||||
);
|
||||
let spawn = spawn_end(CollabAgentSpawnEndEvent {
|
||||
call_id: "call-spawn".to_string(),
|
||||
sender_thread_id,
|
||||
new_thread_id: Some(robie_id),
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: "Compute 11! and reply with just the integer result.".to_string(),
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
});
|
||||
|
||||
let send = interaction_end(CollabAgentInteractionEndEvent {
|
||||
call_id: "call-send".to_string(),
|
||||
@@ -732,23 +729,17 @@ mod tests {
|
||||
.expect("valid sender thread id");
|
||||
let robie_id = ThreadId::from_string("00000000-0000-0000-0000-000000000002")
|
||||
.expect("valid robie thread id");
|
||||
let cell = spawn_end(
|
||||
CollabAgentSpawnEndEvent {
|
||||
call_id: "call-spawn".to_string(),
|
||||
sender_thread_id,
|
||||
new_thread_id: Some(robie_id),
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: String::new(),
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
},
|
||||
Some(&SpawnRequestSummary {
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
}),
|
||||
);
|
||||
let cell = spawn_end(CollabAgentSpawnEndEvent {
|
||||
call_id: "call-spawn".to_string(),
|
||||
sender_thread_id,
|
||||
new_thread_id: Some(robie_id),
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: String::new(),
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
});
|
||||
|
||||
let lines = cell.display_lines(200);
|
||||
let title = &lines[0];
|
||||
|
||||
Reference in New Issue
Block a user