mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[tool search] support namespaced deferred dynamic tools (#18413)
Deferred dynamic tools need to round-trip a namespace so a tool returned by `tool_search` can be called through the same registry key that core uses for dispatch. This change adds namespace support for dynamic tool specs/calls, persists it through app-server thread state, and routes dynamic tool calls by full `ToolName` while still sending the app the leaf tool name. Deferred dynamic tools must provide a namespace; non-deferred dynamic tools may remain top-level. It also introduces `LoadableToolSpec` as the shared function-or-namespace Responses shape used by both `tool_search` output and dynamic tool registration, so dynamic tools use the same wrapping logic in both paths. Validation: - `cargo test -p codex-tools` - `cargo test -p codex-core tool_search` --------- Co-authored-by: Sayan Sisodiya <sayan@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
1dcea729d3
commit
dc1a8f2190
@@ -470,6 +470,7 @@ impl ThreadHistoryBuilder {
|
||||
) {
|
||||
let item = ThreadItem::DynamicToolCall {
|
||||
id: payload.call_id.clone(),
|
||||
namespace: payload.namespace.clone(),
|
||||
tool: payload.tool.clone(),
|
||||
arguments: payload.arguments.clone(),
|
||||
status: DynamicToolCallStatus::InProgress,
|
||||
@@ -493,6 +494,7 @@ impl ThreadHistoryBuilder {
|
||||
let duration_ms = i64::try_from(payload.duration.as_millis()).ok();
|
||||
let item = ThreadItem::DynamicToolCall {
|
||||
id: payload.call_id.clone(),
|
||||
namespace: payload.namespace.clone(),
|
||||
tool: payload.tool.clone(),
|
||||
arguments: payload.arguments.clone(),
|
||||
status,
|
||||
@@ -1975,6 +1977,7 @@ mod tests {
|
||||
codex_protocol::dynamic_tools::DynamicToolCallRequest {
|
||||
call_id: "dyn-1".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
namespace: Some("codex_app".into()),
|
||||
tool: "lookup_ticket".into(),
|
||||
arguments: serde_json::json!({"id":"ABC-123"}),
|
||||
},
|
||||
@@ -1982,6 +1985,7 @@ mod tests {
|
||||
EventMsg::DynamicToolCallResponse(DynamicToolCallResponseEvent {
|
||||
call_id: "dyn-1".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
namespace: Some("codex_app".into()),
|
||||
tool: "lookup_ticket".into(),
|
||||
arguments: serde_json::json!({"id":"ABC-123"}),
|
||||
content_items: vec![CoreDynamicToolCallOutputContentItem::InputText {
|
||||
@@ -2004,6 +2008,7 @@ mod tests {
|
||||
turns[0].items[1],
|
||||
ThreadItem::DynamicToolCall {
|
||||
id: "dyn-1".into(),
|
||||
namespace: Some("codex_app".into()),
|
||||
tool: "lookup_ticket".into(),
|
||||
arguments: serde_json::json!({"id":"ABC-123"}),
|
||||
status: DynamicToolCallStatus::Completed,
|
||||
|
||||
@@ -613,6 +613,8 @@ pub struct ToolsV2 {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct DynamicToolSpec {
|
||||
#[ts(optional)]
|
||||
pub namespace: Option<String>,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub input_schema: JsonValue,
|
||||
@@ -623,6 +625,7 @@ pub struct DynamicToolSpec {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct DynamicToolSpecDe {
|
||||
namespace: Option<String>,
|
||||
name: String,
|
||||
description: String,
|
||||
input_schema: JsonValue,
|
||||
@@ -636,6 +639,7 @@ impl<'de> Deserialize<'de> for DynamicToolSpec {
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let DynamicToolSpecDe {
|
||||
namespace,
|
||||
name,
|
||||
description,
|
||||
input_schema,
|
||||
@@ -644,6 +648,7 @@ impl<'de> Deserialize<'de> for DynamicToolSpec {
|
||||
} = DynamicToolSpecDe::deserialize(deserializer)?;
|
||||
|
||||
Ok(Self {
|
||||
namespace,
|
||||
name,
|
||||
description,
|
||||
input_schema,
|
||||
@@ -4887,6 +4892,7 @@ pub enum ThreadItem {
|
||||
#[ts(rename_all = "camelCase")]
|
||||
DynamicToolCall {
|
||||
id: String,
|
||||
namespace: Option<String>,
|
||||
tool: String,
|
||||
arguments: JsonValue,
|
||||
status: DynamicToolCallStatus,
|
||||
@@ -6650,6 +6656,7 @@ pub struct DynamicToolCallParams {
|
||||
pub thread_id: String,
|
||||
pub turn_id: String,
|
||||
pub call_id: String,
|
||||
pub namespace: Option<String>,
|
||||
pub tool: String,
|
||||
pub arguments: JsonValue,
|
||||
}
|
||||
@@ -9303,6 +9310,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
actual,
|
||||
DynamicToolSpec {
|
||||
namespace: None,
|
||||
name: "lookup_ticket".to_string(),
|
||||
description: "Fetch a ticket".to_string(),
|
||||
input_schema: json!({
|
||||
|
||||
Reference in New Issue
Block a user