mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: fork pattern v2 (#15771)
Adds this:
```
properties.insert(
"fork_turns".to_string(),
JsonSchema::String {
description: Some(
"Optional MultiAgentV2 fork mode. Use `none`, `all`, or a positive integer string such as `3` to fork only the most recent turns."
.to_string(),
),
},
);
```
---------
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -23,7 +23,7 @@ pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions<'_>) -> ToolSpe
|
||||
let available_models_description = spawn_agent_models_description(options.available_models);
|
||||
let return_value_description =
|
||||
"Returns the spawned agent id plus the user-facing nickname when available.";
|
||||
let properties = spawn_agent_common_properties(&options.agent_type_description);
|
||||
let properties = spawn_agent_common_properties_v1(&options.agent_type_description);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "spawn_agent".to_string(),
|
||||
@@ -45,7 +45,7 @@ pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions<'_>) -> ToolSpe
|
||||
pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions<'_>) -> ToolSpec {
|
||||
let available_models_description = spawn_agent_models_description(options.available_models);
|
||||
let return_value_description = "Returns the canonical task name for the spawned agent, plus the user-facing nickname when available.";
|
||||
let mut properties = spawn_agent_common_properties(&options.agent_type_description);
|
||||
let mut properties = spawn_agent_common_properties_v2(&options.agent_type_description);
|
||||
properties.insert(
|
||||
"task_name".to_string(),
|
||||
JsonSchema::String {
|
||||
@@ -544,7 +544,7 @@ fn create_collab_input_items_schema() -> JsonSchema {
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_agent_common_properties(agent_type_description: &str) -> BTreeMap<String, JsonSchema> {
|
||||
fn spawn_agent_common_properties_v1(agent_type_description: &str) -> BTreeMap<String, JsonSchema> {
|
||||
BTreeMap::from([
|
||||
(
|
||||
"message".to_string(),
|
||||
@@ -592,6 +592,54 @@ fn spawn_agent_common_properties(agent_type_description: &str) -> BTreeMap<Strin
|
||||
])
|
||||
}
|
||||
|
||||
fn spawn_agent_common_properties_v2(agent_type_description: &str) -> BTreeMap<String, JsonSchema> {
|
||||
BTreeMap::from([
|
||||
(
|
||||
"message".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Initial plain-text task for the new agent. Use either message or items."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
("items".to_string(), create_collab_input_items_schema()),
|
||||
(
|
||||
"agent_type".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(agent_type_description.to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"fork_turns".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional MultiAgentV2 fork mode. Use `none`, `all`, or a positive integer string such as `3` to fork only the most recent turns."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"model".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional model override for the new agent. Replaces the inherited model."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"reasoning_effort".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
fn spawn_agent_tool_description(
|
||||
available_models_description: &str,
|
||||
return_value_description: &str,
|
||||
|
||||
@@ -56,6 +56,8 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||
assert!(description.contains("visible display (`visible-model`)"));
|
||||
assert!(!description.contains("hidden display (`hidden-model`)"));
|
||||
assert!(properties.contains_key("task_name"));
|
||||
assert!(properties.contains_key("fork_turns"));
|
||||
assert!(!properties.contains_key("fork_context"));
|
||||
assert_eq!(
|
||||
properties.get("agent_type"),
|
||||
Some(&JsonSchema::String {
|
||||
@@ -69,6 +71,24 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_agent_tool_v1_keeps_legacy_fork_context_field() {
|
||||
let tool = create_spawn_agent_tool_v1(SpawnAgentToolOptions {
|
||||
available_models: &[],
|
||||
agent_type_description: "role help".to_string(),
|
||||
});
|
||||
|
||||
let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = tool else {
|
||||
panic!("spawn_agent should be a function tool");
|
||||
};
|
||||
let JsonSchema::Object { properties, .. } = parameters else {
|
||||
panic!("spawn_agent should use object params");
|
||||
};
|
||||
|
||||
assert!(properties.contains_key("fork_context"));
|
||||
assert!(!properties.contains_key("fork_turns"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_message_tool_requires_items_and_uses_submission_output() {
|
||||
let ToolSpec::Function(ResponsesApiTool {
|
||||
|
||||
Reference in New Issue
Block a user