diff --git a/docs/ai-chat/background-injection.mdx b/docs/ai-chat/background-injection.mdx index f559373881..567da627f1 100644 --- a/docs/ai-chat/background-injection.mdx +++ b/docs/ai-chat/background-injection.mdx @@ -154,7 +154,7 @@ export const myChat = chat.agent({ }); ``` -The self-review runs on `gpt-4o-mini` (fast, cheap) in the background. If the user sends another message before it completes, the coaching is still injected — `chat.inject()` persists across the idle wait. +The self-review runs on `claude-haiku-4-5` (fast, cheap) in the background. If the user sends another message before it completes, the coaching is still injected — `chat.inject()` persists across the idle wait. ## Other use cases diff --git a/docs/ai-chat/lifecycle-hooks.mdx b/docs/ai-chat/lifecycle-hooks.mdx index 4867067082..c6ea62cbc8 100644 --- a/docs/ai-chat/lifecycle-hooks.mdx +++ b/docs/ai-chat/lifecycle-hooks.mdx @@ -412,15 +412,18 @@ Fires after each turn completes, after the response is captured and the stream i export const myChat = chat.agent({ id: "my-chat", onTurnComplete: async ({ chatId, uiMessages, runId, chatAccessToken, lastEventId }) => { - await db.chat.update({ - where: { id: chatId }, - data: { messages: uiMessages }, - }); - await db.chatSession.upsert({ - where: { id: chatId }, - create: { id: chatId, runId, publicAccessToken: chatAccessToken, lastEventId }, - update: { runId, publicAccessToken: chatAccessToken, lastEventId }, - }); + // Atomic write — see Database persistence for the race-condition rationale + await db.$transaction([ + db.chat.update({ + where: { id: chatId }, + data: { messages: uiMessages }, + }), + db.chatSession.upsert({ + where: { id: chatId }, + create: { id: chatId, runId, publicAccessToken: chatAccessToken, lastEventId }, + update: { runId, publicAccessToken: chatAccessToken, lastEventId }, + }), + ]); }, run: async ({ messages, signal }) => { return streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal }); diff --git a/docs/ai-chat/patterns/database-persistence.mdx b/docs/ai-chat/patterns/database-persistence.mdx index d7cfc10aa0..5ee32f8a6b 100644 --- a/docs/ai-chat/patterns/database-persistence.mdx +++ b/docs/ai-chat/patterns/database-persistence.mdx @@ -258,16 +258,19 @@ export const myChat = chat.agent({ }); }, onTurnComplete: async ({ chatId, uiMessages, runId, chatAccessToken, lastEventId }) => { - // Persist assistant response + stream position - await db.chat.update({ - where: { id: chatId }, - data: { messages: uiMessages }, - }); - await db.chatSession.upsert({ - where: { id: chatId }, - create: { id: chatId, runId, publicAccessToken: chatAccessToken, lastEventId }, - update: { runId, publicAccessToken: chatAccessToken, lastEventId }, - }); + // Persist assistant response + stream position atomically — see the + // race-condition warning earlier on this page. + await db.$transaction([ + db.chat.update({ + where: { id: chatId }, + data: { messages: uiMessages }, + }), + db.chatSession.upsert({ + where: { id: chatId }, + create: { id: chatId, runId, publicAccessToken: chatAccessToken, lastEventId }, + update: { runId, publicAccessToken: chatAccessToken, lastEventId }, + }), + ]); }, run: async ({ messages, signal }) => { return streamText({