mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
Add test
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { Cline } from '../Cline';
|
||||
import { ClineProvider } from '../webview/ClineProvider';
|
||||
import { ApiConfiguration } from '../../shared/api';
|
||||
import { ApiConfiguration, ModelInfo } from '../../shared/api';
|
||||
import { ApiStreamChunk } from '../../api/transform/stream';
|
||||
import { Anthropic } from '@anthropic-ai/sdk';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
// Mock all MCP-related modules
|
||||
@@ -498,6 +499,133 @@ describe('Cline', () => {
|
||||
expect(passedMessage).not.toHaveProperty('ts');
|
||||
expect(passedMessage).not.toHaveProperty('extraProp');
|
||||
});
|
||||
|
||||
it('should handle image blocks based on model capabilities', async () => {
|
||||
// Create two configurations - one with image support, one without
|
||||
const configWithImages = {
|
||||
...mockApiConfig,
|
||||
apiModelId: 'claude-3-sonnet'
|
||||
};
|
||||
const configWithoutImages = {
|
||||
...mockApiConfig,
|
||||
apiModelId: 'gpt-3.5-turbo'
|
||||
};
|
||||
|
||||
// Create test conversation history with mixed content
|
||||
const conversationHistory: (Anthropic.MessageParam & { ts?: number })[] = [
|
||||
{
|
||||
role: 'user' as const,
|
||||
content: [
|
||||
{
|
||||
type: 'text' as const,
|
||||
text: 'Here is an image'
|
||||
} satisfies Anthropic.TextBlockParam,
|
||||
{
|
||||
type: 'image' as const,
|
||||
source: {
|
||||
type: 'base64' as const,
|
||||
media_type: 'image/jpeg',
|
||||
data: 'base64data'
|
||||
}
|
||||
} satisfies Anthropic.ImageBlockParam
|
||||
]
|
||||
},
|
||||
{
|
||||
role: 'assistant' as const,
|
||||
content: [{
|
||||
type: 'text' as const,
|
||||
text: 'I see the image'
|
||||
} satisfies Anthropic.TextBlockParam]
|
||||
}
|
||||
];
|
||||
|
||||
// Test with model that supports images
|
||||
const clineWithImages = new Cline(
|
||||
mockProvider,
|
||||
configWithImages,
|
||||
undefined,
|
||||
false,
|
||||
undefined,
|
||||
'test task'
|
||||
);
|
||||
// Mock the model info to indicate image support
|
||||
jest.spyOn(clineWithImages.api, 'getModel').mockReturnValue({
|
||||
id: 'claude-3-sonnet',
|
||||
info: {
|
||||
supportsImages: true,
|
||||
supportsPromptCache: true,
|
||||
supportsComputerUse: true,
|
||||
contextWindow: 200000,
|
||||
maxTokens: 4096,
|
||||
inputPrice: 0.25,
|
||||
outputPrice: 0.75
|
||||
} as ModelInfo
|
||||
});
|
||||
clineWithImages.apiConversationHistory = conversationHistory;
|
||||
|
||||
// Test with model that doesn't support images
|
||||
const clineWithoutImages = new Cline(
|
||||
mockProvider,
|
||||
configWithoutImages,
|
||||
undefined,
|
||||
false,
|
||||
undefined,
|
||||
'test task'
|
||||
);
|
||||
// Mock the model info to indicate no image support
|
||||
jest.spyOn(clineWithoutImages.api, 'getModel').mockReturnValue({
|
||||
id: 'gpt-3.5-turbo',
|
||||
info: {
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
supportsComputerUse: false,
|
||||
contextWindow: 16000,
|
||||
maxTokens: 2048,
|
||||
inputPrice: 0.1,
|
||||
outputPrice: 0.2
|
||||
} as ModelInfo
|
||||
});
|
||||
clineWithoutImages.apiConversationHistory = conversationHistory;
|
||||
|
||||
// Create message spy for both instances
|
||||
const createMessageSpyWithImages = jest.fn();
|
||||
const createMessageSpyWithoutImages = jest.fn();
|
||||
const mockStream = {
|
||||
async *[Symbol.asyncIterator]() {
|
||||
yield { type: 'text', text: '' };
|
||||
}
|
||||
} as AsyncGenerator<ApiStreamChunk>;
|
||||
|
||||
jest.spyOn(clineWithImages.api, 'createMessage').mockImplementation((...args) => {
|
||||
createMessageSpyWithImages(...args);
|
||||
return mockStream;
|
||||
});
|
||||
jest.spyOn(clineWithoutImages.api, 'createMessage').mockImplementation((...args) => {
|
||||
createMessageSpyWithoutImages(...args);
|
||||
return mockStream;
|
||||
});
|
||||
|
||||
// Trigger API requests for both instances
|
||||
await clineWithImages.recursivelyMakeClineRequests([{ type: 'text', text: 'test' }]);
|
||||
await clineWithoutImages.recursivelyMakeClineRequests([{ type: 'text', text: 'test' }]);
|
||||
|
||||
// Verify model with image support preserves image blocks
|
||||
const callsWithImages = createMessageSpyWithImages.mock.calls;
|
||||
const historyWithImages = callsWithImages[0][1][0];
|
||||
expect(historyWithImages.content).toHaveLength(2);
|
||||
expect(historyWithImages.content[0]).toEqual({ type: 'text', text: 'Here is an image' });
|
||||
expect(historyWithImages.content[1]).toHaveProperty('type', 'image');
|
||||
|
||||
// Verify model without image support converts image blocks to text
|
||||
const callsWithoutImages = createMessageSpyWithoutImages.mock.calls;
|
||||
const historyWithoutImages = callsWithoutImages[0][1][0];
|
||||
expect(historyWithoutImages.content).toHaveLength(2);
|
||||
expect(historyWithoutImages.content[0]).toEqual({ type: 'text', text: 'Here is an image' });
|
||||
expect(historyWithoutImages.content[1]).toEqual({
|
||||
type: 'text',
|
||||
text: '[Referenced image in conversation]'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user