Improve claude tools (#36538)
- Return unified diff from `Edit` tool so model can see the final state - Format on save if enabled - Provide `Write` tool - Disable `MultiEdit` tool - Better prompting Release Notes: - N/A
This commit is contained in:
parent
714c36fa7b
commit
7c7043947b
11 changed files with 606 additions and 302 deletions
|
@ -14,6 +14,7 @@ use serde::de::DeserializeOwned;
|
|||
use serde_json::{json, value::RawValue};
|
||||
use smol::stream::StreamExt;
|
||||
use std::{
|
||||
any::TypeId,
|
||||
cell::RefCell,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
|
@ -87,18 +88,26 @@ impl McpServer {
|
|||
settings.inline_subschemas = true;
|
||||
let mut generator = settings.into_generator();
|
||||
|
||||
let output_schema = generator.root_schema_for::<T::Output>();
|
||||
let unit_schema = generator.root_schema_for::<T::Output>();
|
||||
let input_schema = generator.root_schema_for::<T::Input>();
|
||||
|
||||
let description = input_schema
|
||||
.get("description")
|
||||
.and_then(|desc| desc.as_str())
|
||||
.map(|desc| desc.to_string());
|
||||
debug_assert!(
|
||||
description.is_some(),
|
||||
"Input schema struct must include a doc comment for the tool description"
|
||||
);
|
||||
|
||||
let registered_tool = RegisteredTool {
|
||||
tool: Tool {
|
||||
name: T::NAME.into(),
|
||||
description: Some(tool.description().into()),
|
||||
input_schema: generator.root_schema_for::<T::Input>().into(),
|
||||
output_schema: if output_schema == unit_schema {
|
||||
description,
|
||||
input_schema: input_schema.into(),
|
||||
output_schema: if TypeId::of::<T::Output>() == TypeId::of::<()>() {
|
||||
None
|
||||
} else {
|
||||
Some(output_schema.into())
|
||||
Some(generator.root_schema_for::<T::Output>().into())
|
||||
},
|
||||
annotations: Some(tool.annotations()),
|
||||
},
|
||||
|
@ -399,8 +408,6 @@ pub trait McpServerTool {
|
|||
|
||||
const NAME: &'static str;
|
||||
|
||||
fn description(&self) -> &'static str;
|
||||
|
||||
fn annotations(&self) -> ToolAnnotations {
|
||||
ToolAnnotations {
|
||||
title: None,
|
||||
|
@ -418,6 +425,7 @@ pub trait McpServerTool {
|
|||
) -> impl Future<Output = Result<ToolResponse<Self::Output>>>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ToolResponse<T> {
|
||||
pub content: Vec<ToolResponseContent>,
|
||||
pub structured_content: T,
|
||||
|
|
|
@ -711,6 +711,16 @@ pub enum ToolResponseContent {
|
|||
Resource { resource: ResourceContents },
|
||||
}
|
||||
|
||||
impl ToolResponseContent {
|
||||
pub fn text(&self) -> Option<&str> {
|
||||
if let ToolResponseContent::Text { text } = self {
|
||||
Some(text)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ListToolsResponse {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue