fix(cursor): avoid empty user turns after tool results

This commit is contained in:
Tam Nhu Tran
2026-03-16 14:42:15 -04:00
parent daad5d1f50
commit b068fb2621
2 changed files with 33 additions and 1 deletions
+3 -1
View File
@@ -102,6 +102,7 @@ export function translateAnthropicRequest(raw: unknown): TranslatedAnthropicRequ
const textParts: string[] = [];
const toolCalls: NonNullable<CursorOpenAIMessage['tool_calls']> = [];
let sawToolResult = false;
content.forEach((block, blockIndex) => {
const parsed = assertObject(
@@ -140,6 +141,7 @@ export function translateAnthropicRequest(raw: unknown): TranslatedAnthropicRequ
`messages[${messageIndex}].content[${blockIndex}] tool_result requires user role`
);
}
sawToolResult = true;
translatedMessages.push({
role: 'tool',
tool_call_id: typeof parsed.tool_use_id === 'string' ? parsed.tool_use_id : '',
@@ -165,7 +167,7 @@ export function translateAnthropicRequest(raw: unknown): TranslatedAnthropicRequ
return;
}
if (textParts.length > 0 || toolCalls.length === 0) {
if (textParts.length > 0 || !sawToolResult) {
translatedMessages.push({
role,
content: textParts.join('\n'),
@@ -59,6 +59,36 @@ describe('translateAnthropicRequest', () => {
})
).toThrow('is not supported');
});
it('does not append an empty user message after tool_result-only turns', () => {
const translated = translateAnthropicRequest({
messages: [
{
role: 'assistant',
content: [{ type: 'tool_use', id: 'toolu_1', name: 'search', input: { q: 'x' } }],
},
{
role: 'user',
content: [{ type: 'tool_result', tool_use_id: 'toolu_1', content: 'done' }],
},
],
});
expect(translated.messages).toEqual([
{
role: 'assistant',
content: '',
tool_calls: [
{
id: 'toolu_1',
type: 'function',
function: { name: 'search', arguments: '{"q":"x"}' },
},
],
},
{ role: 'tool', tool_call_id: 'toolu_1', content: 'done' },
]);
});
});
describe('createAnthropicProxyResponse', () => {