mirror of
https://github.com/linshenkx/prompt-optimizer.git
synced 2026-05-06 21:50:27 +08:00
fix(core): allow multi-image requests past stale capabilities
This commit is contained in:
@@ -155,21 +155,6 @@ export class ImageService implements IImageService {
|
||||
|
||||
this.validateInputImage(inputImage)
|
||||
}
|
||||
|
||||
const config = await this.imageModelManager.getConfig(request.configId)
|
||||
if (!config) {
|
||||
throw new ImageError(IMAGE_ERROR_CODES.CONFIG_NOT_FOUND, undefined, { configId: request.configId })
|
||||
}
|
||||
|
||||
const configModel = config.model
|
||||
const staticModels = this.registry.getStaticModels(config.providerId)
|
||||
const staticModel = staticModels.find(m => m.id === config.modelId)
|
||||
const capabilities = configModel?.capabilities ?? staticModel?.capabilities
|
||||
const modelName = configModel?.name ?? staticModel?.name ?? config.modelId
|
||||
|
||||
if (capabilities && !capabilities.multiImage) {
|
||||
throw new ImageError(IMAGE_ERROR_CODES.MODEL_NOT_SUPPORT_MULTI_IMAGE, undefined, { modelName })
|
||||
}
|
||||
}
|
||||
|
||||
private async validateBaseRequest(request: Pick<ImageRequest, 'prompt' | 'configId' | 'count'>): Promise<void> {
|
||||
|
||||
@@ -503,6 +503,30 @@ describe('ImageService', () => {
|
||||
await expect(imageService.validateMultiImageRequest(request)).resolves.not.toThrow()
|
||||
})
|
||||
|
||||
test('should not reject multi-image requests only because local capabilities say multiImage is unsupported', async () => {
|
||||
await mockModelManager.updateConfig('test-multiimage-config', {
|
||||
model: {
|
||||
...(await mockModelManager.getConfig('test-multiimage-config'))!.model,
|
||||
capabilities: {
|
||||
text2image: true,
|
||||
image2image: true,
|
||||
multiImage: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const request: MultiImageRequest = {
|
||||
prompt: 'merge these references into one scene',
|
||||
configId: 'test-multiimage-config',
|
||||
inputImages: [
|
||||
{ b64: 'AAAA', mimeType: 'image/png' },
|
||||
{ b64: 'BBBB', mimeType: 'image/jpeg' }
|
||||
]
|
||||
}
|
||||
|
||||
await expect(imageService.validateMultiImageRequest(request)).resolves.not.toThrow()
|
||||
})
|
||||
|
||||
test('should reject multi-image requests with fewer than two images', async () => {
|
||||
const request: MultiImageRequest = {
|
||||
prompt: 'merge these references into one scene',
|
||||
@@ -671,6 +695,62 @@ describe('ImageService', () => {
|
||||
expect(result.metadata?.modelId).toBe('gemini-2.5-flash-image-preview')
|
||||
expect(registry.getAdapter).toHaveBeenCalledWith('gemini')
|
||||
})
|
||||
|
||||
test('should still call the adapter for multi-image generation when local capability metadata is stale', async () => {
|
||||
await mockModelManager.updateConfig('test-multiimage-config', {
|
||||
model: {
|
||||
...(await mockModelManager.getConfig('test-multiimage-config'))!.model,
|
||||
capabilities: {
|
||||
text2image: true,
|
||||
image2image: true,
|
||||
multiImage: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const adapterGenerate = vi.fn().mockResolvedValue({
|
||||
images: [{ b64: 'aGVsbG8=', mimeType: 'image/png', url: 'data:image/png;base64,aGVsbG8=' }],
|
||||
})
|
||||
|
||||
const registry = {
|
||||
getAdapter: vi.fn().mockReturnValue({
|
||||
generate: adapterGenerate,
|
||||
}),
|
||||
getStaticModels: vi.fn().mockReturnValue([
|
||||
{
|
||||
id: 'gemini-2.5-flash-image-preview',
|
||||
name: 'Gemini 2.5 Flash Image Preview',
|
||||
providerId: 'gemini',
|
||||
capabilities: { text2image: true, image2image: true, multiImage: false },
|
||||
parameterDefinitions: [],
|
||||
defaultParameterValues: {},
|
||||
},
|
||||
]),
|
||||
getDynamicModels: vi.fn(),
|
||||
getModels: vi.fn(),
|
||||
getAllProviders: vi.fn(),
|
||||
getAllStaticModels: vi.fn(),
|
||||
supportsDynamicModels: vi.fn(),
|
||||
validateProviderModel: vi.fn(),
|
||||
} as unknown as IImageAdapterRegistry
|
||||
const multiImageService = new ImageService(mockModelManager, registry)
|
||||
|
||||
const request: MultiImageGenerationRequest = {
|
||||
prompt: 'compose 图1 and 图2 into one cinematic frame',
|
||||
configId: 'test-multiimage-config',
|
||||
inputImages: [
|
||||
{ b64: 'AAAA', mimeType: 'image/png' },
|
||||
{ b64: 'BBBB', mimeType: 'image/png' }
|
||||
]
|
||||
}
|
||||
|
||||
await expect(multiImageService.generateMultiImage(request)).resolves.toMatchObject({
|
||||
metadata: {
|
||||
configId: 'test-multiimage-config',
|
||||
},
|
||||
})
|
||||
expect(adapterGenerate).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Error Handling', () => {
|
||||
|
||||
Reference in New Issue
Block a user