mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add multi-agent runtime metadata types (#25720)
Stack split from #25708. Original PR intentionally left open. This first PR adds the multi-agent runtime metadata types and catalog plumbing used by the rest of the stack.
This commit is contained in:
committed by
GitHub
Unverified
parent
45912a6dc6
commit
3f1fb7ed8b
@@ -54,6 +54,7 @@ fn preset_to_info(preset: &ModelPreset, priority: i32) -> ModelInfo {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ fn create_fake_rollout_with_source_and_parent_thread_id(
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
let payload = serde_json::to_value(SessionMetaLine {
|
||||
meta,
|
||||
@@ -279,6 +280,7 @@ pub fn create_fake_rollout_with_text_elements(
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
let payload = serde_json::to_value(SessionMetaLine {
|
||||
meta,
|
||||
|
||||
@@ -30,6 +30,10 @@ use codex_app_server_protocol::TurnStatus;
|
||||
use codex_app_server_protocol::UserInput;
|
||||
use codex_config::types::AuthCredentialsStoreMode;
|
||||
use codex_login::REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR;
|
||||
use codex_protocol::protocol::MultiAgentVersion;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_rollout::append_rollout_item_to_path;
|
||||
use codex_rollout::read_session_meta_line;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::Value;
|
||||
use serde_json::json;
|
||||
@@ -82,6 +86,9 @@ async fn thread_fork_creates_new_thread_and_emits_started() -> Result<()> {
|
||||
"expected original rollout to exist at {}",
|
||||
original_path.display()
|
||||
);
|
||||
let mut session_meta = read_session_meta_line(&original_path).await?;
|
||||
session_meta.meta.multi_agent_version = Some(MultiAgentVersion::V1);
|
||||
append_rollout_item_to_path(&original_path, &RolloutItem::SessionMeta(session_meta)).await?;
|
||||
let original_contents = std::fs::read_to_string(&original_path)?;
|
||||
|
||||
let mut mcp = TestAppServer::new(codex_home.path()).await?;
|
||||
|
||||
@@ -63,6 +63,8 @@ use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::ImageGenerationEndEvent;
|
||||
use codex_protocol::protocol::McpInvocation;
|
||||
use codex_protocol::protocol::McpToolCallEndEvent;
|
||||
use codex_protocol::protocol::MultiAgentVersion;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_protocol::protocol::SessionMeta;
|
||||
use codex_protocol::protocol::SessionMetaLine;
|
||||
use codex_protocol::protocol::SessionSource as RolloutSessionSource;
|
||||
@@ -74,6 +76,8 @@ use codex_protocol::protocol::TurnAbortedEvent;
|
||||
use codex_protocol::protocol::TurnStartedEvent;
|
||||
use codex_protocol::user_input::ByteRange;
|
||||
use codex_protocol::user_input::TextElement;
|
||||
use codex_rollout::append_rollout_item_to_path;
|
||||
use codex_rollout::read_session_meta_line;
|
||||
use codex_state::StateRuntime;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use core_test_support::responses;
|
||||
@@ -1805,6 +1809,7 @@ stream_max_retries = 0
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
std::fs::write(
|
||||
&rollout_path,
|
||||
@@ -2013,7 +2018,7 @@ async fn thread_resume_and_read_interrupt_incomplete_rollout_turn_when_thread_is
|
||||
async fn thread_resume_defers_updated_at_until_turn_start() -> Result<()> {
|
||||
let server = create_mock_responses_server_repeating_assistant("Done").await;
|
||||
let codex_home = TempDir::new()?;
|
||||
let rollout = setup_rollout_fixture(codex_home.path(), &server.uri())?;
|
||||
let rollout = setup_rollout_fixture(codex_home.path(), &server.uri()).await?;
|
||||
let thread_id = rollout.conversation_id.clone();
|
||||
|
||||
let mut mcp = TestAppServer::new(codex_home.path()).await?;
|
||||
@@ -3051,7 +3056,7 @@ async fn thread_resume_with_overrides_defers_updated_at_until_turn_start() -> Re
|
||||
async fn thread_resume_fails_when_required_mcp_server_fails_to_initialize() -> Result<()> {
|
||||
let server = create_mock_responses_server_repeating_assistant("Done").await;
|
||||
let codex_home = TempDir::new()?;
|
||||
let rollout = setup_rollout_fixture(codex_home.path(), &server.uri())?;
|
||||
let rollout = setup_rollout_fixture(codex_home.path(), &server.uri()).await?;
|
||||
create_config_toml_with_required_broken_mcp(codex_home.path(), &server.uri())?;
|
||||
|
||||
let mut mcp = TestAppServer::new(codex_home.path()).await?;
|
||||
@@ -3614,7 +3619,7 @@ struct RolloutFixture {
|
||||
before_modified: std::time::SystemTime,
|
||||
}
|
||||
|
||||
fn setup_rollout_fixture(codex_home: &Path, server_uri: &str) -> Result<RolloutFixture> {
|
||||
async fn setup_rollout_fixture(codex_home: &Path, server_uri: &str) -> Result<RolloutFixture> {
|
||||
create_config_toml(codex_home, server_uri)?;
|
||||
|
||||
let preview = "Saved user message";
|
||||
@@ -3631,6 +3636,10 @@ fn setup_rollout_fixture(codex_home: &Path, server_uri: &str) -> Result<RolloutF
|
||||
/*git_info*/ None,
|
||||
)?;
|
||||
let rollout_file_path = rollout_path(codex_home, filename_ts, &conversation_id);
|
||||
let mut session_meta = read_session_meta_line(&rollout_file_path).await?;
|
||||
session_meta.meta.multi_agent_version = Some(MultiAgentVersion::V1);
|
||||
append_rollout_item_to_path(&rollout_file_path, &RolloutItem::SessionMeta(session_meta))
|
||||
.await?;
|
||||
set_rollout_mtime(rollout_file_path.as_path(), expected_updated_at_rfc3339)?;
|
||||
let before_modified = std::fs::metadata(&rollout_file_path)?.modified()?;
|
||||
Ok(RolloutFixture {
|
||||
|
||||
@@ -100,6 +100,7 @@ async fn models_client_hits_models_endpoint() {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}],
|
||||
};
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ fn turn_context_item_filesystem_uses_workspace_roots_instead_of_cwd() {
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
|
||||
@@ -132,6 +132,7 @@ fn reference_context_item() -> TurnContextItem {
|
||||
model: "gpt-test".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(false),
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
|
||||
@@ -59,6 +59,7 @@ async fn write_rollout_with_user_event(dir: &Path, thread_id: ThreadId) -> io::R
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
|
||||
@@ -72,6 +72,7 @@ async fn record_initial_history_resumed_bare_turn_context_does_not_hydrate_previ
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -110,6 +111,7 @@ async fn record_initial_history_resumed_hydrates_previous_turn_settings_from_lif
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -959,6 +961,7 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -1037,6 +1040,7 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -1065,6 +1069,7 @@ async fn record_initial_history_resumed_aborted_turn_without_id_clears_active_tu
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -1183,6 +1188,7 @@ async fn record_initial_history_resumed_unmatched_abort_preserves_active_turn_fo
|
||||
model: current_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -1300,6 +1306,7 @@ async fn record_initial_history_resumed_trailing_incomplete_turn_compaction_clea
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -1458,6 +1465,7 @@ async fn record_initial_history_resumed_replaced_incomplete_compacted_turn_clear
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
|
||||
@@ -2471,6 +2471,7 @@ async fn record_initial_history_forked_hydrates_previous_turn_settings() {
|
||||
model: previous_model.to_string(),
|
||||
personality: turn_context.personality,
|
||||
collaboration_mode: Some(turn_context.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
effort: turn_context.reasoning_effort,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
|
||||
@@ -353,6 +353,7 @@ impl TurnContext {
|
||||
model: self.model_info.slug.clone(),
|
||||
personality: self.personality,
|
||||
collaboration_mode: Some(self.collaboration_mode.clone()),
|
||||
multi_agent_version: None,
|
||||
realtime_active: Some(self.realtime_active),
|
||||
effort: self.reasoning_effort,
|
||||
summary: ReasoningSummaryConfig::Auto,
|
||||
|
||||
@@ -233,6 +233,7 @@ fn remote_model_with_auto_review_override(slug: &str, review_model: &str) -> Mod
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: Some(review_model.to_string()),
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
|
||||
@@ -114,6 +114,7 @@ fn test_model_info(
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
@@ -933,6 +934,7 @@ async fn model_switch_to_smaller_model_updates_token_context_window() -> Result<
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
|
||||
@@ -372,5 +372,6 @@ fn test_remote_model(slug: &str, priority: i32) -> ModelInfo {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,6 +594,7 @@ async fn remote_model_friendly_personality_instructions_with_feature() -> anyhow
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
|
||||
let _models_mock = mount_models_once(
|
||||
@@ -706,6 +707,7 @@ async fn user_turn_personality_remote_model_template_includes_update_message() -
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
|
||||
let _models_mock = mount_models_once(
|
||||
|
||||
@@ -75,6 +75,7 @@ async fn write_rollout_with_user_event(dir: &Path, thread_id: ThreadId) -> io::R
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
@@ -124,6 +125,7 @@ async fn write_rollout_with_meta_only(dir: &Path, thread_id: ThreadId) -> io::Re
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
|
||||
@@ -479,6 +479,7 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
@@ -730,6 +731,7 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
@@ -1215,6 +1217,7 @@ fn test_remote_model_with_policy(
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
|
||||
@@ -39,6 +39,7 @@ fn resume_history(
|
||||
model: previous_model.to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: config.model_reasoning_effort,
|
||||
summary: config
|
||||
|
||||
@@ -1351,6 +1351,7 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -62,6 +62,7 @@ fn test_model_info(
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers,
|
||||
|
||||
@@ -222,6 +222,7 @@ async fn backfill_scans_existing_rollouts() -> Result<()> {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
|
||||
@@ -1357,6 +1357,7 @@ async fn view_image_tool_returns_unsupported_message_for_text_only_model() -> an
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
priority: 1,
|
||||
additional_speed_tiers: Vec::new(),
|
||||
service_tiers: Vec::new(),
|
||||
|
||||
@@ -101,6 +101,7 @@ pub fn model_info_from_slug(slug: &str) -> ModelInfo {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ use crate::config_types::ReasoningSummary;
|
||||
use crate::config_types::SERVICE_TIER_DEFAULT_REQUEST_VALUE;
|
||||
use crate::config_types::ServiceTier;
|
||||
use crate::config_types::Verbosity;
|
||||
use crate::protocol::MultiAgentVersion;
|
||||
|
||||
const PERSONALITY_PLACEHOLDER: &str = "{{ personality }}";
|
||||
pub const SPEED_TIER_FAST: &str = "fast";
|
||||
@@ -347,6 +348,12 @@ pub struct ModelInfo {
|
||||
deserialize_with = "deserialize_optional_model_selector"
|
||||
)]
|
||||
pub tool_mode: Option<ToolMode>,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
deserialize_with = "deserialize_optional_model_selector"
|
||||
)]
|
||||
pub multi_agent_version: Option<MultiAgentVersion>,
|
||||
}
|
||||
|
||||
impl ModelInfo {
|
||||
@@ -643,6 +650,7 @@ mod tests {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,6 +909,22 @@ mod tests {
|
||||
assert!(!object.contains_key("tool_mode"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_info_treats_unknown_multi_agent_version_as_omitted() {
|
||||
let mut value =
|
||||
serde_json::to_value(test_model(/*spec*/ None)).expect("serialize test model");
|
||||
let object = value
|
||||
.as_object_mut()
|
||||
.expect("model info should be an object");
|
||||
object.insert(
|
||||
"multi_agent_version".to_string(),
|
||||
serde_json::Value::String("future_multi_agent_version".to_string()),
|
||||
);
|
||||
let model = serde_json::from_value::<ModelInfo>(value).expect("deserialize model info");
|
||||
|
||||
assert_eq!(model.multi_agent_version, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolved_context_window_prefers_context_window() {
|
||||
let model = ModelInfo {
|
||||
|
||||
@@ -2450,6 +2450,18 @@ impl InitialHistory {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_multi_agent_version(&self) -> Option<MultiAgentVersion> {
|
||||
match self {
|
||||
InitialHistory::New | InitialHistory::Cleared => None,
|
||||
InitialHistory::Resumed(resumed) => {
|
||||
multi_agent_version_from_items(&resumed.history, Some(resumed.conversation_id))
|
||||
}
|
||||
InitialHistory::Forked(items) => {
|
||||
multi_agent_version_from_items(items, /*thread_id*/ None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_resumed_session_sources(&self) -> Option<(SessionSource, Option<ThreadSource>)> {
|
||||
let meta = self.get_resumed_session_meta()?;
|
||||
Some((meta.source.clone(), meta.thread_source))
|
||||
@@ -2720,6 +2732,39 @@ impl fmt::Display for InternalSessionSource {
|
||||
}
|
||||
}
|
||||
|
||||
fn multi_agent_version_from_items(
|
||||
items: &[RolloutItem],
|
||||
thread_id: Option<ThreadId>,
|
||||
) -> Option<MultiAgentVersion> {
|
||||
let session_meta_version = items.iter().rev().find_map(|item| match item {
|
||||
RolloutItem::SessionMeta(meta_line)
|
||||
if thread_id.is_none_or(|thread_id| meta_line.meta.id == thread_id) =>
|
||||
{
|
||||
meta_line.meta.multi_agent_version
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
|
||||
session_meta_version.or_else(|| {
|
||||
items.iter().rev().find_map(|item| match item {
|
||||
RolloutItem::TurnContext(turn_context) => turn_context.multi_agent_version,
|
||||
RolloutItem::SessionMeta(_)
|
||||
| RolloutItem::ResponseItem(_)
|
||||
| RolloutItem::Compacted(_)
|
||||
| RolloutItem::EventMsg(_) => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum MultiAgentVersion {
|
||||
Disabled,
|
||||
V1,
|
||||
V2,
|
||||
}
|
||||
|
||||
/// SessionMeta contains session-level data that doesn't correspond to a specific turn.
|
||||
///
|
||||
/// NOTE: There used to be an `instructions` field here, which stored user_instructions, but we
|
||||
@@ -2759,6 +2804,8 @@ pub struct SessionMeta {
|
||||
pub dynamic_tools: Option<Vec<DynamicToolSpec>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub memory_mode: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub multi_agent_version: Option<MultiAgentVersion>,
|
||||
}
|
||||
|
||||
impl Default for SessionMeta {
|
||||
@@ -2780,6 +2827,7 @@ impl Default for SessionMeta {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2859,6 +2907,8 @@ pub struct TurnContextItem {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub collaboration_mode: Option<CollaborationMode>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub multi_agent_version: Option<MultiAgentVersion>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub realtime_active: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub effort: Option<ReasoningEffortConfig>,
|
||||
@@ -5280,6 +5330,39 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_agent_version_uses_newest_present_session_meta_value() -> Result<()> {
|
||||
let thread_id = ThreadId::from_string("67e55044-10b1-426f-9247-bb680e5fe0c8")?;
|
||||
let older_meta = SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
id: thread_id,
|
||||
multi_agent_version: Some(MultiAgentVersion::V2),
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
let newer_meta_without_version = SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
id: thread_id,
|
||||
multi_agent_version: None,
|
||||
..Default::default()
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
multi_agent_version_from_items(
|
||||
&[
|
||||
RolloutItem::SessionMeta(older_meta),
|
||||
RolloutItem::SessionMeta(newer_meta_without_version),
|
||||
],
|
||||
Some(thread_id),
|
||||
),
|
||||
Some(MultiAgentVersion::V2)
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_context_item_serializes_network_when_present() -> Result<()> {
|
||||
let item = TurnContextItem {
|
||||
@@ -5306,6 +5389,7 @@ mod tests {
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: None,
|
||||
summary: ReasoningSummaryConfig::Auto,
|
||||
|
||||
@@ -473,6 +473,7 @@ fn write_rollout(path: &std::path::Path, thread_id: ThreadId, message: &str) ->
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
|
||||
@@ -49,6 +49,7 @@ async fn extract_metadata_from_rollout_uses_session_meta() {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
let session_meta_line = SessionMetaLine {
|
||||
meta: session_meta,
|
||||
@@ -102,9 +103,11 @@ async fn extract_metadata_from_rollout_returns_latest_memory_mode() {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
let polluted_meta = SessionMeta {
|
||||
memory_mode: Some("polluted".to_string()),
|
||||
multi_agent_version: None,
|
||||
..session_meta.clone()
|
||||
};
|
||||
let lines = vec![
|
||||
@@ -363,6 +366,7 @@ fn write_rollout_in_sessions_with_cwd(
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
};
|
||||
let session_meta_line = SessionMetaLine {
|
||||
meta: session_meta,
|
||||
|
||||
@@ -696,6 +696,7 @@ impl RolloutRecorder {
|
||||
Some(dynamic_tools)
|
||||
},
|
||||
memory_mode: (!config.generate_memories()).then_some("disabled".to_string()),
|
||||
multi_agent_version: None,
|
||||
};
|
||||
|
||||
(None, Some(log_file_info), path, Some(session_meta))
|
||||
|
||||
@@ -99,6 +99,7 @@ async fn state_db_init_backfills_before_returning() -> anyhow::Result<()> {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
};
|
||||
@@ -1145,6 +1146,7 @@ async fn resume_candidate_matches_cwd_reads_latest_turn_context() -> std::io::Re
|
||||
model: "test-model".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
|
||||
@@ -41,6 +41,7 @@ fn write_rollout_with_metadata(path: &Path, thread_id: ThreadId) -> std::io::Res
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
|
||||
@@ -158,6 +158,7 @@ fn write_rollout_with_user_message(
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
|
||||
@@ -1274,6 +1274,7 @@ async fn test_updated_at_uses_file_mtime() -> Result<()> {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
|
||||
@@ -336,6 +336,7 @@ mod tests {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
@@ -357,6 +358,7 @@ mod tests {
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -394,6 +396,7 @@ mod tests {
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -428,6 +431,7 @@ mod tests {
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: Some(ReasoningEffort::High),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -458,6 +462,7 @@ mod tests {
|
||||
model: "gpt-5".to_string(),
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
realtime_active: None,
|
||||
effort: Some(ReasoningEffort::High),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
@@ -494,6 +499,7 @@ mod tests {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
}),
|
||||
|
||||
@@ -1332,6 +1332,7 @@ mod tests {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: Some("polluted".to_string()),
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: None,
|
||||
})];
|
||||
@@ -1392,6 +1393,7 @@ mod tests {
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
},
|
||||
git: Some(GitInfo {
|
||||
commit_hash: Some(codex_git_utils::GitSha::new("rollout-sha")),
|
||||
|
||||
@@ -46,6 +46,7 @@ fn model_with_shell_type(shell_type: ConfigShellToolType) -> ModelInfo {
|
||||
supports_search_tool: false,
|
||||
auto_review_model_override: None,
|
||||
tool_mode: None,
|
||||
multi_agent_version: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user