fix(copilot): use upsert in add_chat_messages_batch to handle duplicate sequences

Concurrent writers (incremental streaming saves and long-running tool
callbacks) can race to persist messages with the same (sessionId, sequence)
pair, causing unique constraint violations.

Replace prisma create() with upsert() so duplicate sequences update the
existing row instead of failing. This is safe because later writes always
contain the most complete data (e.g. accumulated assistant text).
This commit is contained in:
Otto
2026-02-20 09:59:45 +00:00
parent fc64f83331
commit 0450ea5313

View File

@@ -170,8 +170,21 @@ async def add_chat_messages_batch(
if msg.get("function_call") is not None:
data["functionCall"] = SafeJson(msg["function_call"])
created = await PrismaChatMessage.prisma(tx).create(
data=cast(ChatMessageCreateInput, data)
# Use upsert to handle concurrent writers (e.g. incremental
# streaming saves racing with long-running tool callbacks) that
# may produce duplicate (sessionId, sequence) pairs.
update_data = {k: v for k, v in data.items() if k != "Session"}
created = await PrismaChatMessage.prisma(tx).upsert(
where={
"sessionId_sequence": {
"sessionId": session_id,
"sequence": start_sequence + i,
}
},
data={
"create": cast(ChatMessageCreateInput, data),
"update": update_data,
},
)
created_messages.append(created)