-
-
Notifications
You must be signed in to change notification settings - Fork 13.9k
🐛 fix(ai-image): save config.imageUrl with fullUrl instead of key #9016
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
Conversation
Fix compatibility issue where historical data stored complete URLs instead of keys, causing expired presigned URLs and concatenation errors. - Add URL detection and key extraction for both S3 and local services - Extract shared utility function with comprehensive tests - Maintain backward compatibility for existing key-based data Closes #8994
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Reviewer's GuideThis PR addresses legacy data compatibility by extracting S3/local file keys from stored full URLs before generating new URLs, using a shared utility, integrating it into file service implementations and the image router, and adding comprehensive tests to cover both normal and URL-based inputs without breaking existing key-based behavior. Sequence diagram for file key extraction in getFullFileUrl (S3 and Local)sequenceDiagram
participant Caller
participant FileServiceImpl
participant extractKeyFromUrlOrReturnOriginal
participant getKeyFromFullUrl
participant getLocalFileUrl
participant createPreSignedUrlForPreview
Caller->>FileServiceImpl: getFullFileUrl(url)
FileServiceImpl->>extractKeyFromUrlOrReturnOriginal: extractKeyFromUrlOrReturnOriginal(url, getKeyFromFullUrl)
alt url starts with http(s)://
extractKeyFromUrlOrReturnOriginal->>getKeyFromFullUrl: getKeyFromFullUrl(url)
getKeyFromFullUrl-->>extractKeyFromUrlOrReturnOriginal: key
extractKeyFromUrlOrReturnOriginal-->>FileServiceImpl: key
else url is already a key
extractKeyFromUrlOrReturnOriginal-->>FileServiceImpl: url
end
alt S3StaticFileImpl
FileServiceImpl->>createPreSignedUrlForPreview: createPreSignedUrlForPreview(key, expiresIn)
createPreSignedUrlForPreview-->>FileServiceImpl: presignedUrl
FileServiceImpl-->>Caller: presignedUrl
else DesktopLocalFileImpl
FileServiceImpl->>getLocalFileUrl: getLocalFileUrl(key)
getLocalFileUrl-->>FileServiceImpl: localFileUrl
FileServiceImpl-->>Caller: localFileUrl
end
Sequence diagram for imageRouter storing normalized image URLssequenceDiagram
participant imageRouter
participant fileService
participant extractKeyFromUrlOrReturnOriginal
participant getKeyFromFullUrl
participant Database
imageRouter->>fileService: getKeyFromFullUrl(imageUrl)
fileService->>extractKeyFromUrlOrReturnOriginal: extractKeyFromUrlOrReturnOriginal(imageUrl, getKeyFromFullUrl)
alt imageUrl starts with http(s)://
extractKeyFromUrlOrReturnOriginal->>getKeyFromFullUrl: getKeyFromFullUrl(imageUrl)
getKeyFromFullUrl-->>extractKeyFromUrlOrReturnOriginal: key
extractKeyFromUrlOrReturnOriginal-->>fileService: key
else imageUrl is already a key
extractKeyFromUrlOrReturnOriginal-->>fileService: imageUrl
end
fileService-->>imageRouter: key
imageRouter->>Database: store key as imageUrl
Database-->>imageRouter: ack
Class diagram for updated file service implementations and utilityclassDiagram
class S3StaticFileImpl {
+getFullFileUrl(url, expiresIn)
+getKeyFromFullUrl(url)
-createPreSignedUrlForPreview(key, expiresIn)
}
class DesktopLocalFileImpl {
+getFullFileUrl(url)
+getKeyFromFullUrl(url)
-getLocalFileUrl(key)
}
class extractKeyFromUrlOrReturnOriginal {
+extractKeyFromUrlOrReturnOriginal(url, getKeyFromFullUrl)
}
S3StaticFileImpl --> extractKeyFromUrlOrReturnOriginal : uses
DesktopLocalFileImpl --> extractKeyFromUrlOrReturnOriginal : uses
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
👍 @tjx666 Thank you for raising your pull request and contributing to our Community |
TestGru AssignmentSummary
Files
Tip You can |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9016 +/- ##
=========================================
Coverage 77.17% 77.17%
=========================================
Files 810 818 +8
Lines 48848 49087 +239
Branches 5226 6381 +1155
=========================================
+ Hits 37696 37883 +187
- Misses 11146 11198 +52
Partials 6 6
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/server/routers/lambda/image.ts:97` </location>
<code_context>
}
}
+ // 2) 处理单图 imageUrl
+ if (typeof params.imageUrl === 'string' && params.imageUrl) {
+ try {
+ const key = fileService.getKeyFromFullUrl(params.imageUrl);
+ log('Converted single imageUrl to key: %s -> %s', params.imageUrl, key);
+ configForDatabase = { ...configForDatabase, imageUrl: key };
+ } catch (error) {
+ log('Error converting imageUrl to key: %O', error);
</code_context>
<issue_to_address>
Consider using the shared utility for key extraction for consistency.
Use extractKeyFromUrlOrReturnOriginal for key extraction to align with other usages and improve maintainability.
Suggested implementation:
```typescript
const key = extractKeyFromUrlOrReturnOriginal(params.imageUrl);
log('Converted single imageUrl to key using shared utility: %s -> %s', params.imageUrl, key);
configForDatabase = { ...configForDatabase, imageUrl: key };
```
If `extractKeyFromUrlOrReturnOriginal` is not already imported in this file, add the following import statement at the top of the file (adjust the import path as needed for your project structure):
```typescript
import { extractKeyFromUrlOrReturnOriginal } from 'shared/utils/fileKeyUtils';
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Refactor the path for aiModels in the VSCode settings to simplify the structure. This change enhances the organization of model files within the project.
Add recursive validation to prevent full URLs from being stored in database: - Validate configForDatabase before transaction to ensure only keys are stored - Comprehensive error reporting with precise field path location - Add 9 test cases covering valid/invalid configs and edge cases Prevents data corruption from accidentally storing complete URLs instead of storage keys
|
❤️ Great PR @tjx666 ❤️ The growth of project is inseparable from user feedback and contribution, thanks for your contribution! If you are interesting with the lobehub developer community, please join our discord and then dm @arvinxx or @canisminor1990. They will invite you to our private developer channel. We are talking about the lobe-chat development or sharing ai newsletter around the world. |
### [Version 1.120.5](v1.120.4...v1.120.5) <sup>Released on **2025-09-01**</sup> #### 🐛 Bug Fixes - **ai-image**: Save config.imageUrl with fullUrl instead of key. <br/> <details> <summary><kbd>Improvements and Fixes</kbd></summary> #### What's fixed * **ai-image**: Save config.imageUrl with fullUrl instead of key, closes [#9016](#9016) ([bad009a](bad009a)) </details> <div align="right"> [](#readme-top) </div>
|
🎉 This PR is included in version 1.120.5 🎉 The release is available on: Your semantic-release bot 📦🚀 |
## [Version 1.120.0](v1.119.1...v1.120.0) <sup>Released on **2025-09-02**</sup> #### ♻ Code Refactoring - **model-runtime**: Refactor model-runtime dependencies and clean code. - **misc**: Remove base path, remove webrtc sync feature flag. #### ✨ Features - **misc**: Added support for Azure OpenAI Image Generation, rename Gemini 2.5 flash image to Nano Banana. #### 🐛 Bug Fixes - **ai-image**: Save config.imageUrl with fullUrl instead of key. - **misc**: Update enableStreaming name. #### 💄 Styles - **misc**: Add upload hint for non-visual model, adjust ControlsForm component to adapt to mobile phone display, Support new provider Nebius, update i18n, update i18n. <br/> <details> <summary><kbd>Improvements and Fixes</kbd></summary> #### Code refactoring * **model-runtime**: Refactor model-runtime dependencies and clean code, closes [lobehub#8997](https://github.com/jaworldwideorg/OneJA-Bot/issues/8997) ([9f7677d](9f7677d)) * **misc**: Remove base path, closes [lobehub#9015](https://github.com/jaworldwideorg/OneJA-Bot/issues/9015) ([2a5f8d7](2a5f8d7)) * **misc**: Remove webrtc sync feature flag, closes [lobehub#9002](https://github.com/jaworldwideorg/OneJA-Bot/issues/9002) ([0924d98](0924d98)) #### What's improved * **misc**: Added support for Azure OpenAI Image Generation, closes [lobehub#8898](https://github.com/jaworldwideorg/OneJA-Bot/issues/8898) ([6042340](6042340)) * **misc**: Rename Gemini 2.5 flash image to Nano Banana, closes [lobehub#9004](https://github.com/jaworldwideorg/OneJA-Bot/issues/9004) ([dac5a6f](dac5a6f)) #### What's fixed * **ai-image**: Save config.imageUrl with fullUrl instead of key, closes [lobehub#9016](https://github.com/jaworldwideorg/OneJA-Bot/issues/9016) ([bad009a](bad009a)) * **misc**: Update enableStreaming name, closes [lobehub#8995](https://github.com/jaworldwideorg/OneJA-Bot/issues/8995) ([7c7de40](7c7de40)) #### Styles * **misc**: Add upload hint for non-visual model, closes [lobehub#7969](https://github.com/jaworldwideorg/OneJA-Bot/issues/7969) ([1224f4e](1224f4e)) * **misc**: Adjust ControlsForm component to adapt to mobile phone display, closes [lobehub#9013](https://github.com/jaworldwideorg/OneJA-Bot/issues/9013) ([c6038c0](c6038c0)) * **misc**: Support new provider Nebius, closes [lobehub#8903](https://github.com/jaworldwideorg/OneJA-Bot/issues/8903) ([c15791d](c15791d)) * **misc**: Update i18n, closes [lobehub#9033](https://github.com/jaworldwideorg/OneJA-Bot/issues/9033) ([650e552](650e552)) * **misc**: Update i18n, closes [lobehub#9005](https://github.com/jaworldwideorg/OneJA-Bot/issues/9005) ([63760f9](63760f9)) </details> <div align="right"> [](#readme-top) </div>
### [Version 1.120.5](lobehub/lobe-chat@v1.120.4...v1.120.5) <sup>Released on **2025-09-01**</sup> #### 🐛 Bug Fixes - **ai-image**: Save config.imageUrl with fullUrl instead of key. <br/> <details> <summary><kbd>Improvements and Fixes</kbd></summary> #### What's fixed * **ai-image**: Save config.imageUrl with fullUrl instead of key, closes [lobehub#9016](lobehub#9016) ([bad009a](lobehub@bad009a)) </details> <div align="right"> [](#readme-top) </div>
💻 变更类型 | Change Type
🔀 变更说明 | Description of Change
Fix compatibility issue where historical data stored complete URLs instead of keys in file services, causing expired presigned URLs and URL concatenation errors.
Key Changes:
http://andhttps://protocols for legacy dataProblem Solved:
📝 补充信息 | Additional Information
Closes #8994
Testing:
Backward Compatibility:
http://orhttps://for legacy compatibilitySummary by Sourcery
Fix legacy full URL handling in file services and image router by extracting keys from URLs before generating or storing file paths, preserving backward compatibility and avoiding expired or malformed URLs
Bug Fixes:
Enhancements:
Tests: