Skip to content

[ACTION] Update Google Gemini actions #16358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2025
Merged

Conversation

jcortes
Copy link
Collaborator

@jcortes jcortes commented Apr 17, 2025

WHY

Resolves #16262

Summary by CodeRabbit

  • New Features
    • Added support for conversation history and safety settings in content generation actions, allowing for improved context and control.
    • Introduced a unified media input property supporting images, audio, and video for content generation.
    • Added a new action to generate text embeddings using Google Gemini.
  • Enhancements
    • Improved input validation and configurability for conversation history and content safety filtering.
    • Dynamically detect media file types for content generation.
  • Other
    • Updated package version to 0.3.0.

@jcortes jcortes self-assigned this Apr 17, 2025
Copy link

vercel bot commented Apr 17, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) Visit Preview Apr 22, 2025 2:24am
pipedream-docs ⬜️ Ignored (Inspect) Apr 22, 2025 2:24am
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Apr 22, 2025 2:24am

Copy link
Contributor

coderabbitai bot commented Apr 17, 2025

Walkthrough

This update introduces significant enhancements and refactoring to the Google Gemini integration. It adds a new "Generate Embeddings" action using the Gemini embedding API, introduces robust handling and validation for conversation history and safety settings in content generation actions, and unifies media input handling for multimodal actions. Constants for harm categories, block thresholds, and task types are defined for improved input validation and configuration. The app's methods and property definitions are updated to support these features, and the package version is incremented to 0.3.0.

Changes

File(s) Change Summary
components/google_gemini/actions/common/generate-content.mjs Added props and methods for validating and formatting conversation history and safety settings.
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs Refactored to use a unified mediaPaths prop for media input, dynamic MIME type detection, incorporated history and safety settings, and updated payload construction.
components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs Updated to include formatted conversation history and safety settings in content generation requests; removed explicit text/responseFormat props.
components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs Added a new action for generating embeddings from text, with model and task type selection.
components/google_gemini/common/constants.mjs Introduced constants for harm categories, block thresholds, and task types; extended model methods.
components/google_gemini/google_gemini.app.mjs Removed mimeType prop, generalized imagePaths to mediaPaths, and added the embedContent method.
components/google_gemini/package.json Bumped package version from 0.2.2 to 0.3.0.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Action
    participant App
    participant GeminiAPI

    User->>Action: Provide text, (mediaPaths), history, safetySettings
    Action->>Action: Validate and format history & safetySettings
    Action->>App: Call generateContent or embedContent with formatted data
    App->>GeminiAPI: POST request with payload
    GeminiAPI-->>App: Return response
    App-->>Action: Pass API response
    Action-->>User: Output result
Loading

Assessment against linked issues

Objective Addressed Explanation
Update Google Gemini actions to use up-to-date models and endpoints (dynamic listing not implemented) (#16262) Models are filtered for embedding support, but dynamic model listing is not confirmed implemented.
Chat action: Support conversation history, safety settings, and correct API mapping for props (#16262)
Embeddings action: Add embedding generation with task type and correct API mapping (#16262)
Multimodal/vision action: Unify media input handling, support images/videos, and output schema (#16262)
General improvements: Remove deprecated props, add robust validation, update constants (#16262)

Suggested labels

ai-assisted

Suggested reviewers

  • lcaresia

Poem

In Gemini’s warren, new features bloom,
Embeddings and history now banish the gloom.
Safety and context, all neat and precise,
Media hops in, with carrots and spice!
Constants and methods, all tidy and bright,
This bunny’s code garden is hopping tonight! 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/google_gemini/actions/common/generate-content.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

  • 3 others

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9932d26 and 3dd50d7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • components/google_gemini/package.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • components/google_gemini/google_gemini.app.mjs
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
  • components/google_gemini/common/constants.mjs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (7)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4)

12-12: Version increment is appropriate

Incrementing the version from 0.1.2 to 0.2.0 appropriately reflects the significant changes to the component's interface (replacing imagePaths with mediaPaths and adding conversation history support).


16-21: Good API improvement: unified media handling

Replacing the image-specific prop with a more generic mediaPaths allows the component to handle multiple media types uniformly, aligning with Gemini's multimodal capabilities.


57-63: Improved validation error messages

The validation error messages now correctly refer to "media paths" instead of "image paths", which aligns with the updated prop name and supports multiple media types.


82-84: Good integration of safety settings

The implementation now properly integrates safety settings using the common formatting method. This provides more control over content filtering and aligns with Gemini API capabilities.

components/google_gemini/actions/common/generate-content.mjs (3)

24-29: Good: Added text prop to common module

Moving the text prop to the common module promotes code reuse across different content generation actions.


36-47: Well-documented conversation and safety props

The history and safetySettings props have clear descriptions with examples, helping users understand the expected format for these complex inputs.


50-89: Robust history validation with good error messages

The formatHistoryToContent method thoroughly validates conversation history items and provides specific error messages for different validation failures. The handling of both string and object inputs adds flexibility.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (1)

57-63: Error message still references “Image/Video”

The validation now targets the generic mediaPaths prop, but the exception text still says “Image/Video paths”.

-throw new ConfigurationError("Image/Video paths must be an array.");
+throw new ConfigurationError("Media paths must be an array.");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 44e0bd9 and 8864fc1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (1 hunks)
  • components/hubspot/common/constants.mjs (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (16)
components/hubspot/common/constants.mjs (2)

242-243: Updated exports to include new constants

The exports have been appropriately updated to include the new HARM_CATEGORIES and BLOCK_THRESHOLDS constants.


217-222:

❓ Verification inconclusive

New block threshold constants added to HubSpot component

The BLOCK_THRESHOLDS constant defines content moderation thresholds. Similar to HARM_CATEGORIES, placing these in the HubSpot component is unusual if they're primarily for Google Gemini functionality.


🏁 Script executed:

#!/bin/bash
# Check if these constants are used elsewhere in the HubSpot component
rg "BLOCK_THRESHOLDS" --type js components/hubspot/

# Check if the same constants exist in Google Gemini component
rg "BLOCK_NONE" --type js components/google_gemini/

Length of output: 103


Confirm placement of BLOCK_THRESHOLDS constants

I wasn’t able to find any references to BLOCK_THRESHOLDS in the HubSpot component nor definitions of these same values in the Google Gemini component. Please verify whether these thresholds are actually consumed by HubSpot logic or if they belong in the Google Gemini module instead.

• components/hubspot/common/constants.mjs (lines 217–222): check if BLOCK_THRESHOLDS is ever imported or used
• components/google_gemini/: if these values power Gemini’s moderation, move them into components/google_gemini/common/constants.mjs and update imports accordingly

components/google_gemini/package.json (1)

3-3: Version bump from 0.2.2 to 0.3.0

The version has been increased from 0.2.2 to 0.3.0, which follows semantic versioning principles and correctly indicates the addition of new features (embedding generation functionality) while maintaining backward compatibility.

components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (3)

4-9: Well-structured action metadata for the new embeddings feature

The action metadata is clear and includes a helpful link to the official documentation, which is good practice.


10-43: Comprehensive props configuration for embedding generation

The props are well-defined with appropriate descriptions. The model selector efficiently filters out discontinued/deprecated models and only includes those supporting embedding generation.


44-61: Clean implementation of the embedding generation run method

The run method correctly uses the app's embedContent method and returns a helpful summary message along with the full response.

components/google_gemini/google_gemini.app.mjs (2)

13-16: Generalized media input handling

The property has been updated from likely "imagePaths" to "mediaPaths" with an expanded description to support multiple media types (images, audio, video), which increases the flexibility of the component.


106-116:

✅ Verification successful

New embedContent method for embedding generation

This method follows the same pattern as the existing generateContent method, appropriately constructing the request path based on the model and making a POST request to the embedding endpoint. The implementation is clean and consistent with existing code patterns.


🏁 Script executed:

#!/bin/bash
# Check if MODEL_METHODS.EMBED_CONTENT is defined in the constants file
rg "EMBED_CONTENT" --type js components/google_gemini/common/constants.mjs

Length of output: 107


EmbedContent implementation is correct and ready to merge

Confirmed that MODEL_METHODS.EMBED_CONTENT is defined as "embedContent" in components/google_gemini/common/constants.mjs. The new embedContent method follows the established generateContent pattern and correctly constructs the request path.

components/google_gemini/common/constants.mjs (1)

9-22: Enumerations improve safety‑filter ergonomics – looks good

Introducing HARM_CATEGORIES and BLOCK_THRESHOLDS as named exports makes downstream validation much clearer and less error‑prone than magic strings.
No issues spotted here.

components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2)

27-37: Conversation history prepending is correct

Prepending formatHistoryToContent(history) before the current user message matches Gemini’s expected chronological order (oldest → newest). Nice job keeping the API payload consistent.


46-57: responseFormat is checked but never forwarded – clarify intent

responseFormat gates the inclusion of generationConfig, yet the resulting object only sets responseMimeType, not the requested responseFormat.
If callers expect the field to affect the output (e.g. "JSON" | "TEXT"), the current implementation has no effect.

Please confirm whether:

  1. responseFormat is obsolete (remove the prop and the conditional), or
  2. Gemini expects a different field name (e.g. response_format) that should be forwarded.

This mismatch could lead to silent degradations in existing workflows.

components/google_gemini/actions/common/generate-content.mjs (5)

3-7: Necessary imports added for validation and safety configurations.

The imports for ConfigurationError and the safety-related constants are appropriate for supporting the new validation functionality.


28-39: Properties restructured correctly.

The properties for text and responseFormat have been properly maintained and structured in a consistent format.


40-51: Well-documented conversation history and safety settings properties.

The new properties for conversation history and safety settings include clear descriptions and examples, which will help users understand the expected format.


54-83: Robust history formatting method with proper validation.

The formatHistoryToContent method appropriately:

  1. Handles empty/undefined input
  2. Validates JSON format
  3. Checks for required fields and valid role values
  4. Transforms data to the API-expected format

This implementation helps prevent runtime errors when users provide invalid history data.


84-115: Comprehensive safety settings validation and formatting.

The formatSafetySettings method includes thorough validation:

  1. Checks for properly formatted JSON
  2. Validates required fields existence
  3. Ensures categories and thresholds match allowed values from constants
  4. Transforms input to the format expected by the Gemini API

The detailed error messages will assist users in providing valid configuration.

@jcortes jcortes force-pushed the google-gemini-update-actions branch 2 times, most recently from 27b098e to 984351a Compare April 17, 2025 21:39
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (3)

2-2: Verify the mime dependency is declared in package.json

The code now imports the mime package, but there's no indication that it's been added as a dependency in the component's manifest or package.json.

#!/bin/bash
# Check if mime is declared in the component's package.json
grep -r "mime" --include="package.json" components/google_gemini/

24-38: 🛠️ Refactor suggestion

Handle unknown MIME types and add error handling

The fileToGenerativePart method has been updated to infer MIME types dynamically, but it still lacks handling for:

  1. Unknown file extensions where mime.getType() returns null
  2. Potential errors when reading files
fileToGenerativePart(filePath) {
  if (!filePath) {
    return;
  }

-  const mimeType = mime.getType(filePath);
+  const mimeType = mime.getType(filePath) ?? "application/octet-stream";
+  
+  try {
+    return {
+      inline_data: {
+        mime_type: mimeType,
+        data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
+      },
+    };
+  } catch (error) {
+    console.error(`Failed to read file: ${filePath}`, error);
+    return;
+  }
-  return {
-    inline_data: {
-      mime_type: mimeType,
-      data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
-    },
-  };
}

65-75: 🛠️ Refactor suggestion

Filter out undefined parts to prevent API errors

When mapping media paths to generative parts, failures in fileToGenerativePart could result in undefined elements in the parts array, which would cause the Gemini API to reject the request.

const contents = [
  ...this.formatHistoryToContent(history),
  {
    parts: [
-      ...mediaPaths.map((path) => this.fileToGenerativePart(path)),
+      ...mediaPaths
+        .map((path) => this.fileToGenerativePart(path))
+        .filter(Boolean),
      {
        text,
      },
    ],
  },
];
🧹 Nitpick comments (1)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (1)

57-63: Update error message to reflect broader media support

The error message still refers specifically to "Image/Video paths" even though the property now supports other media types (as indicated by the rename to mediaPaths).

if (!Array.isArray(mediaPaths)) {
-  throw new ConfigurationError("Image/Video paths must be an array.");
+  throw new ConfigurationError("Media paths must be an array.");
}

if (!mediaPaths.length) {
-  throw new ConfigurationError("At least one media path must be provided.");
+  throw new ConfigurationError("At least one media file path must be provided.");
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8864fc1 and 27b098e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • components/google_gemini/package.json
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs
  • components/google_gemini/google_gemini.app.mjs
  • components/google_gemini/common/constants.mjs
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
  • components/google_gemini/actions/common/generate-content.mjs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (3)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (3)

12-12: LGTM: Version incremented appropriately

The version has been incremented from 0.1.2 to 0.2.0, which is appropriate given the non-breaking changes to the API.


16-21: LGTM: Props refactored to use unified mediaPaths property

Good refactoring to use a single mediaPaths property instead of separate imagePaths, aligning with the updated app property definition.


81-82: LGTM: Proper integration of new safety settings and conversation history

Good implementation of the new content structure and safety settings, utilizing the helper methods from the common module.

@jcortes jcortes force-pushed the google-gemini-update-actions branch from 984351a to e81e448 Compare April 17, 2025 21:50
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
components/google_gemini/actions/common/generate-content.mjs (1)

42-47: Update safety settings description to include HARM_BLOCK_THRESHOLD_UNSPECIFIED

The safety settings property description should include the "HARM_BLOCK_THRESHOLD_UNSPECIFIED" threshold option which was mentioned in the previous review comments.

-      description: "Configure content filtering for different harm categories. Each item must be a valid JSON string with `category` (one of: `HARASSMENT`, `HATE_SPEECH`, `SEXUALLY_EXPLICIT`, `DANGEROUS`, `CIVIC`) and `threshold` (one of: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`, `BLOCK_LOW_AND_ABOVE`). Example: `{\"category\": \"HARASSMENT\", \"threshold\": \"BLOCK_MEDIUM_AND_ABOVE\"}`",
+      description: "Configure content filtering for different harm categories. Each item must be a valid JSON string with `category` (one of: `HARASSMENT`, `HATE_SPEECH`, `SEXUALLY_EXPLICIT`, `DANGEROUS`, `CIVIC`) and `threshold` (one of: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`, `BLOCK_LOW_AND_ABOVE`, `HARM_BLOCK_THRESHOLD_UNSPECIFIED`). Example: `{\"category\": \"HARASSMENT\", \"threshold\": \"BLOCK_MEDIUM_AND_ABOVE\"}`",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 984351a and e81e448.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • components/google_gemini/package.json
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
  • components/google_gemini/google_gemini.app.mjs
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs
  • components/google_gemini/common/constants.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (6)
components/google_gemini/actions/common/generate-content.mjs (6)

3-3: Good addition of ConfigurationError import

Adding the ConfigurationError import from the platform is appropriate for the validation logic in the new methods.


24-29: LGTM: Text property definition

The text property is properly defined with appropriate propDefinition referencing the app.


30-35: LGTM: Response format property definition

The responseFormat property is properly defined with appropriate propDefinition referencing the app.


36-41: LGTM: Well-structured history property with clear documentation

The history property is well defined with appropriate type, label, and descriptive documentation that includes example format.


50-79: LGTM: Robust history formatting method with appropriate validation

The formatHistoryToContent method is well implemented with:

  • Proper handling of empty/null history
  • Strong JSON validation with clear error messages
  • Validation of required fields (text and role)
  • Validation of role values (user or model)
  • Correct transformation to the expected structure with parts and role

This provides robust validation for user input and appropriate error feedback.


80-111: LGTM: Well-structured safety settings formatting with thorough validation

The formatSafetySettings method is well implemented with:

  • Proper handling of empty/null settings
  • Strong JSON validation with clear error messages
  • Validation of required fields (category and threshold)
  • Validation against predefined constants with descriptive error messages
  • Appropriate transformation to the expected structure

This provides robust validation for user input and appropriate error feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4)

2-2: Ensure the mime dependency is added to package.json

The action now imports the mime package, but it's important to verify that this dependency is also listed in the component's package.json to avoid runtime "module not found" errors.

#!/bin/bash
# Check if mime is listed in package.json dependencies
grep -r "\"mime\":" components/google_gemini/package.json || echo "mime dependency not found"

30-31: ⚠️ Potential issue

Handle unknown MIME types to avoid API errors

mime.getType(filePath) may return null for uncommon file extensions. Passing null to the API as a MIME type would result in an invalid request.

-const mimeType = mime.getType(filePath);
+const mimeType = mime.getType(filePath) ?? "application/octet-stream";

69-69: ⚠️ Potential issue

Filter out failed conversions to prevent undefined parts

If fileToGenerativePart returns undefined (e.g., for unreadable files), the parts array will contain undefined elements, causing Gemini to reject the request.

-...mediaPaths.map((path) => this.fileToGenerativePart(path)),
+...mediaPaths
+  .map((path) => this.fileToGenerativePart(path))
+  .filter(Boolean),

25-38: 🛠️ Refactor suggestion

Add error handling for file reading operations

The current implementation doesn't handle potential errors when reading files, which could lead to unhandled exceptions if a file is missing or not readable.

fileToGenerativePart(filePath) {
  if (!filePath) {
    return;
  }

  const mimeType = mime.getType(filePath) ?? "application/octet-stream";
  
+  try {
+    const fileData = fs.readFileSync(filePath);
+    return {
+      inline_data: {
+        mime_type: mimeType,
+        data: Buffer.from(fileData).toString("base64"),
+      },
+    };
+  } catch (error) {
+    console.error(`Error reading file ${filePath}: ${error.message}`);
+    return undefined;
+  }
-  return {
-    inline_data: {
-      mime_type: mimeType,
-      data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
-    },
-  };
},
🧹 Nitpick comments (2)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (2)

57-59: Update error message to match expanded media types

The error message still references "Image/Video paths" but according to the AI summary, mediaPaths now supports images, audio, and videos.

-throw new ConfigurationError("Image/Video paths must be an array.");
+throw new ConfigurationError("Media paths (images, audio, or videos) must be an array.");

61-63: Update error message to match expanded media types

Similar to the previous comment, update this error message to reflect the broader range of supported media types.

-throw new ConfigurationError("At least one media path must be provided.");
+throw new ConfigurationError("At least one media file path (image, audio, or video) must be provided.");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e81e448 and 042c460.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • components/google_gemini/package.json
  • components/google_gemini/google_gemini.app.mjs
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
  • components/google_gemini/common/constants.mjs
  • components/google_gemini/actions/common/generate-content.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (4)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4)

12-12: Version increment is appropriate

The version bump from 0.1.2 to 0.2.0 correctly follows semantic versioning since you're adding new functionality without breaking backward compatibility.


65-75: Content generation structure looks good

The updated content generation structure properly incorporates conversation history and combines multiple media inputs with text into a single request, which aligns with the Gemini API's capabilities for multimodal inputs.


81-82: Safety settings integration is well implemented

The addition of safety settings through the common formatSafetySettings method is a good improvement that allows for better control over content generation safety parameters.


16-21: Streamlined media input handling

Consolidating different media types into a single mediaPaths property simplifies the interface and makes the component more flexible.

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a couple suggested improvements.

@jcortes jcortes force-pushed the google-gemini-update-actions branch from ff53301 to c04c3f6 Compare April 18, 2025 17:14
@jcortes jcortes requested a review from michelle0927 April 18, 2025 17:15
@jcortes jcortes force-pushed the google-gemini-update-actions branch from c04c3f6 to b6df669 Compare April 18, 2025 17:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4)

2-2: Remember to declare the new mime dependency

The action now imports mime, but ensure mime is listed in package.json or the component's manifest to avoid runtime "module not found" errors.


30-36: 🛠️ Refactor suggestion

Handle unknown MIME types to avoid 4xx responses

mime.getType(filePath) may return null for uncommon extensions, which would lead to an invalid request.

-const mimeType = mime.getType(filePath);
+const mimeType = mime.getType(filePath) ?? "application/octet-stream";

Also consider adding error handling for file reading operations:

-data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
+try {
+  data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
+} catch (error) {
+  throw new ConfigurationError(`Failed to read file at ${filePath}: ${error.message}`);
+}

69-69: 🛠️ Refactor suggestion

Filter out failed conversions to prevent undefined parts

If fileToGenerativePart returns undefined (e.g., unreadable file), the parts array will contain undefined elements and Gemini will reject the request.

-...mediaPaths.map((path) => this.fileToGenerativePart(path)),
+...mediaPaths
+  .map((path) => this.fileToGenerativePart(path))
+  .filter(Boolean),

70-72: 🛠️ Refactor suggestion

Ensure text value is properly defined

The code references text in the parts array, but there's no validation to ensure it's properly defined.

{
-  text,
+  text: text ?? "", // Ensure text has a default value if not defined
},
🧹 Nitpick comments (1)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (1)

57-59: Update error message to match prop name

The error message refers to "Image/Video paths" but the prop is named "mediaPaths", which could include other media types.

-throw new ConfigurationError("Image/Video paths must be an array.");
+throw new ConfigurationError("Media paths must be an array.");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff53301 and b6df669.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • components/google_gemini/package.json
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs
  • components/google_gemini/google_gemini.app.mjs
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
  • components/google_gemini/common/constants.mjs
  • components/google_gemini/actions/common/generate-content.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (3)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (3)

16-21: LGTM: Improved media handling with unified prop

The change from imagePaths to mediaPaths aligns with the app-level changes and improves the component's ability to handle different types of media uniformly.


65-75: LGTM: Enhanced content structure with history support

The new content structure that incorporates conversation history through formatHistoryToContent is a good improvement that enables more sophisticated interactions with the Gemini API.


82-82: LGTM: Added safety settings

Including formatted safety settings in the API request is a good enhancement for controlling the content generation process.

michelle0927
michelle0927 previously approved these changes Apr 18, 2025
Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (8)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (5)

2-2: ⚠️ Potential issue

Remember to declare the new mime dependency.

This file imports mime, but it's not clear if it has been added to package.json as a dependency. Without this, the code will fail at runtime with "module not found" errors.


30-31: 🛠️ Refactor suggestion

Handle unknown MIME types to avoid API errors.

mime.getType(filePath) may return null for uncommon file extensions, causing the API to reject the request with a 400 error.

-const mimeType = mime.getType(filePath);
+const mimeType = mime.getType(filePath) ?? "application/octet-stream";

69-69: ⚠️ Potential issue

Filter out failed conversions to prevent undefined parts.

If fileToGenerativePart returns undefined (e.g., unreadable file), the parts array will contain undefined elements and Gemini will reject the request.

-...mediaPaths.map((path) => this.fileToGenerativePart(path)),
+...mediaPaths
+  .map((path) => this.fileToGenerativePart(path))
+  .filter(Boolean),

70-72: 🛠️ Refactor suggestion

Ensure text value is properly defined.

The code references text in the parts array, but there's no validation to ensure it's properly defined.

{
-  text,
+  text: text ?? "", // Ensure text has a default value if not defined
},

35-35: 🛠️ Refactor suggestion

Add error handling for file reading operations.

The current implementation doesn't handle errors that might occur when reading files (e.g., file not found, permission issues).

-      data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
+      try {
+        data: Buffer.from(fs.readFileSync(filePath)).toString("base64"),
+      } catch (error) {
+        throw new ConfigurationError(`Failed to read file at path: ${filePath}. Error: ${error.message}`);
+      }
components/google_gemini/actions/common/generate-content.mjs (3)

118-121: Address inconsistency in safety settings category/threshold handling.

There's an inconsistency in how categories and thresholds are handled: the category is transformed by looking up its value in the constants object, while the threshold is used directly from the input.

For consistency, both should use the same approach. Either:

        return {
          category,
-         threshold: setting.threshold,
+         threshold: constants.BLOCK_THRESHOLDS[setting.threshold],
        };

Or:

        return {
-         category,
+         category: setting.category,
          threshold: setting.threshold,
        };

63-71: 🛠️ Refactor suggestion

Process objects directly in history array.

The current implementation assumes every history item needs to be parsed from JSON, but we should allow for the case where an item in the array is already an object.

      return history.map((itemStr) => {
-        let item = itemStr;
-        if (typeof item === "string") {
-          try {
-            item = JSON.parse(itemStr);
-          } catch (e) {
-            throw new ConfigurationError(`Invalid JSON in history item: ${itemStr}`);
-          }
+        let item = itemStr;
+        if (typeof item === "string") {
+          try {
+            item = JSON.parse(itemStr);
+          } catch (e) {
+            throw new ConfigurationError(`Invalid JSON in history item: ${itemStr}`);
+          }
        }

95-103: 🛠️ Refactor suggestion

Process objects directly in safety settings array.

Similar to the history array, we should allow for the case where a safety setting in the array is already an object.

      return safetySettings.map((settingStr) => {
-        let setting = settingStr;
-        if (typeof setting === "string") {
-          try {
-            setting = JSON.parse(settingStr);
-          } catch (e) {
-            throw new ConfigurationError(`Invalid JSON in safety setting: ${settingStr}`);
-          }
+        let setting = settingStr;
+        if (typeof setting === "string") {
+          try {
+            setting = JSON.parse(settingStr);
+          } catch (e) {
+            throw new ConfigurationError(`Invalid JSON in safety setting: ${settingStr}`);
+          }
        }
🧹 Nitpick comments (1)
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (1)

57-58: Update error message to match the prop name.

The error message refers to "Image/Video paths" but the prop is named mediaPaths, which is more general and could include other media types.

-      throw new ConfigurationError("Image/Video paths must be an array.");
+      throw new ConfigurationError("Media paths must be an array.");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6df669 and 9932d26.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/google_gemini/actions/common/generate-content.mjs (2 hunks)
  • components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (4 hunks)
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (2 hunks)
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs (1 hunks)
  • components/google_gemini/common/constants.mjs (1 hunks)
  • components/google_gemini/google_gemini.app.mjs (2 hunks)
  • components/google_gemini/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • components/google_gemini/package.json
  • components/google_gemini/google_gemini.app.mjs
  • components/google_gemini/actions/generate-embeddings/generate-embeddings.mjs
  • components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
  • components/google_gemini/common/constants.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base

@jcortes jcortes force-pushed the google-gemini-update-actions branch from 9932d26 to 3dd50d7 Compare April 22, 2025 02:24
@jcortes jcortes merged commit 637b342 into master Apr 22, 2025
11 checks passed
@jcortes jcortes deleted the google-gemini-update-actions branch April 22, 2025 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ACTION] Update Google Gemini actions
2 participants