


































@@ -107,6 +107,8 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar
107107assistantTextBaseline: 0,
108108suppressBlockChunks: false, // Avoid late chunk inserts after final text merge.
109109lastReasoningSent: undefined,
110+pendingAssistantUsage: undefined,
111+assistantUsageCommitted: false,
110112compactionInFlight: false,
111113pendingCompactionRetry: 0,
112114compactionRetryResolve: undefined,
@@ -212,6 +214,8 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar
212214state.lastReasoningSent = undefined;
213215state.reasoningStreamOpen = false;
214216state.suppressBlockChunks = false;
217+state.pendingAssistantUsage = undefined;
218+state.assistantUsageCommitted = false;
215219state.assistantMessageIndex += 1;
216220state.lastAssistantStreamItemId = undefined;
217221state.lastAssistantTextMessageIndex = -1;
@@ -352,11 +356,42 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar
352356const maybeResolveCompactionWait = () => {
353357resolveCompactionPromiseIfIdle();
354358};
355-const recordAssistantUsage = (usageLike: unknown) => {
356-const usage = normalizeUsage((usageLike ?? undefined) as UsageLike | undefined);
357-if (!hasNonzeroUsage(usage)) {
359+const resolveAssistantUsage = (usageLike: unknown) => {
360+const candidates: unknown[] = [usageLike];
361+if (usageLike && typeof usageLike === "object") {
362+const record = usageLike as Record<string, unknown>;
363+const partial =
364+record.partial && typeof record.partial === "object"
365+ ? (record.partial as Record<string, unknown>)
366+ : undefined;
367+const message =
368+record.message && typeof record.message === "object"
369+ ? (record.message as Record<string, unknown>)
370+ : undefined;
371+candidates.push(
372+record.usage,
373+record.timings,
374+record.partial,
375+record.message,
376+partial?.usage,
377+partial?.timings,
378+message?.usage,
379+message?.timings,
380+);
381+}
382+for (const candidate of candidates) {
383+const usage = normalizeUsage((candidate ?? undefined) as UsageLike | undefined);
384+if (hasNonzeroUsage(usage)) {
385+return usage;
386+}
387+}
388+return undefined;
389+};
390+const commitAssistantUsage = () => {
391+if (state.assistantUsageCommitted || !state.pendingAssistantUsage) {
358392return;
359393}
394+const usage = state.pendingAssistantUsage;
360395usageTotals.input += usage.input ?? 0;
361396usageTotals.output += usage.output ?? 0;
362397usageTotals.cacheRead += usage.cacheRead ?? 0;
@@ -365,6 +400,17 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar
365400usage.total ??
366401(usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
367402usageTotals.total += usageTotal;
403+state.assistantUsageCommitted = true;
404+};
405+const recordAssistantUsage = (usageLike: unknown) => {
406+if (state.assistantUsageCommitted) {
407+return;
408+}
409+const usage = resolveAssistantUsage(usageLike);
410+if (!usage) {
411+return;
412+}
413+state.pendingAssistantUsage = usage;
368414};
369415const getUsageTotals = () => {
370416const hasUsage =
@@ -759,6 +805,7 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar
759805 resolveCompactionRetry,
760806 maybeResolveCompactionWait,
761807 recordAssistantUsage,
808+ commitAssistantUsage,
762809 incrementCompactionCount,
763810 getUsageTotals,
764811getCompactionCount: () => compactionCount,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。