fix: remove unnecessary fields from tools' inputSchema (#856)
This commit is contained in:
parent
c330fede90
commit
53e4410d99
5 changed files with 114 additions and 10 deletions
|
|
@ -48,6 +48,36 @@ pub fn schema_for_type<T: JsonSchema + std::any::Any>() -> Arc<JsonObject> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Generate a JSON schema for inputSchema (does not need "title" or "description" fields for the top-level object)
|
||||
pub fn schema_for_input<T: JsonSchema + std::any::Any>() -> Arc<JsonObject> {
|
||||
thread_local! {
|
||||
static CACHE_FOR_INPUT: std::sync::RwLock<HashMap<TypeId, Arc<JsonObject>>> = Default::default();
|
||||
};
|
||||
CACHE_FOR_INPUT.with(|cache| {
|
||||
if let Some(schema) = cache
|
||||
.read()
|
||||
.expect("input schema cache lock poisoned")
|
||||
.get(&TypeId::of::<T>())
|
||||
{
|
||||
schema.clone()
|
||||
} else {
|
||||
let mut schema = schema_for_type::<T>().as_ref().clone();
|
||||
|
||||
// Remove unnecessary top-level fields
|
||||
schema.remove("title");
|
||||
schema.remove("description");
|
||||
|
||||
let schema = Arc::new(schema);
|
||||
cache
|
||||
.write()
|
||||
.expect("input schema cache lock poisoned")
|
||||
.insert(TypeId::of::<T>(), schema.clone());
|
||||
|
||||
schema
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: should be updated according to the new specifications
|
||||
/// Schema used when input is empty.
|
||||
pub fn schema_for_empty_input() -> Arc<JsonObject> {
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ pub use tool_traits::{AsyncTool, SyncTool, ToolBase};
|
|||
|
||||
use crate::{
|
||||
handler::server::{
|
||||
tool::{CallToolHandler, DynCallToolHandler, ToolCallContext, schema_for_type},
|
||||
common::schema_for_input,
|
||||
tool::{CallToolHandler, DynCallToolHandler, ToolCallContext},
|
||||
tool_name_validation::validate_and_warn_tool_name,
|
||||
},
|
||||
model::{CallToolResult, Tool, ToolAnnotations},
|
||||
|
|
@ -249,7 +250,7 @@ where
|
|||
attr: Tool::new(
|
||||
name.into(),
|
||||
"",
|
||||
schema_for_type::<crate::model::JsonObject>(),
|
||||
schema_for_input::<crate::model::JsonObject>(),
|
||||
),
|
||||
call: self,
|
||||
_marker: std::marker::PhantomData,
|
||||
|
|
@ -286,7 +287,7 @@ where
|
|||
self
|
||||
}
|
||||
pub fn parameters<T: JsonSchema + 'static>(mut self) -> Self {
|
||||
self.attr.input_schema = schema_for_type::<T>();
|
||||
self.attr.input_schema = schema_for_input::<T>();
|
||||
self
|
||||
}
|
||||
pub fn parameters_value(mut self, schema: serde_json::Value) -> Self {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::{
|
||||
ErrorData,
|
||||
handler::server::{
|
||||
common::schema_for_empty_input,
|
||||
tool::{schema_for_output, schema_for_type},
|
||||
common::{schema_for_empty_input, schema_for_input},
|
||||
tool::schema_for_output,
|
||||
wrapper::{Json, Parameters},
|
||||
},
|
||||
model::{Icon, JsonObject, Meta, ToolAnnotations, ToolExecution},
|
||||
|
|
@ -49,7 +49,7 @@ pub trait ToolBase {
|
|||
/// If the tool does not have any parameters, you should override this methods to return [`None`],
|
||||
/// and when invoked, the parameter will get default values.
|
||||
fn input_schema() -> Option<Arc<JsonObject>> {
|
||||
Some(schema_for_type::<Parameters<Self::Parameter>>())
|
||||
Some(schema_for_input::<Parameters<Self::Parameter>>())
|
||||
}
|
||||
|
||||
/// Json schema for tool output.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use serde::de::DeserializeOwned;
|
|||
|
||||
use super::common::{AsRequestContext, FromContextPart};
|
||||
pub use super::{
|
||||
common::{Extension, RequestId, schema_for_output, schema_for_type},
|
||||
common::{Extension, RequestId, schema_for_input, schema_for_output, schema_for_type},
|
||||
router::tool::{ToolRoute, ToolRouter},
|
||||
};
|
||||
use crate::{
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ impl Tool {
|
|||
/// Set the input schema using a type that implements JsonSchema
|
||||
#[cfg(feature = "server")]
|
||||
pub fn with_input_schema<T: JsonSchema + 'static>(mut self) -> Self {
|
||||
self.input_schema = crate::handler::server::tool::schema_for_type::<T>();
|
||||
self.input_schema = crate::handler::server::tool::schema_for_input::<T>();
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue