mirror of
https://github.com/openai/codex.git
synced 2026-10-31 19:28:49 +00:00
Fix 400 due to missing id parameter
Fixes issue #6700 which describes failures when search is enabled like this: ``` ■ unexpected status 400 Bad Request: { "error": { "message": "Missing required parameter: 'input[25].id'.", "type": "invalid_request_error", "param": "input[25].id", "code": "missing_required_parameter" } } ``` This also fixes another issue I ran into after fixing the above issue: ``` ■ unexpected status 400 Bad Request: { "error": { "message": "Invalid value: 'other'. Supported values are: 'search', 'open_page', and 'find_in_page'.", "type": "invalid_request_error", "param": "input[60].action.type", "code": "invalid_value" } } ```
This commit is contained in:
@@ -8,6 +8,8 @@ use serde::Deserialize;
|
||||
use serde::Deserializer;
|
||||
use serde::Serialize;
|
||||
use serde::ser::Serializer;
|
||||
use serde_json::Value;
|
||||
use serde_json::json;
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::user_input::UserInput;
|
||||
@@ -120,7 +122,7 @@ pub enum ResponseItem {
|
||||
// "action": {"type":"search","query":"weather: San Francisco, CA"}
|
||||
// }
|
||||
WebSearchCall {
|
||||
#[serde(default, skip_serializing)]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(skip)]
|
||||
id: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@@ -211,13 +213,37 @@ pub struct LocalShellExecAction {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema, TS)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum WebSearchAction {
|
||||
Search {
|
||||
query: String,
|
||||
},
|
||||
#[serde(other)]
|
||||
Other,
|
||||
#[serde(transparent)]
|
||||
#[ts(type = "Record<string, unknown>")]
|
||||
pub struct WebSearchAction(Value);
|
||||
|
||||
impl WebSearchAction {
|
||||
pub fn search(query: impl Into<String>) -> Self {
|
||||
Self(json!({
|
||||
"type": "search",
|
||||
"query": query.into(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn as_object(&self) -> Option<&serde_json::Map<String, Value>> {
|
||||
self.0.as_object()
|
||||
}
|
||||
|
||||
pub fn action_type(&self) -> Option<&str> {
|
||||
self.as_object()
|
||||
.and_then(|map| map.get("type"))
|
||||
.and_then(Value::as_str)
|
||||
}
|
||||
|
||||
pub fn is_search(&self) -> bool {
|
||||
matches!(self.action_type(), Some("search"))
|
||||
}
|
||||
|
||||
pub fn query(&self) -> Option<&str> {
|
||||
self.as_object()
|
||||
.and_then(|map| map.get("query"))
|
||||
.and_then(Value::as_str)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema, TS)]
|
||||
@@ -703,4 +729,17 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_search_call_serializes_id() -> Result<()> {
|
||||
let item = ResponseItem::WebSearchCall {
|
||||
id: Some("search-1".into()),
|
||||
status: Some("completed".into()),
|
||||
action: WebSearchAction::search("weather"),
|
||||
};
|
||||
|
||||
let json = serde_json::to_value(&item)?;
|
||||
assert_eq!(json.get("id").and_then(|v| v.as_str()), Some("search-1"));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user