Fix apps extension: coerce string arguments from inner LLM responses (#8030)
Signed-off-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use crate::agents::extension::PlatformExtensionContext;
|
use crate::agents::extension::PlatformExtensionContext;
|
||||||
use crate::agents::mcp_client::{Error, McpClientTrait};
|
use crate::agents::mcp_client::{Error, McpClientTrait};
|
||||||
|
use crate::agents::reply_parts::coerce_tool_arguments;
|
||||||
use crate::agents::tool_execution::ToolCallContext;
|
use crate::agents::tool_execution::ToolCallContext;
|
||||||
use crate::config::paths::Paths;
|
use crate::config::paths::Paths;
|
||||||
use crate::conversation::message::Message;
|
use crate::conversation::message::Message;
|
||||||
@@ -284,7 +285,11 @@ impl AppsManagerClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extract_tool_response(&response, "create_app_content")
|
extract_tool_response(
|
||||||
|
&response,
|
||||||
|
"create_app_content",
|
||||||
|
&Self::schema::<CreateAppContentResponse>(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn generate_updated_app_content(
|
async fn generate_updated_app_content(
|
||||||
@@ -323,7 +328,11 @@ impl AppsManagerClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extract_tool_response(&response, "update_app_content")
|
extract_tool_response(
|
||||||
|
&response,
|
||||||
|
"update_app_content",
|
||||||
|
&Self::schema::<UpdateAppContentResponse>(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_list_apps(
|
async fn handle_list_apps(
|
||||||
@@ -652,7 +661,10 @@ fn extract_string(args: &JsonObject, key: &str) -> Result<String, String> {
|
|||||||
fn extract_tool_response<T: serde::de::DeserializeOwned>(
|
fn extract_tool_response<T: serde::de::DeserializeOwned>(
|
||||||
response: &Message,
|
response: &Message,
|
||||||
tool_name: &str,
|
tool_name: &str,
|
||||||
|
tool_schema: &JsonObject,
|
||||||
) -> Result<T, String> {
|
) -> Result<T, String> {
|
||||||
|
let schema_value = serde_json::Value::Object(tool_schema.clone());
|
||||||
|
|
||||||
for content in &response.content {
|
for content in &response.content {
|
||||||
if let crate::conversation::message::MessageContent::ToolRequest(tool_req) = content {
|
if let crate::conversation::message::MessageContent::ToolRequest(tool_req) = content {
|
||||||
if let Ok(tool_call) = &tool_req.tool_call {
|
if let Ok(tool_call) = &tool_req.tool_call {
|
||||||
@@ -662,7 +674,10 @@ fn extract_tool_response<T: serde::de::DeserializeOwned>(
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or("Missing tool call parameters")?;
|
.ok_or("Missing tool call parameters")?;
|
||||||
|
|
||||||
return serde_json::from_value(serde_json::Value::Object(params.clone()))
|
let coerced = coerce_tool_arguments(Some(params.clone()), &schema_value)
|
||||||
|
.unwrap_or_else(|| params.clone());
|
||||||
|
|
||||||
|
return serde_json::from_value(serde_json::Value::Object(coerced))
|
||||||
.map_err(|e| format!("Failed to parse tool response: {}", e));
|
.map_err(|e| format!("Failed to parse tool response: {}", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ fn try_coerce_boolean(s: &str) -> Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coerce_tool_arguments(
|
pub(crate) fn coerce_tool_arguments(
|
||||||
arguments: Option<serde_json::Map<String, Value>>,
|
arguments: Option<serde_json::Map<String, Value>>,
|
||||||
tool_schema: &Value,
|
tool_schema: &Value,
|
||||||
) -> Option<serde_json::Map<String, Value>> {
|
) -> Option<serde_json::Map<String, Value>> {
|
||||||
|
|||||||
Reference in New Issue
Block a user