The first-round title guard compared the pre-RPC snapshot, so append_consultation_question had already rewritten the title and the model name never landed. Co-authored-by: Cursor <cursoragent@cursor.com>
41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
type GuardedTitleUpdate = {
|
|
eq: (column: string, value: string) => GuardedTitleUpdate;
|
|
select: (columns: "id") => PromiseLike<{ data: Array<{ id?: string }> | null; error: unknown }>;
|
|
};
|
|
|
|
export type GuardedTitleClient = {
|
|
from: (table: "chat_sessions") => {
|
|
update: (values: { title: string }) => GuardedTitleUpdate;
|
|
};
|
|
};
|
|
|
|
export async function persistGuardedSessionTitle(input: {
|
|
client: GuardedTitleClient;
|
|
sessionId: string;
|
|
userId: string;
|
|
expectedTitle: string;
|
|
title: string;
|
|
warn?: (message: string, extra?: unknown) => void;
|
|
}): Promise<"updated" | "missed" | "failed"> {
|
|
const warn = input.warn ?? ((message: string, extra?: unknown) => console.warn(message, extra));
|
|
try {
|
|
const { data, error } = await input.client.from("chat_sessions").update({ title: input.title })
|
|
.eq("id", input.sessionId)
|
|
.eq("user_id", input.userId)
|
|
.eq("title", input.expectedTitle)
|
|
.select("id");
|
|
if (error) {
|
|
warn("session title persist failed", error);
|
|
return "failed";
|
|
}
|
|
if (!data?.length) {
|
|
warn("session title guard missed");
|
|
return "missed";
|
|
}
|
|
return "updated";
|
|
} catch (error) {
|
|
warn("session title persist failed", error);
|
|
return "failed";
|
|
}
|
|
}
|