feat: combine create and reply comment tools (#2388)
This commit is contained in:
@@ -545,39 +545,14 @@ impl GoogleDriveRouter {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
let create_comment_tool = Tool::new(
|
let manage_comment_tool = Tool::new(
|
||||||
"create_comment".to_string(),
|
"manage_comment".to_string(),
|
||||||
indoc! {r#"
|
indoc! {r#"
|
||||||
Create a comment for the latest revision of a Google Drive file. The Google Drive API only supports unanchored comments (they don't refer to a specific location in the file).
|
Manage comment for a Google Drive file.
|
||||||
"#}
|
|
||||||
.to_string(),
|
|
||||||
json!({
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"fileId": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Id of the file to comment on.",
|
|
||||||
},
|
|
||||||
"comment": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Content of the comment.",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["fileId", "comment"],
|
|
||||||
}),
|
|
||||||
Some(ToolAnnotations {
|
|
||||||
title: Some("Create file comment".to_string()),
|
|
||||||
read_only_hint: false,
|
|
||||||
destructive_hint: false,
|
|
||||||
idempotent_hint: false,
|
|
||||||
open_world_hint: false,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
let reply_tool = Tool::new(
|
Supports the operations:
|
||||||
"reply".to_string(),
|
- create: Create a comment for the latest revision of a Google Drive file. The Google Drive API only supports unanchored comments (they don't refer to a specific location in the file).
|
||||||
indoc! {r#"
|
- reply: Add a reply to a comment thread, or resolve a comment.
|
||||||
Add a reply to a comment thread, or resolve a comment.
|
|
||||||
"#}
|
"#}
|
||||||
.to_string(),
|
.to_string(),
|
||||||
json!({
|
json!({
|
||||||
@@ -587,23 +562,28 @@ impl GoogleDriveRouter {
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Id of the file.",
|
"description": "Id of the file.",
|
||||||
},
|
},
|
||||||
"commentId": {
|
"operation": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Id of the comment to which you'd like to reply.",
|
"description": "Desired comment management operation.",
|
||||||
|
"enum": ["create", "reply"],
|
||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Content of the reply.",
|
"description": "Content of the comment to create or reply.",
|
||||||
|
},
|
||||||
|
"commentId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Id of the comment to which you'd like to reply. ",
|
||||||
},
|
},
|
||||||
"resolveComment": {
|
"resolveComment": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether to resolve the comment. Defaults to false.",
|
"description": "Whether to resolve the comment in reply. Defaults to false.",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["fileId", "commentId", "content"],
|
"required": ["fileId", "operation", "content"],
|
||||||
}),
|
}),
|
||||||
Some(ToolAnnotations {
|
Some(ToolAnnotations {
|
||||||
title: Some("Reply to a comment".to_string()),
|
title: Some("Manage file comment".to_string()),
|
||||||
read_only_hint: false,
|
read_only_hint: false,
|
||||||
destructive_hint: false,
|
destructive_hint: false,
|
||||||
idempotent_hint: false,
|
idempotent_hint: false,
|
||||||
@@ -729,12 +709,11 @@ impl GoogleDriveRouter {
|
|||||||
5. get_permissions - List the permissions of a file or folder
|
5. get_permissions - List the permissions of a file or folder
|
||||||
6. sharing - Share a file or folder with others
|
6. sharing - Share a file or folder with others
|
||||||
7. get_comments - List a file or folder's comments
|
7. get_comments - List a file or folder's comments
|
||||||
8. create_comment - Create a comment on a file or folder
|
8. manage_comment - Manage comment for a Google Drive file.
|
||||||
9. reply - Reply to a comment on a file or folder
|
9. create_file - Create a new file
|
||||||
10. create_file - Create a new file
|
10. update_file - Update a existing file
|
||||||
11. update_file - Update a existing file
|
11. sheets_tool - Work with Google Sheets data using various operations
|
||||||
12. sheets_tool - Work with Google Sheets data using various operations
|
12. docs_tool - Work with Google Docs data using various operations
|
||||||
13. docs_tool - Work with Google Docs data using various operations
|
|
||||||
|
|
||||||
## Available Tools
|
## Available Tools
|
||||||
|
|
||||||
@@ -794,15 +773,10 @@ impl GoogleDriveRouter {
|
|||||||
### 7. Get Comments Tool
|
### 7. Get Comments Tool
|
||||||
Lists the comments for a Google Workspace file.
|
Lists the comments for a Google Workspace file.
|
||||||
|
|
||||||
### 8. Create Comment Tool
|
### 8. Manage Comment Tool
|
||||||
Create a new comment on a Google Workspace file. The Google Drive
|
Create or reply comment for a Google Drive file.
|
||||||
API only allows "unanchored" comments, which are comments not
|
|
||||||
attache to a specific location or region in the document.
|
|
||||||
|
|
||||||
### 9. Reply Tool
|
### 9. Create File Tool
|
||||||
Reply to an existing comment.
|
|
||||||
|
|
||||||
### 10. Create File Tool
|
|
||||||
Create any kind of file, including Google Workspace files (Docs, Sheets, or Slides) directly in Google Drive.
|
Create any kind of file, including Google Workspace files (Docs, Sheets, or Slides) directly in Google Drive.
|
||||||
- For Google Docs: Converts Markdown text to a Google Document
|
- For Google Docs: Converts Markdown text to a Google Document
|
||||||
- For Google Sheets: Converts CSV text to a Google Spreadsheet
|
- For Google Sheets: Converts CSV text to a Google Spreadsheet
|
||||||
@@ -813,14 +787,14 @@ impl GoogleDriveRouter {
|
|||||||
content provided. To modify specific parts of the document, you must
|
content provided. To modify specific parts of the document, you must
|
||||||
include the changes as part of the entire document.
|
include the changes as part of the entire document.
|
||||||
|
|
||||||
### 11. Update File Tool
|
### 10. Update File Tool
|
||||||
Replace the entire contents of an existing file with new content, including Google Workspace files (Docs, Sheets, or Slides).
|
Replace the entire contents of an existing file with new content, including Google Workspace files (Docs, Sheets, or Slides).
|
||||||
- For Google Docs: Updates with new Markdown text
|
- For Google Docs: Updates with new Markdown text
|
||||||
- For Google Sheets: Updates with new CSV text
|
- For Google Sheets: Updates with new CSV text
|
||||||
- For Google Slides: Updates with a new PowerPoint file (requires a path to the powerpoint file)
|
- For Google Slides: Updates with a new PowerPoint file (requires a path to the powerpoint file)
|
||||||
- Other: No file conversion.
|
- Other: No file conversion.
|
||||||
|
|
||||||
### 12. Sheets Tool
|
### 11. Sheets Tool
|
||||||
Work with Google Sheets data using various operations:
|
Work with Google Sheets data using various operations:
|
||||||
- list_sheets: List all sheets in a spreadsheet
|
- list_sheets: List all sheets in a spreadsheet
|
||||||
- get_columns: Get column headers from a specific sheet
|
- get_columns: Get column headers from a specific sheet
|
||||||
@@ -847,7 +821,7 @@ impl GoogleDriveRouter {
|
|||||||
- title: Title for the new sheet (required for add_sheet operation)
|
- title: Title for the new sheet (required for add_sheet operation)
|
||||||
- valueInputOption: How input data should be interpreted (RAW or USER_ENTERED)
|
- valueInputOption: How input data should be interpreted (RAW or USER_ENTERED)
|
||||||
|
|
||||||
### 13. Docs Tool
|
### 12. Docs Tool
|
||||||
Work with Google Docs data using various operations:
|
Work with Google Docs data using various operations:
|
||||||
- get_document: Get the full document content
|
- get_document: Get the full document content
|
||||||
- insert_text: Insert text at a specific location
|
- insert_text: Insert text at a specific location
|
||||||
@@ -898,8 +872,7 @@ impl GoogleDriveRouter {
|
|||||||
sheets_tool,
|
sheets_tool,
|
||||||
docs_tool,
|
docs_tool,
|
||||||
get_comments_tool,
|
get_comments_tool,
|
||||||
create_comment_tool,
|
manage_comment_tool,
|
||||||
reply_tool,
|
|
||||||
list_drives_tool,
|
list_drives_tool,
|
||||||
get_permissions_tool,
|
get_permissions_tool,
|
||||||
sharing_tool,
|
sharing_tool,
|
||||||
@@ -2177,7 +2150,7 @@ impl GoogleDriveRouter {
|
|||||||
Ok(vec![Content::text(results.join("\n"))])
|
Ok(vec![Content::text(results.join("\n"))])
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_comment(&self, params: Value) -> Result<Vec<Content>, ToolError> {
|
async fn manage_comment(&self, params: Value) -> Result<Vec<Content>, ToolError> {
|
||||||
let file_id =
|
let file_id =
|
||||||
params
|
params
|
||||||
.get("fileId")
|
.get("fileId")
|
||||||
@@ -2185,54 +2158,8 @@ impl GoogleDriveRouter {
|
|||||||
.ok_or(ToolError::InvalidParameters(
|
.ok_or(ToolError::InvalidParameters(
|
||||||
"The fileId param is required".to_string(),
|
"The fileId param is required".to_string(),
|
||||||
))?;
|
))?;
|
||||||
let comment =
|
let operation = params.get("operation").and_then(|q| q.as_str()).ok_or(
|
||||||
params
|
ToolError::InvalidParameters("The operation is required".to_string()),
|
||||||
.get("comment")
|
|
||||||
.and_then(|q| q.as_str())
|
|
||||||
.ok_or(ToolError::InvalidParameters(
|
|
||||||
"The comment param is required".to_string(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let req = Comment {
|
|
||||||
content: Some(comment.to_string()),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let result = self
|
|
||||||
.drive
|
|
||||||
.comments()
|
|
||||||
.create(req, file_id)
|
|
||||||
.clear_scopes() // Scope::MeetReadonly is the default, remove it
|
|
||||||
.add_scope(GOOGLE_DRIVE_SCOPES)
|
|
||||||
.param("fields", "*")
|
|
||||||
// .param("fields", "action, author, content, createdTime, id")
|
|
||||||
.doit()
|
|
||||||
.await;
|
|
||||||
match result {
|
|
||||||
Err(e) => Err(ToolError::ExecutionError(format!(
|
|
||||||
"Failed to add comment for google drive file {}, {}.",
|
|
||||||
file_id, e
|
|
||||||
))),
|
|
||||||
Ok(r) => Ok(vec![Content::text(format!(
|
|
||||||
"Author: {:?} Content: {} Created: {} uri: {} quoted_content: {:?}",
|
|
||||||
r.1.author.unwrap_or_default(),
|
|
||||||
r.1.content.unwrap_or_default(),
|
|
||||||
r.1.created_time.unwrap_or_default(),
|
|
||||||
r.1.id.unwrap_or_default(),
|
|
||||||
r.1.quoted_file_content.unwrap_or_default()
|
|
||||||
))]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn reply(&self, params: Value) -> Result<Vec<Content>, ToolError> {
|
|
||||||
let file_id =
|
|
||||||
params
|
|
||||||
.get("fileId")
|
|
||||||
.and_then(|q| q.as_str())
|
|
||||||
.ok_or(ToolError::InvalidParameters(
|
|
||||||
"The fileId param is required".to_string(),
|
|
||||||
))?;
|
|
||||||
let comment_id = params.get("commentId").and_then(|q| q.as_str()).ok_or(
|
|
||||||
ToolError::InvalidParameters("The commentId param is required".to_string()),
|
|
||||||
)?;
|
)?;
|
||||||
let content =
|
let content =
|
||||||
params
|
params
|
||||||
@@ -2241,41 +2168,86 @@ impl GoogleDriveRouter {
|
|||||||
.ok_or(ToolError::InvalidParameters(
|
.ok_or(ToolError::InvalidParameters(
|
||||||
"The content param is required if the action is create".to_string(),
|
"The content param is required if the action is create".to_string(),
|
||||||
))?;
|
))?;
|
||||||
let resolve_comment = params
|
|
||||||
.get("resolveComment")
|
|
||||||
.and_then(|q| q.as_bool())
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
let mut req = Reply {
|
match operation {
|
||||||
content: Some(content.to_string()),
|
"create" => {
|
||||||
..Default::default()
|
let req = Comment {
|
||||||
};
|
content: Some(content.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let result = self
|
||||||
|
.drive
|
||||||
|
.comments()
|
||||||
|
.create(req, file_id)
|
||||||
|
.clear_scopes() // Scope::MeetReadonly is the default, remove it
|
||||||
|
.add_scope(GOOGLE_DRIVE_SCOPES)
|
||||||
|
.param("fields", "*")
|
||||||
|
// .param("fields", "action, author, content, createdTime, id")
|
||||||
|
.doit()
|
||||||
|
.await;
|
||||||
|
match result {
|
||||||
|
Err(e) => Err(ToolError::ExecutionError(format!(
|
||||||
|
"Failed to add comment for google drive file {}, {}.",
|
||||||
|
file_id, e
|
||||||
|
))),
|
||||||
|
Ok(r) => Ok(vec![Content::text(format!(
|
||||||
|
"Author: {:?} Content: {} Created: {} uri: {} quoted_content: {:?}",
|
||||||
|
r.1.author.unwrap_or_default(),
|
||||||
|
r.1.content.unwrap_or_default(),
|
||||||
|
r.1.created_time.unwrap_or_default(),
|
||||||
|
r.1.id.unwrap_or_default(),
|
||||||
|
r.1.quoted_file_content.unwrap_or_default()
|
||||||
|
))]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"reply" => {
|
||||||
|
let comment_id = params.get("commentId").and_then(|q| q.as_str()).ok_or(
|
||||||
|
ToolError::InvalidParameters(
|
||||||
|
"The commentId param is required for reply".to_string(),
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
if resolve_comment {
|
let resolve_comment = params
|
||||||
req.action = Some("resolve".to_string());
|
.get("resolveComment")
|
||||||
}
|
.and_then(|q| q.as_bool())
|
||||||
let result = self
|
.unwrap_or(false);
|
||||||
.drive
|
|
||||||
.replies()
|
let mut req = Reply {
|
||||||
.create(req, file_id, comment_id)
|
content: Some(content.to_string()),
|
||||||
.clear_scopes() // Scope::MeetReadonly is the default, remove it
|
..Default::default()
|
||||||
.add_scope(GOOGLE_DRIVE_SCOPES)
|
};
|
||||||
.param("fields", "action, author, content, createdTime, id")
|
|
||||||
.doit()
|
if resolve_comment {
|
||||||
.await;
|
req.action = Some("resolve".to_string());
|
||||||
match result {
|
}
|
||||||
Err(e) => Err(ToolError::ExecutionError(format!(
|
let result = self
|
||||||
"Failed to manage reply to comment {} for google drive file {}, {}.",
|
.drive
|
||||||
comment_id, file_id, e
|
.replies()
|
||||||
|
.create(req, file_id, comment_id)
|
||||||
|
.clear_scopes() // Scope::MeetReadonly is the default, remove it
|
||||||
|
.add_scope(GOOGLE_DRIVE_SCOPES)
|
||||||
|
.param("fields", "action, author, content, createdTime, id")
|
||||||
|
.doit()
|
||||||
|
.await;
|
||||||
|
match result {
|
||||||
|
Err(e) => Err(ToolError::ExecutionError(format!(
|
||||||
|
"Failed to manage reply to comment {} for google drive file {}, {}.",
|
||||||
|
comment_id, file_id, e
|
||||||
|
))),
|
||||||
|
Ok(r) => Ok(vec![Content::text(format!(
|
||||||
|
"Action: {} Author: {:?} Content: {} Created: {} uri: {}",
|
||||||
|
r.1.action.unwrap_or_default(),
|
||||||
|
r.1.author.unwrap_or_default(),
|
||||||
|
r.1.content.unwrap_or_default(),
|
||||||
|
r.1.created_time.unwrap_or_default(),
|
||||||
|
r.1.id.unwrap_or_default()
|
||||||
|
))]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(ToolError::InvalidParameters(format!(
|
||||||
|
"Invalid operation: {}. Supported operations are: create, reply",
|
||||||
|
operation
|
||||||
))),
|
))),
|
||||||
Ok(r) => Ok(vec![Content::text(format!(
|
|
||||||
"Action: {} Author: {:?} Content: {} Created: {} uri: {}",
|
|
||||||
r.1.action.unwrap_or_default(),
|
|
||||||
r.1.author.unwrap_or_default(),
|
|
||||||
r.1.content.unwrap_or_default(),
|
|
||||||
r.1.created_time.unwrap_or_default(),
|
|
||||||
r.1.id.unwrap_or_default()
|
|
||||||
))]),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2966,9 +2938,8 @@ impl Router for GoogleDriveRouter {
|
|||||||
"update_file" => this.update_file(arguments).await,
|
"update_file" => this.update_file(arguments).await,
|
||||||
"sheets_tool" => this.sheets_tool(arguments).await,
|
"sheets_tool" => this.sheets_tool(arguments).await,
|
||||||
"docs_tool" => this.docs_tool(arguments).await,
|
"docs_tool" => this.docs_tool(arguments).await,
|
||||||
"create_comment" => this.create_comment(arguments).await,
|
"manage_comment" => this.manage_comment(arguments).await,
|
||||||
"get_comments" => this.get_comments(arguments).await,
|
"get_comments" => this.get_comments(arguments).await,
|
||||||
"reply" => this.reply(arguments).await,
|
|
||||||
"list_drives" => this.list_drives(arguments).await,
|
"list_drives" => this.list_drives(arguments).await,
|
||||||
"get_permissions" => this.get_permissions(arguments).await,
|
"get_permissions" => this.get_permissions(arguments).await,
|
||||||
"sharing" => this.sharing(arguments).await,
|
"sharing" => this.sharing(arguments).await,
|
||||||
|
|||||||
Reference in New Issue
Block a user