Fix turn-usage keying: idempotent per request turn id, not messageId
Live smoke exposed two bugs in the turn usage log: - onFinish messages carry no ids (withMessageIds fills copies inside persistTurn), so fresh turns keyed messageId "" — provenance lost. - The SDK coalesces continuation turns into ONE response message (a whole probe conversation lands in a single assistant message), so per-messageId idempotency swallowed every continuation turn's usage. TurnUsage gains id: string (unique per request, the append idempotency key); messageId stays as transcript provenance, taken from the id-filled list. appendTurnUsage dedupes by id; continuation turns with the same messageId each keep their usage.
This commit is contained in:
+4
-3
@@ -80,12 +80,13 @@ function saveMessages(id: string, messages: UIMessage[]): void {
|
||||
}
|
||||
|
||||
/** Append one usage entry to the record's turn log — idempotent per
|
||||
* messageId: abort replays and wake-turn retries persist the same turn
|
||||
* twice; the second append is a no-op. */
|
||||
* turn id: each REQUEST carries its own id, so a replay of the same turn's
|
||||
* persist appends once, while continuation turns (which share a response
|
||||
* message id) each keep their usage. */
|
||||
function appendTurnUsage(id: string, entry: TurnUsage): void {
|
||||
const record = getChat(id);
|
||||
if (!record) throw new Error(`Chat not found: ${id}`);
|
||||
record.turns = record.turns?.some((t) => t.messageId === entry.messageId)
|
||||
record.turns = record.turns?.some((t) => t.id === entry.id)
|
||||
? record.turns
|
||||
: [...(record.turns ?? []), entry];
|
||||
fs.writeFileSync(chatFile(id), JSON.stringify(record, null, "\t"), "utf-8");
|
||||
|
||||
Reference in New Issue
Block a user