agent2: Fix tool schemas for Gemini (#36507)
Release Notes: - N/A --------- Co-authored-by: Agus Zubiaga <agus@zed.dev>
This commit is contained in:
parent
1af47a563f
commit
6b6eb11643
4 changed files with 48 additions and 4 deletions
|
@ -2,6 +2,7 @@ mod agent;
|
|||
mod native_agent_server;
|
||||
mod templates;
|
||||
mod thread;
|
||||
mod tool_schema;
|
||||
mod tools;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1732,8 +1732,8 @@ where
|
|||
fn initial_title(&self, input: Result<Self::Input, serde_json::Value>) -> SharedString;
|
||||
|
||||
/// Returns the JSON schema that describes the tool's input.
|
||||
fn input_schema(&self) -> Schema {
|
||||
schemars::schema_for!(Self::Input)
|
||||
fn input_schema(&self, format: LanguageModelToolSchemaFormat) -> Schema {
|
||||
crate::tool_schema::root_schema_for::<Self::Input>(format)
|
||||
}
|
||||
|
||||
/// Some tools rely on a provider for the underlying billing or other reasons.
|
||||
|
@ -1819,7 +1819,7 @@ where
|
|||
}
|
||||
|
||||
fn input_schema(&self, format: LanguageModelToolSchemaFormat) -> Result<serde_json::Value> {
|
||||
let mut json = serde_json::to_value(self.0.input_schema())?;
|
||||
let mut json = serde_json::to_value(self.0.input_schema(format))?;
|
||||
adapt_schema_to_format(&mut json, format)?;
|
||||
Ok(json)
|
||||
}
|
||||
|
|
43
crates/agent2/src/tool_schema.rs
Normal file
43
crates/agent2/src/tool_schema.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use language_model::LanguageModelToolSchemaFormat;
|
||||
use schemars::{
|
||||
JsonSchema, Schema,
|
||||
generate::SchemaSettings,
|
||||
transform::{Transform, transform_subschemas},
|
||||
};
|
||||
|
||||
pub(crate) fn root_schema_for<T: JsonSchema>(format: LanguageModelToolSchemaFormat) -> Schema {
|
||||
let mut generator = match format {
|
||||
LanguageModelToolSchemaFormat::JsonSchema => SchemaSettings::draft07().into_generator(),
|
||||
LanguageModelToolSchemaFormat::JsonSchemaSubset => SchemaSettings::openapi3()
|
||||
.with(|settings| {
|
||||
settings.meta_schema = None;
|
||||
settings.inline_subschemas = true;
|
||||
})
|
||||
.with_transform(ToJsonSchemaSubsetTransform)
|
||||
.into_generator(),
|
||||
};
|
||||
generator.root_schema_for::<T>()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ToJsonSchemaSubsetTransform;
|
||||
|
||||
impl Transform for ToJsonSchemaSubsetTransform {
|
||||
fn transform(&mut self, schema: &mut Schema) {
|
||||
// Ensure that the type field is not an array, this happens when we use
|
||||
// Option<T>, the type will be [T, "null"].
|
||||
if let Some(type_field) = schema.get_mut("type")
|
||||
&& let Some(types) = type_field.as_array()
|
||||
&& let Some(first_type) = types.first()
|
||||
{
|
||||
*type_field = first_type.clone();
|
||||
}
|
||||
|
||||
// oneOf is not supported, use anyOf instead
|
||||
if let Some(one_of) = schema.remove("oneOf") {
|
||||
schema.insert("anyOf".to_string(), one_of);
|
||||
}
|
||||
|
||||
transform_subschemas(self, schema);
|
||||
}
|
||||
}
|
|
@ -266,7 +266,7 @@ pub struct CitationMetadata {
|
|||
pub struct PromptFeedback {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub block_reason: Option<String>,
|
||||
pub safety_ratings: Vec<SafetyRating>,
|
||||
pub safety_ratings: Option<Vec<SafetyRating>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub block_reason_message: Option<String>,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue