fix(ts): handle empty Google chat candidates (#5817)
This commit is contained in:
@@ -11,12 +11,8 @@ export class GoogleLLM implements LLM {
|
|||||||
this.model = config.model || "gemini-2.0-flash";
|
this.model = config.model || "gemini-2.0-flash";
|
||||||
}
|
}
|
||||||
|
|
||||||
async generateResponse(
|
private formatContents(messages: Message[]) {
|
||||||
messages: Message[],
|
return messages.map((msg) => ({
|
||||||
responseFormat?: { type: string },
|
|
||||||
tools?: any[],
|
|
||||||
): Promise<string | LLMResponse> {
|
|
||||||
const contents = messages.map((msg) => ({
|
|
||||||
parts: [
|
parts: [
|
||||||
{
|
{
|
||||||
text:
|
text:
|
||||||
@@ -27,6 +23,14 @@ export class GoogleLLM implements LLM {
|
|||||||
],
|
],
|
||||||
role: msg.role === "system" ? "model" : "user",
|
role: msg.role === "system" ? "model" : "user",
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateResponse(
|
||||||
|
messages: Message[],
|
||||||
|
responseFormat?: { type: string },
|
||||||
|
tools?: any[],
|
||||||
|
): Promise<string | LLMResponse> {
|
||||||
|
const contents = this.formatContents(messages);
|
||||||
|
|
||||||
// Build config with tools if provided
|
// Build config with tools if provided
|
||||||
const config: Record<string, any> = {};
|
const config: Record<string, any> = {};
|
||||||
@@ -69,13 +73,18 @@ export class GoogleLLM implements LLM {
|
|||||||
|
|
||||||
async generateChat(messages: Message[]): Promise<LLMResponse> {
|
async generateChat(messages: Message[]): Promise<LLMResponse> {
|
||||||
const completion = await this.google.models.generateContent({
|
const completion = await this.google.models.generateContent({
|
||||||
contents: messages,
|
contents: this.formatContents(messages),
|
||||||
model: this.model,
|
model: this.model,
|
||||||
});
|
});
|
||||||
const response = completion.candidates![0].content;
|
const response = completion.candidates?.[0]?.content;
|
||||||
|
const content =
|
||||||
|
response?.parts?.map((part) => part.text || "").join("") ||
|
||||||
|
completion.text ||
|
||||||
|
"";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: response!.parts![0].text || "",
|
content,
|
||||||
role: response!.role!,
|
role: response?.role || "assistant",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,4 +184,45 @@ describe("GoogleLLM (unit)", () => {
|
|||||||
expect(response.toolCalls[0].name).toBe("add_graph_memory");
|
expect(response.toolCalls[0].name).toBe("add_graph_memory");
|
||||||
expect(response.toolCalls[1].name).toBe("add_graph_memory");
|
expect(response.toolCalls[1].name).toBe("add_graph_memory");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("formats generateChat messages and joins Gemini response parts", async () => {
|
||||||
|
mockGenerateContent.mockResolvedValueOnce({
|
||||||
|
candidates: [
|
||||||
|
{
|
||||||
|
content: {
|
||||||
|
role: "model",
|
||||||
|
parts: [{ text: "Hello" }, { text: ", world" }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const llm = new GoogleLLM({ apiKey: "test-key" });
|
||||||
|
const result = await llm.generateChat([
|
||||||
|
{ role: "system", content: "Be concise" },
|
||||||
|
{ role: "user", content: "Say hello" },
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(mockGenerateContent).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
contents: [
|
||||||
|
{ role: "model", parts: [{ text: "Be concise" }] },
|
||||||
|
{ role: "user", parts: [{ text: "Say hello" }] },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(result).toEqual({ content: "Hello, world", role: "model" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns an empty assistant response when generateChat has no candidates", async () => {
|
||||||
|
mockGenerateContent.mockResolvedValueOnce({
|
||||||
|
candidates: [],
|
||||||
|
text: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const llm = new GoogleLLM({ apiKey: "test-key" });
|
||||||
|
const result = await llm.generateChat([{ role: "user", content: "Hi" }]);
|
||||||
|
|
||||||
|
expect(result).toEqual({ content: "", role: "assistant" });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user