fix(ts-oss/anthropic): find the text block in no-tools responses (#6506)
This commit is contained in:
@@ -100,12 +100,16 @@ export class AnthropicLLM implements LLM {
|
||||
return { content, role: "assistant", toolCalls };
|
||||
}
|
||||
|
||||
const firstBlock = response.content[0];
|
||||
if (firstBlock.type === "text") {
|
||||
return firstBlock.text;
|
||||
} else {
|
||||
throw new Error("Unexpected response type from Anthropic API");
|
||||
// Thinking-enabled responses put a thinking block before the text block,
|
||||
// and a response can carry no text block at all, so find the text block
|
||||
// like the tools branch above instead of indexing content[0]. Mirrors the
|
||||
// Python provider (#6481).
|
||||
for (const block of response.content) {
|
||||
if (block.type === "text") {
|
||||
return block.text;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async generateChat(messages: Message[]): Promise<LLMResponse> {
|
||||
|
||||
@@ -72,6 +72,37 @@ describe("AnthropicLLM (unit)", () => {
|
||||
expect(callArgs.tool_choice).toBeUndefined();
|
||||
});
|
||||
|
||||
// Regression: thinking-enabled models emit a thinking block before the text
|
||||
// block. Indexing content[0] threw "Unexpected response type"; the text block
|
||||
// must be found by type instead (TS parity with #6481).
|
||||
it("returns the text block when a thinking block precedes it (no tools)", async () => {
|
||||
mockCreate.mockResolvedValueOnce({
|
||||
content: [
|
||||
{ type: "thinking", thinking: "Let me reason about this." },
|
||||
{ type: "text", text: '{"facts": ["fact1"]}' },
|
||||
],
|
||||
});
|
||||
|
||||
const llm = new AnthropicLLM({ apiKey: "test-key" });
|
||||
const result = await llm.generateResponse([
|
||||
{ role: "user", content: "Hello" },
|
||||
]);
|
||||
|
||||
expect(result).toBe('{"facts": ["fact1"]}');
|
||||
});
|
||||
|
||||
// A response carrying no text block at all must resolve to "" rather than throw.
|
||||
it("returns an empty string when no text block is present (no tools)", async () => {
|
||||
mockCreate.mockResolvedValueOnce({
|
||||
content: [{ type: "thinking", thinking: "Thinking only." }],
|
||||
});
|
||||
|
||||
const llm = new AnthropicLLM({ apiKey: "test-key" });
|
||||
await expect(
|
||||
llm.generateResponse([{ role: "user", content: "Hello" }]),
|
||||
).resolves.toBe("");
|
||||
});
|
||||
|
||||
// Bug #1 regression: bare string "auto" must NOT be sent; object form required
|
||||
it("forwards tool_choice as { type: 'auto' } (not bare string) when tools are provided", async () => {
|
||||
mockCreate.mockResolvedValueOnce({
|
||||
|
||||
Reference in New Issue
Block a user