Skip to content

fix: don’t treat SVG uploads as vision images#2728

Open
KerwinLarrobis wants to merge 1 commit intogiselles-ai:mainfrom
KerwinLarrobis:fix-svg-mime-imagepart
Open

fix: don’t treat SVG uploads as vision images#2728
KerwinLarrobis wants to merge 1 commit intogiselles-ai:mainfrom
KerwinLarrobis:fix-svg-mime-imagepart

Conversation

@KerwinLarrobis
Copy link

@KerwinLarrobis KerwinLarrobis commented Feb 12, 2026

Summary

Prevent image/svg+xml files from being treated as vision ImagePart input.

Instead of sending SVG files to LLM providers (which do not support SVG), this change logs a warning and skips the file.

Why

LLM vision providers (OpenAI, Anthropic, Google) do not support SVG image input and return:
Unsupported MIME type: image/svg+xml.

This prevents SVG files from being passed as ImagePart objects.

Testing

pnpm -C packages/giselle test

All tests in the giselle package pass.

Closes #2714

Summary by CodeRabbit

  • New Features

    • Added WebP image format support for vision input processing.
  • Bug Fixes

    • SVG images are now properly rejected during vision input processing with a warning message, preventing improper handling of unsupported formats.

@changeset-bot
Copy link

changeset-bot bot commented Feb 12, 2026

⚠️ No Changeset found

Latest commit: 8489e14

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

💥 An error occurred when fetching the changed packages and changesets in this PR
Some errors occurred when validating the changesets config:
The package or glob expression "giselles-ai" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.

@vercel
Copy link

vercel bot commented Feb 12, 2026

@KerwinLarrobis is attempting to deploy a commit to the Giselle Team on Vercel.

A member of the Team first needs to authorize it.

@giselles-ai
Copy link

giselles-ai bot commented Feb 12, 2026

Finished running flow.

Step 1
🟢
On Pull Request OpenedStatus: Success Updated: Feb 12, 2026 11:44pm
Step 2
🟢
Manual QAStatus: Success Updated: Feb 12, 2026 11:47pm
🟢
Prompt for AI AgentsStatus: Success Updated: Feb 12, 2026 11:47pm
Step 3
🟢
Create a Comment for PRStatus: Success Updated: Feb 12, 2026 11:51pm
Step 4
🟢
Create Pull Request CommentStatus: Success Updated: Feb 12, 2026 11:51pm

@qodo-free-for-open-source-projects

Review Summary by Qodo

Prevent SVG files from being treated as vision images

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Remove SVG from supported vision image formats
• Log warning and skip SVG files instead of sending them
• Add WebP as supported image format for vision input
Diagram
flowchart LR
  SVG["SVG file upload"] --> Check{"MIME type check"}
  Check -->|JPEG/PNG/GIF/WebP| ImagePart["Return ImagePart"]
  Check -->|SVG| Warn["Log warning message"]
  Warn --> Skip["Return undefined"]
  Check -->|PDF| FilePart["Return FilePart"]
Loading

Grey Divider

File Changes

1. packages/giselle/src/generations/internal/use-generation-executor.ts 🐞 Bug fix +9/-1

Handle SVG files separately with warning logging

• Removed image/svg+xml from ImagePart case statement
• Added image/webp as supported vision image format
• Added dedicated SVG case that logs warning and returns undefined
• SVG files are now skipped instead of being sent to LLM providers

packages/giselle/src/generations/internal/use-generation-executor.ts


Grey Divider

Qodo Logo

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Modified the vision input processing to add support for WebP images and properly reject SVG images by returning undefined with a logger warning. These changes are applied consistently across two code paths: the main file resolution and the app-entry parameter resolution paths.

Changes

Cohort / File(s) Summary
Vision Input Format Handling
packages/giselle/src/generations/internal/use-generation-executor.ts
Added image/webp case to return an ImagePart for WebP images. Introduced image/svg+xml handling to log a warning and return undefined, preventing SVGs from being treated as supported vision input since major LLM providers do not support SVG format.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A rabbit hops through formats wide,
WebP now welcomed, SVG denied!
With warnings logged and undefined set,
No more unsupported MIME regret.
Clean paths ahead, both left and right,
Vision inputs handled just right! 🖼️

🚥 Pre-merge checks | ✅ 5 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: preventing SVG files from being treated as vision images.
Description check ✅ Passed The description follows the template structure with all key sections: Summary, Why (motivation), Testing, and closes a linked issue.
Linked Issues check ✅ Passed The code changes directly address issue #2714 by removing SVG from ImagePart handling and logging warnings, matching the chosen solution.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing SVG handling in vision input processing; no unrelated modifications detected.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
packages/giselle/src/generations/internal/use-generation-executor.ts (1)

576-581: Minor: trailing blank line on Line 582.

There's a trailing blank line after return undefined; (Line 582) before the case "application/pdf": block. This may be flagged by Biome. As per coding guidelines, run pnpm biome check --write on this file.

Suggested diff
 							case "image/svg+xml":
 								args.context.logger.warn(
 									{ id: fileParameter.id, type: fileParameter.type, name: fileParameter.name },
 									"SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.",
 								);
 								return undefined;
-								
+
 							case "application/pdf":

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Trailing whitespace line added 📘 Rule violation ✓ Correctness
Description
A line with trailing whitespace was introduced, which violates the repo’s Biome formatting
conventions and can cause formatting churn in diffs/CI. This should be removed to keep formatting
consistent.
Code

packages/giselle/src/generations/internal/use-generation-executor.ts[582]

+								
Evidence
PR Compliance ID 12 requires Biome-conformant formatting. The added blank line at 582 contains
whitespace characters, which Biome formatters typically remove and may fail lint/format checks.

AGENTS.md
packages/giselle/src/generations/internal/use-generation-executor.ts[576-583]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A whitespace-only line was introduced, which violates Biome formatting conventions.

## Issue Context
Biome format/lint may reformat or fail checks due to trailing whitespace.

## Fix Focus Areas
- packages/giselle/src/generations/internal/use-generation-executor.ts[581-583]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. SVG still reaches vision 🐞 Bug ✓ Correctness
Description
The PR only skips SVGs for appEntryResolver parameters; SVGs uploaded via File/Image nodes are still
converted to ImagePart (mediaType=image/svg+xml) and included in outgoing ModelMessage content, so
providers can still error on unsupported SVG input.
Code

packages/giselle/src/generations/internal/use-generation-executor.ts[R576-581]

+							case "image/svg+xml":
+								args.context.logger.warn(
+									{ id: fileParameter.id, type: fileParameter.type, name: fileParameter.name },
+									"SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.",
+								);
+								return undefined;
Evidence
The new code skips SVG only when resolving app-entry parameters. However, File/Image node
attachments are still mapped to ImagePart using the uploaded file.type (which can be image/svg+xml),
and attachedFiles are spread into the user message content sent to the model. The workflow designer
UI also explicitly allows SVG uploads in the image category, making this path likely in practice.

packages/giselle/src/generations/internal/use-generation-executor.ts[566-582]
packages/giselle/src/generations/utils.ts[440-465]
packages/giselle/src/generations/utils.ts[212-225]
packages/giselle/src/generations/utils.ts[358-368]
internal-packages/workflow-designer-ui/src/editor/properties-panel/file-node-properties-panel/index.tsx[8-20]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
SVG is only skipped in `appEntryResolver` parameter handling. SVGs uploaded through File/Image nodes can still be converted to `ImagePart` and included in outbound `ModelMessage.content`, which likely reintroduces the original provider error (`Unsupported MIME type: image/svg+xml`).

### Issue Context
The workflow designer UI currently allows SVG uploads in the `image` file category, and `getFileContents()` maps any `file.type` under `image` category to an `ImagePart` without filtering.

### Fix Focus Areas
- packages/giselle/src/generations/utils.ts[440-472]
- packages/giselle/src/generations/utils.ts[184-226]
- internal-packages/workflow-designer-ui/src/editor/properties-panel/file-node-properties-panel/index.tsx[8-21]
- packages/giselle/src/generations/internal/use-generation-executor.ts[566-582]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Logging fileParameter.name 📘 Rule violation ⛨ Security
Description
The new warning log includes fileParameter.name, which may contain user-provided PII or other
sensitive identifiers. This risks leaking sensitive data into logs.
Code

packages/giselle/src/generations/internal/use-generation-executor.ts[R577-580]

+								args.context.logger.warn(
+									{ id: fileParameter.id, type: fileParameter.type, name: fileParameter.name },
+									"SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.",
+								);
Evidence
PR Compliance ID 5 forbids sensitive data in logs. The new logger.warn includes the uploaded file
name (fileParameter.name), which is user-controlled and can embed personal/sensitive information.

Rule 5: Generic: Secure Logging Practices
packages/giselle/src/generations/internal/use-generation-executor.ts[577-580]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The warning log for SVG inputs includes `fileParameter.name`, which is user-provided and may contain PII/sensitive info.

## Issue Context
Secure logging practices require avoiding sensitive data in logs at any level; file names are frequently user-controlled and can contain identifying info.

## Fix Focus Areas
- packages/giselle/src/generations/internal/use-generation-executor.ts[577-580]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

"SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.",
);
return undefined;

Choose a reason for hiding this comment

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

Action required

1. Trailing whitespace line added 📘 Rule violation ✓ Correctness

A line with trailing whitespace was introduced, which violates the repo’s Biome formatting
conventions and can cause formatting churn in diffs/CI. This should be removed to keep formatting
consistent.
Agent Prompt
## Issue description
A whitespace-only line was introduced, which violates Biome formatting conventions.

## Issue Context
Biome format/lint may reformat or fail checks due to trailing whitespace.

## Fix Focus Areas
- packages/giselle/src/generations/internal/use-generation-executor.ts[581-583]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +576 to +581
case "image/svg+xml":
args.context.logger.warn(
{ id: fileParameter.id, type: fileParameter.type, name: fileParameter.name },
"SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.",
);
return undefined;

Choose a reason for hiding this comment

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

Action required

2. Svg still reaches vision 🐞 Bug ✓ Correctness

The PR only skips SVGs for appEntryResolver parameters; SVGs uploaded via File/Image nodes are still
converted to ImagePart (mediaType=image/svg+xml) and included in outgoing ModelMessage content, so
providers can still error on unsupported SVG input.
Agent Prompt
### Issue description
SVG is only skipped in `appEntryResolver` parameter handling. SVGs uploaded through File/Image nodes can still be converted to `ImagePart` and included in outbound `ModelMessage.content`, which likely reintroduces the original provider error (`Unsupported MIME type: image/svg+xml`).

### Issue Context
The workflow designer UI currently allows SVG uploads in the `image` file category, and `getFileContents()` maps any `file.type` under `image` category to an `ImagePart` without filtering.

### Fix Focus Areas
- packages/giselle/src/generations/utils.ts[440-472]
- packages/giselle/src/generations/utils.ts[184-226]
- internal-packages/workflow-designer-ui/src/editor/properties-panel/file-node-properties-panel/index.tsx[8-21]
- packages/giselle/src/generations/internal/use-generation-executor.ts[566-582]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@giselles-ai
Copy link

giselles-ai bot commented Feb 12, 2026

## 🔍 QA Testing Assistant by Giselle

### 📋 Manual QA Checklist

Based on the changes in this PR, here are the key areas to test manually:

  • Test 1: Upload only an SVG file

    1. Start a new chat or interaction that uses a vision model.
    2. Upload an SVG file.
    3. Enter a prompt like, "What do you see?" and submit.
    4. Expected Result: The request should process without any errors. The model's response should be based only on the text prompt, as if no image was attached.
    5. Log Verification: Check the application logs. You should find a WARN level log entry with the message: SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.
  • Test 2: Upload an SVG file alongside a supported image

    1. Start a new chat or interaction that uses a vision model.
    2. Upload two files at the same time: one SVG and one PNG.
    3. Enter a prompt like, "Describe the image(s) I've uploaded," and submit.
    4. Expected Result: The request should process successfully. The model's response should accurately describe the content of the PNG file, completely ignoring the SVG.
    5. Log Verification: Check the logs. You should see the same warning message for the SVG file as in the test above, but no errors or warnings for the PNG file.
  • Test 3: Upload a WebP file

    1. Start a new chat or interaction that uses a vision model.
    2. Upload a WebP (.webp) file.
    3. Enter a prompt like, "What is in this picture?" and submit.
    4. Expected Result: The request should process successfully. The model should return a response that accurately describes the contents of the WebP image.
  • Test 4: Upload a PNG file

    1. Follow the same steps as Test 3, but upload a PNG file.
    2. Expected Result: The model should successfully describe the PNG image.
  • Test 5: Upload a JPEG file

    1. Follow the same steps as Test 3, but upload a JPEG file.
    2. Expected Result: The model should successfully describe the JPEG image.
  • Test 6: Upload a GIF file

    1. Follow the same steps as Test 3, but upload a GIF file.
    2. Expected Result: The model should successfully describe the GIF image (likely its first frame).

### ✨ Prompt for AI Agents

Use the following prompts with Cursor or Claude Code to automate E2E testing:

📝 E2E Test Generation Prompt

```

Hello! You are an expert automated testing engineer. Your task is to write a new Playwright E2E test suite based on the context and code changes from a recent Pull Request.

The goal is to verify that SVG files are no longer treated as vision inputs, a warning is logged, and other supported image formats continue to work correctly.


1. Context Summary

  • PR Description: The PR implements a fix to prevent image/svg+xml files from being sent to Large Language Model (LLM) vision providers. These providers do not support SVGs and would return an error.
  • The Fix: The code now intercepts SVG file uploads, logs a console warning, and skips the file, preventing it from being included in the payload sent to the LLM.
  • Key User Flow: The user attaches files to a chat prompt, enters a message, and sends it to an LLM for a response.
  • Critical Paths to Test:
    1. Uploading an SVG file should result in it being gracefully ignored as a vision input.
    2. The application should log a specific warning to the console when an SVG is uploaded.
    3. Uploading supported image types (PNG, JPG, GIF, WebP) must remain fully functional.
    4. Uploading a mix of supported and unsupported files should handle each file type correctly.

2. Test Scenarios

Please create E2E tests covering the following scenarios in a new test file named file-upload-vision.spec.ts.

  • Scenario 1: (Happy Path / Regression) Successful PNG Upload

    • Given a user is on the chat page.
    • When they upload a valid PNG file and enter a prompt.
    • And they send the message.
    • Then the network request to the LLM should contain the PNG image data.
    • And no console warnings related to file types should be logged.
  • Scenario 2: (The Fix) SVG Upload is Skipped with a Warning

    • Given a user is on the chat page.
    • When they upload an SVG file and enter a prompt.
    • And they send the message.
    • Then a specific warning message must be logged to the browser console.
    • And the network request to the LLM must not contain any image data related to the SVG file.
  • Scenario 3: (Edge Case) Mixed Upload of Supported and Unsupported Images

    • Given a user is on the chat page.
    • When they upload both a PNG file and an SVG file simultaneously.
    • And they send the message.
    • Then a specific warning message for the SVG file must be logged to the browser console.
    • And the network request to the LLM should contain the PNG image data.
    • And the network request to the LLM must not contain the SVG image data.
  • Scenario 4: (Regression) Verify Other Supported Image Types

    • Given a user is on the chat page.
    • When they upload a valid JPEG file.
    • And they send the message.
    • Then the network request to the LLM should contain the JPEG image data.
    • And no file-related console warnings are logged.

3. Playwright Implementation Instructions

Use the following guidelines to implement the tests.

  • Test File Setup:

    • Create a new file: tests/e2e/file-upload-vision.spec.ts.
    • Import test and expect from @playwright/test.
  • Selectors:

    • Assume the following data-testid attributes are available. If not, use functionally equivalent selectors.
      • File Upload Input: [data-testid="file-upload-input"]
      • Chat Text Input: [data-testid="chat-input"]
      • Send Button: [data-testid="send-button"]
  • File Generation:

    • Do not rely on external files. Generate the necessary files directly within the test using Buffer.
    // Example for a 1x1 PNG file
    const pngBuffer = Buffer.from(
      'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYGBg+A8AAQQBAHAgZQsAAAAASUVORK5CYII=',
      'base64'
    );
    
    // Example for a minimal SVG file
    const svgBuffer = Buffer.from(
      '<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><circle cx="5" cy="5" r="4" fill="blue" /></svg>'
    );
    
    // Example for a 1x1 JPEG file
    const jpegBuffer = Buffer.from(
        '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5ufo6erx8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD86P8Ah7R+zT/0XX9oL/w4H/yvrCg/4K4fs8TwRTj9oz47jzEV9v8AwjAOMjOM/aOa/KP/AIJ7/wDBEr/go5+0L+z3pfxG+FP7d3/CvfCWo6hqUNn4b/4WV400/AmWG5kime+ytrC6t5rO+3y3Dbdu48kX6Zf8AEOq/8Aqz/APpI5/5mDxx/wDGaAP/2Q==',
        'base64'
    );
  • Simulating User Interactions:

    • Use page.locator(...).setInputFiles() to attach files. You can pass an array of file payloads to simulate multiple uploads.
    // Single file upload
    await page.locator('[data-testid="file-upload-input"]').setInputFiles({
      name: 'image.svg',
      mimeType: 'image/svg+xml',
      buffer: svgBuffer,
    });
    
    // Multiple file upload
    await page.locator('[data-testid="file-upload-input"]').setInputFiles([
      { name: 'image.png', mimeType: 'image/png', buffer: pngBuffer },
      { name: 'image.svg', mimeType: 'image/svg+xml', buffer: svgBuffer },
    ]);
  • Assertions:

    1. Console Message Assertion: This is critical. Listen for console events and verify the exact warning message.

      const messages: string[] = [];
      page.on('console', msg => {
          if (msg.type() === 'warning') {
              messages.push(msg.text());
          }
      });
      
      // ... perform actions that trigger the warning ...
      
      const expectedWarning = "SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.";
      expect(messages.some(msg => msg.includes(expectedWarning))).toBe(true);
    2. Network Request Assertion: Mock the API endpoint for the LLM (e.g., /api/generate) and inspect the request payload to ensure files are included/excluded correctly. This is the most reliable way to test the underlying logic.

      // Mock the API route before the interaction
      let requestPayload: any = null;
      await page.route('**/api/generate', async route => {
        requestPayload = route.request().postDataJSON();
        // Fulfill the request to not block the UI
        await route.fulfill({ status: 200, body: JSON.stringify({ response: 'OK' }) });
      });
      
      // ... perform actions (upload, type, click send) ...
      
      // Assertion for SVG test: ensure no image parts are sent
      expect(requestPayload.parts.some((part: any) => part.type === 'image')).toBe(false);
      
      // Assertion for PNG test: ensure an image part is sent
      expect(requestPayload.parts.some((part: any) => part.type === 'image')).toBe(true);

4. MCP Integration Guidelines

While you don't need to write the config file, structure the tests to be compatible with Playwright MCP (Multi-threaded Coordinator and Player).

  • Test File Setup:

    • Create a new file: tests/e2e/file-upload-vision.spec.ts.
    • Import test and expect from @playwright/test.
  • Selectors:

    • Assume the following data-testid attributes are available. If not, use functionally equivalent selectors.
      • File Upload Input: [data-testid="file-upload-input"]
      • Chat Text Input: [data-testid="chat-input"]
      • Send Button: [data-testid="send-button"]
  • File Generation:

    • Do not rely on external files. Generate the necessary files directly within the test using Buffer.
    // Example for a 1x1 PNG file
    const pngBuffer = Buffer.from(
      'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYGBg+A8AAQQBAHAgZQsAAAAASUVORK5CYII=',
      'base64'
    );
    
    // Example for a minimal SVG file
    const svgBuffer = Buffer.from(
      '<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><circle cx="5" cy="5" r="4" fill="blue" /></svg>'
    );
    
    // Example for a 1x1 JPEG file
    const jpegBuffer = Buffer.from(
        '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5ufo6erx8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD86P8Ah7R+zT/0XX9oL/w4H/yvrCg/4K4fs8TwRTj9oz47jzEV9v8AwjAOMjOM/aOa/KP/AIJ7/wDBEr/go5+0L+z3pfxG+FP7d3/CvfCWo6hqUNn4b/4WV400/AmWG5kime+ytrC6t5rO+3y3Dbdu48kX6Zf8AEOq/8Aqz/APpI5/5mDxx/wDGaAP/2Q==',
        'base64'
    );
  • Simulating User Interactions:

    • Use page.locator(...).setInputFiles() to attach files. You can pass an array of file payloads to simulate multiple uploads.
    // Single file upload
    await page.locator('[data-testid="file-upload-input"]').setInputFiles({
      name: 'image.svg',
      mimeType: 'image/svg+xml',
      buffer: svgBuffer,
    });
    
    // Multiple file upload
    await page.locator('[data-testid="file-upload-input"]').setInputFiles([
      { name: 'image.png', mimeType: 'image/png', buffer: pngBuffer },
      { name: 'image.svg', mimeType: 'image/svg+xml', buffer: svgBuffer },
    ]);
  • Assertions:

    1. Console Message Assertion: This is critical. Listen for console events and verify the exact warning message.

      const messages: string[] = [];
      page.on('console', msg => {
          if (msg.type() === 'warning') {
              messages.push(msg.text());
          }
      });
      
      // ... perform actions that trigger the warning ...
      
      const expectedWarning = "SVG is not supported for vision input. Please upload PNG/JPEG/GIF/WebP instead.";
      expect(messages.some(msg => msg.includes(expectedWarning))).toBe(true);
    2. Network Request Assertion: Mock the API endpoint for the LLM (e.g., /api/generate) and inspect the request payload to ensure files are included/excluded correctly. This is the most reliable way to test the underlying logic.

      // Mock the API route before the interaction
      let requestPayload: any = null;
      await page.route('**/api/generate', async route => {
        requestPayload = route.request().postDataJSON();
        // Fulfill the request to not block the UI
        await route.fulfill({ status: 200, body: JSON.stringify({ response: 'OK' }) });
      });
      
      // ... perform actions (upload, type, click send) ...
      
      // Assertion for SVG test: ensure no image parts are sent
      expect(requestPayload.parts.some((part: any) => part.type === 'image')).toBe(false);
      
      // Assertion for PNG test: ensure an image part is sent
      expect(requestPayload.parts.some((part: any) => part.type === 'image')).toBe(true);

4. MCP Integration Guidelines

  • Command Structure: The tests will be run via a command like mcp --config=mcp.config.ts.
  • Parallelization: Ensure all tests are atomic and independent. Use test.beforeEach to reset state (like navigating to the page) for each test, which is standard practice and ensures they can run in any order and in parallel.

5. CI-Ready Code Requirements

  • Test Organization: Place the new test file in tests/e2e/.
  • Naming Conventions: Use clear, descriptive names for tests using the test('description', ...) format. For example: test('should skip SVG files and log a console warning', ...).
  • Code Quality:
    • Use async/await correctly.
    • Code should be clean, readable, and well-commented where necessary.
    • Include await page.waitForTimeout(100); after triggering actions if needed to allow asynchronous events (like console logs or network requests) to be processed before assertions.
    • Wrap tests in a test.describe('File Upload for Vision', () => { ... }); block for better organization and reporting.

-->

```

---

Copy link
Member

@shige shige left a comment

Choose a reason for hiding this comment

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

Review

Thanks for fixing the SVG handling issue! The core fix is correct — returning undefined for SVG and adding WebP support are both good changes. However, there are a couple of things I'd like to see addressed before merging.

1. Trailing whitespace (nit)

packages/giselle/src/generations/internal/use-generation-executor.ts line 582

There's trailing whitespace after return undefined;. Could you clean that up?

2. UI still accepts SVG uploads for image nodes

internal-packages/workflow-designer-ui/src/editor/properties-panel/file-node-properties-panel/index.tsx line 18

The image upload accept list still includes image/svg+xml:

accept: ["image/png", "image/jpeg", "image/gif", "image/svg+xml"],

With this PR, SVG files uploaded through the Image node will be silently dropped at generation time — the user won't see the warning log. This creates a confusing experience where the upload succeeds but the image is quietly ignored.

Could you remove image/svg+xml from this accept list so users can't upload SVGs as images in the first place? Also, since the backend now supports image/webp, it would be good to add it here too:

accept: ["image/png", "image/jpeg", "image/gif", "image/webp"],

3. Misleading validation message for SVG in file-panel.tsx

internal-packages/workflow-designer-ui/src/editor/properties-panel/file-node-properties-panel/file-panel.tsx line 53

This validation returns "Please use Image node to upload this file." for image/svg+xml. Since SVGs will no longer work as image inputs, this message becomes misleading. If SVG is removed from the image accept list (as suggested above), this case can also be removed or updated to something like "SVG is not supported. Please use PNG/JPEG/GIF/WebP instead.".

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.

SVG images incorrectly handled as ImagePart causing "Unsupported MIME type" error

2 participants