feat(docs): add advanced document tools#278
feat(docs): add advanced document tools#278oskarcode wants to merge 2 commits intogemini-cli-extensions:mainfrom
Conversation
…eateHeaderFooter, addComment)
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands the Google Docs integration by introducing a suite of advanced document manipulation tools. These additions empower users to programmatically insert images and tables, manage headers and footers, and add comments within Google Docs, thereby enhancing automation and content generation workflows. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces four new tools for advanced document manipulation in Google Docs: insertImage, insertTable, createHeaderFooter, and addComment. The implementation is solid, but I've identified a few areas for improvement. Specifically, there's a high-severity issue with image resizing that could cause distortion, some code duplication that affects maintainability, and a minor inconsistency in calculating insertion points. My review includes suggestions to address these points.
| if (widthPt || heightPt) { | ||
| imageRequest.insertInlineImage!.objectSize = { | ||
| width: widthPt | ||
| ? { magnitude: widthPt, unit: 'PT' } | ||
| : { magnitude: 300, unit: 'PT' }, | ||
| height: heightPt | ||
| ? { magnitude: heightPt, unit: 'PT' } | ||
| : { magnitude: 200, unit: 'PT' }, | ||
| }; | ||
| } |
There was a problem hiding this comment.
The current logic for setting the image size can lead to distorted images. If only widthPt is provided, a default heightPt of 200 is used, and vice-versa. This will not preserve the image's aspect ratio. The code should only set the dimensions that are explicitly provided by the user, allowing the Docs API to scale the other dimension to maintain the aspect ratio.
| if (widthPt || heightPt) { | |
| imageRequest.insertInlineImage!.objectSize = { | |
| width: widthPt | |
| ? { magnitude: widthPt, unit: 'PT' } | |
| : { magnitude: 300, unit: 'PT' }, | |
| height: heightPt | |
| ? { magnitude: heightPt, unit: 'PT' } | |
| : { magnitude: 200, unit: 'PT' }, | |
| }; | |
| } | |
| if (widthPt || heightPt) { | |
| const objectSize: docs_v1.Schema$Size = {}; | |
| if (widthPt) { | |
| objectSize.width = { magnitude: widthPt, unit: 'PT' }; | |
| } | |
| if (heightPt) { | |
| objectSize.height = { magnitude: heightPt, unit: 'PT' }; | |
| } | |
| imageRequest.insertInlineImage!.objectSize = objectSize; | |
| } |
| if (!insertIndex) { | ||
| const res = await docs.documents.get({ | ||
| documentId: id, | ||
| fields: 'tabs', | ||
| includeTabsContent: true, | ||
| }); | ||
| const tabs = res.data.tabs || []; | ||
| let content: docs_v1.Schema$StructuralElement[] | undefined; | ||
| if (tabId) { | ||
| const tab = tabs.find((t) => t.tabProperties?.tabId === tabId); | ||
| if (!tab) { | ||
| throw new Error(`Tab with ID ${tabId} not found.`); | ||
| } | ||
| content = tab.documentTab?.body?.content; | ||
| } else if (tabs.length > 0) { | ||
| content = tabs[0].documentTab?.body?.content; | ||
| } | ||
| const lastElement = content?.[content.length - 1]; | ||
| const endIndex = lastElement?.endIndex || 2; | ||
| insertIndex = Math.max(1, endIndex - 1); | ||
| } |
There was a problem hiding this comment.
This logic to determine the insertIndex when it's not provided is duplicated in the insertTable function (lines 778-798). To improve maintainability and avoid future inconsistencies, consider extracting this logic into a private helper method. This will make the code more DRY (Don't Repeat Yourself).
| content = tabs[0].documentTab?.body?.content; | ||
| } | ||
| const lastElement = content?.[content.length - 1]; | ||
| const endIndex = lastElement?.endIndex || 2; |
There was a problem hiding this comment.
There's an inconsistency in how the default endIndex is calculated here compared to the existing writeText function. This line uses || 2, while writeText uses || 1 (see line 330 in the full file). To ensure predictable behavior and maintain consistency, it would be best to align this with the existing pattern.
| const endIndex = lastElement?.endIndex || 2; | |
| const endIndex = lastElement?.endIndex || 1; |
| content = tabs[0].documentTab?.body?.content; | ||
| } | ||
| const lastElement = content?.[content.length - 1]; | ||
| const endIndex = lastElement?.endIndex || 2; |
There was a problem hiding this comment.
Similar to the insertImage function, there's an inconsistency here in calculating the default endIndex (|| 2) compared to the existing writeText function (|| 1 on line 330). Please align this for consistency.
| const endIndex = lastElement?.endIndex || 2; | |
| const endIndex = lastElement?.endIndex || 1; |
| */ | ||
|
|
||
| import { google, docs_v1 } from 'googleapis'; | ||
| import { google, docs_v1, drive_v3 } from 'googleapis'; |
There was a problem hiding this comment.
See #255 we are keeping a strict seperation of concerns for oauth scopes. All of our commenting features (which require the drive scope and api) are in the drive.* namespace. Please move commenting features there.
Summary
Adds four new Google Docs tools for advanced document manipulation.
New Tools
docs.insertImageInserts an image into a Google Doc at a specified position or at the end of the document.
documentId,imageUrl,positionIndex(optional),tabId(optional),widthPt(optional),heightPt(optional)docs.insertTableInserts a table into a Google Doc at a specified position or at the end of the document.
documentId,rows,columns,tabId(optional),positionIndex(optional)docs.createHeaderFooterCreates a header or footer in a Google Doc with optional initial text.
documentId,type("header" or "footer"),text(optional)docs.addCommentAdds a comment to a Google Doc's comment thread.
documentId,contentChanges
insertImage,insertTable,createHeaderFooter,addCommentmethods toDocsService.tsgetDriveClienthelper method for Drive API access (needed byaddComment)index.tsTesting
Tested locally with Google Docs documents.