Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
688 changes: 688 additions & 0 deletions docs/design/web-shell/web-shell-image-drag-and-drop.md

Large diffs are not rendered by default.

109 changes: 56 additions & 53 deletions packages/core/src/core/anthropicContentGenerator/converter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,64 +570,67 @@ describe('AnthropicContentConverter', () => {
});
});

it('renders non-image inlineData as a text block (avoids invalid image media_type)', () => {
const { messages } = converter.convertGeminiRequestToAnthropic({
model: 'models/test',
contents: [
{
role: 'model',
parts: [
{
functionCall: {
id: 'call-1',
name: 'Read',
args: {},
it.each(['audio/mpeg', 'image/bmp'])(
'renders unsupported %s inlineData as a text block',
(mimeType) => {
const { messages } = converter.convertGeminiRequestToAnthropic({
model: 'models/test',
contents: [
{
role: 'model',
parts: [
{
functionCall: {
id: 'call-1',
name: 'Read',
args: {},
},
},
},
],
},
{
role: 'user',
parts: [
{
functionResponse: {
id: 'call-1',
name: 'Read',
response: { output: 'Audio content' },
parts: [
{
inlineData: {
mimeType: 'audio/mpeg',
data: 'base64encodedaudiodata',
],
},
{
role: 'user',
parts: [
{
functionResponse: {
id: 'call-1',
name: 'Read',
response: { output: 'Unsupported content' },
parts: [
{
inlineData: {
mimeType,
data: 'base64encodeddata',
},
},
},
],
],
},
},
},
],
},
],
});
],
},
],
});

expect(messages).toHaveLength(2);
expect(messages[1]?.role).toBe('user');
expect(messages).toHaveLength(2);
expect(messages[1]?.role).toBe('user');

const toolResult = messages[1]?.content?.[0] as {
type: string;
content: Array<{ type: string; text?: string }>;
};
expect(toolResult.type).toBe('tool_result');
expect(Array.isArray(toolResult.content)).toBe(true);
expect(toolResult.content[0]).toEqual({
type: 'text',
text: 'Audio content',
});
expect(toolResult.content[1]?.type).toBe('text');
expect(toolResult.content[1]?.text).toContain(
'Unsupported inline media type',
);
expect(toolResult.content[1]?.text).toContain('audio/mpeg');
});
const toolResult = messages[1]?.content?.[0] as {
type: string;
content: Array<{ type: string; text?: string }>;
};
expect(toolResult.type).toBe('tool_result');
expect(Array.isArray(toolResult.content)).toBe(true);
expect(toolResult.content[0]).toEqual({
type: 'text',
text: 'Unsupported content',
});
expect(toolResult.content[1]?.type).toBe('text');
expect(toolResult.content[1]?.text).toContain(
'Unsupported inline media type',
);
expect(toolResult.content[1]?.text).toContain(mimeType);
},
);

it('converts inlineData with PDF into document block', () => {
const { messages } = converter.convertGeminiRequestToAnthropic({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7391,20 +7391,24 @@ describe('modality filtering', () => {
expect(parts[0].text).toContain('does not support image input');
});

it('keeps image when image modality is enabled', () => {
it('keeps BMP image data when image modality is enabled', () => {
const conv = OpenAIContentConverter;
const request = makeRequest([
{
inlineData: { mimeType: 'image/png', data: 'abc123' },
inlineData: { mimeType: 'image/bmp', data: 'abc123' },
} as unknown as Part,
]);
const messages = conv.convertGeminiRequestToOpenAI(
request,
makeRequestContext('gpt-4o', { image: true }),
);
const parts = getUserContentParts(messages);
const parts = getUserContentParts(messages) as Array<{
type: string;
image_url?: { url: string };
}>;
expect(parts).toHaveLength(1);
expect(parts[0].type).toBe('image_url');
expect(parts[0].image_url?.url).toBe('data:image/bmp;base64,abc123');
});

it('replaces PDF with placeholder when pdf modality is disabled', () => {
Expand Down
6 changes: 6 additions & 0 deletions packages/web-shell/client/App.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,12 @@
color: var(--foreground);
}

.queuedPromptAmbiguity {
color: var(--secondary-foreground);
font-size: 12px;
line-height: 18px;
}

.queuedPrompt + .queuedPrompt {
border-top: 0;
}
Expand Down
Loading
Loading