refactor(llm): share user message coalescing

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
This commit is contained in:
chrarnoldus
2026-08-21 08:44:44 +00:00
parent 705f6b7dad
commit 406c1910b1
4 changed files with 33 additions and 36 deletions
@@ -415,10 +415,7 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (
}
const part = yield* ProviderShared.wrappedSystemUpdate("Anthropic Messages", message)
const block = { type: "text" as const, text: part.text, cache_control: cacheControl(breakpoints, part.cache) }
const previous = messages.at(-1)
if (previous?.role === "user")
messages[messages.length - 1] = { role: "user", content: [...previous.content, block] }
else messages.push({ role: "user", content: [block] })
ProviderShared.appendUserMessage(messages, { role: "user", content: [block] }) // kilocode_change
continue
}
@@ -435,10 +432,7 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (
}
return yield* ProviderShared.unsupportedContent("Anthropic Messages", "user", ["text", "media"])
}
const previous = messages.at(-1) // kilocode_change
if (previous?.role === "user") // kilocode_change
messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] } // kilocode_change
else messages.push({ role: "user", content }) // kilocode_change
ProviderShared.appendUserMessage(messages, { role: "user", content }) // kilocode_change
continue
}
@@ -485,10 +479,7 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (
cache_control: cacheControl(breakpoints, part.cache),
})
}
const previous = messages.at(-1) // kilocode_change
if (previous?.role === "user") // kilocode_change
messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] } // kilocode_change
else messages.push({ role: "user", content }) // kilocode_change
ProviderShared.appendUserMessage(messages, { role: "user", content }) // kilocode_change
}
return messages
+3 -12
View File
@@ -309,10 +309,7 @@ const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* (
if (message.role === "system") {
const part = yield* ProviderShared.wrappedSystemUpdate("Bedrock Converse", message)
const content = textWithCache(breakpoints, part.text, part.cache)
const previous = messages.at(-1)
if (previous?.role === "user")
messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] }
else messages.push({ role: "user", content })
ProviderShared.appendUserMessage(messages, { role: "user", content }) // kilocode_change
continue
}
@@ -330,10 +327,7 @@ const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* (
continue
}
}
const previous = messages.at(-1) // kilocode_change
if (previous?.role === "user") // kilocode_change
messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] } // kilocode_change
else messages.push({ role: "user", content }) // kilocode_change
ProviderShared.appendUserMessage(messages, { role: "user", content }) // kilocode_change
continue
}
@@ -375,10 +369,7 @@ const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* (
const cachePoint = BedrockCache.block(breakpoints, part.cache)
if (cachePoint) content.push(cachePoint)
}
const previous = messages.at(-1) // kilocode_change
if (previous?.role === "user") // kilocode_change
messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] } // kilocode_change
else messages.push({ role: "user", content }) // kilocode_change
ProviderShared.appendUserMessage(messages, { role: "user", content }) // kilocode_change
}
return messages
+3 -12
View File
@@ -208,10 +208,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
for (const message of request.messages) {
if (message.role === "system") {
const part = yield* ProviderShared.wrappedSystemUpdate("Gemini", message)
const previous = contents.at(-1)
if (previous?.role === "user")
contents[contents.length - 1] = { role: "user", parts: [...previous.parts, { text: part.text }] }
else contents.push({ role: "user", parts: [{ text: part.text }] })
ProviderShared.appendUserMessage(contents, { role: "user", parts: [{ text: part.text }] }) // kilocode_change
continue
}
@@ -222,10 +219,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
return yield* ProviderShared.unsupportedContent("Gemini", "user", ["text", "media"])
parts.push(yield* lowerUserPart(part))
}
const previous = contents.at(-1) // kilocode_change
if (previous?.role === "user") // kilocode_change
contents[contents.length - 1] = { role: "user", parts: [...previous.parts, ...parts] } // kilocode_change
else contents.push({ role: "user", parts }) // kilocode_change
ProviderShared.appendUserMessage(contents, { role: "user", parts }) // kilocode_change
continue
}
@@ -284,10 +278,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
parts.push({ inlineData: { mimeType: media.mime, data: media.base64 } })
}
}
const previous = contents.at(-1) // kilocode_change
if (previous?.role === "user") // kilocode_change
contents[contents.length - 1] = { role: "user", parts: [...previous.parts, ...parts] } // kilocode_change
else contents.push({ role: "user", parts }) // kilocode_change
ProviderShared.appendUserMessage(contents, { role: "user", parts }) // kilocode_change
}
return contents
+24
View File
@@ -108,6 +108,30 @@ export const parseJson = (route: string, input: string, message: string) =>
*/
export const joinText = (parts: ReadonlyArray<{ readonly text: string }>) => parts.map((part) => part.text).join("\n")
// kilocode_change start - preserve provider role alternation when tool results lower to user messages
type UserMessage =
| { readonly role: "user"; readonly content: ReadonlyArray<unknown> }
| { readonly role: "user"; readonly parts: ReadonlyArray<unknown> }
export const appendUserMessage = <Message extends { readonly role: string }, User extends Message & UserMessage>(
messages: Message[],
message: User,
) => {
const previous = messages.at(-1)
if (previous?.role !== "user") {
messages.push(message)
return
}
if ("content" in message) {
const content = (previous as { readonly content: ReadonlyArray<unknown> }).content
messages[messages.length - 1] = { ...message, content: [...content, ...message.content] }
return
}
const parts = (previous as { readonly parts: ReadonlyArray<unknown> }).parts
messages[messages.length - 1] = { ...message, parts: [...parts, ...message.parts] }
}
// kilocode_change end
const escapeSystemUpdateText = (text: string) =>
text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;")