fix(ai): isolate Gemini function-response turns (#43479)
Signed-off-by: Major Hayden <major@mhtx.net>
This commit is contained in:
@@ -289,7 +289,9 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
|
||||
if (message.role === "system") {
|
||||
const part = yield* ProviderShared.wrappedSystemUpdate("Gemini", message)
|
||||
const previous = contents.at(-1)
|
||||
if (previous?.role === "user")
|
||||
// Gemini rejects a continuation whose function-response turn carries extra
|
||||
// parts, so an update after a tool result starts its own user turn.
|
||||
if (previous?.role === "user" && !previous.parts.some((item) => "functionResponse" in item))
|
||||
contents[contents.length - 1] = { role: "user", parts: [...previous.parts, { text: part.text }] }
|
||||
else contents.push({ role: "user", parts: [{ text: part.text }] })
|
||||
continue
|
||||
|
||||
@@ -139,6 +139,48 @@ describe("Gemini route", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("keeps system updates separate from function responses", () =>
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model,
|
||||
messages: [
|
||||
Message.assistant([ToolCallPart.make({ id: "call_1", name: "lookup", input: { query: "weather" } })]),
|
||||
Message.tool({ id: "call_1", name: "lookup", result: "done", resultType: "text" }),
|
||||
Message.system("Update."),
|
||||
Message.system("Later update."),
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
expect(prepared.body.contents).toEqual([
|
||||
{
|
||||
role: "model",
|
||||
parts: [{ functionCall: { id: undefined, name: "lookup", args: { query: "weather" } } }],
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
parts: [
|
||||
{
|
||||
functionResponse: {
|
||||
id: undefined,
|
||||
name: "lookup",
|
||||
response: { name: "lookup", content: "done" },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
parts: [
|
||||
{ text: "<system-update>\nUpdate.\n</system-update>" },
|
||||
{ text: "<system-update>\nLater update.\n</system-update>" },
|
||||
],
|
||||
},
|
||||
])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("prepares multimodal user input and tool history", () =>
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
|
||||
Reference in New Issue
Block a user