




















@@ -37,6 +37,14 @@ function markRestoredCallSkipped(call: CallRecord, endReason: "completed" | "tim
3737call.state = endReason;
3838}
393940+function incrementRestoreStatusCount(
41+counts: Map<string, number>,
42+status: string | undefined,
43+): void {
44+const key = normalizeOptionalString(status) ?? "terminal";
45+counts.set(key, (counts.get(key) ?? 0) + 1);
46+}
47+4048function resolveDefaultStoreBase(config: VoiceCallConfig, storePath?: string): string {
4149const rawOverride = storePath?.trim() || config.store?.trim();
4250if (rawOverride) {
@@ -110,6 +118,7 @@ export class CallManager {
110118}
111119112120// Restart max-duration timers for restored calls that are past the answered state
121+let skippedAlreadyElapsedTimers = 0;
113122for (const [callId, call] of verified) {
114123if (call.answeredAt && !TerminalStates.has(call.state)) {
115124const elapsed = Date.now() - call.answeredAt;
@@ -120,9 +129,7 @@ export class CallManager {
120129if (call.providerCallId) {
121130this.providerCallIdMap.delete(call.providerCallId);
122131}
123-console.log(
124-`[voice-call] Skipping restored call ${callId} (max duration already elapsed)`,
125-);
132+skippedAlreadyElapsedTimers += 1;
126133continue;
127134}
128135startMaxDurationTimer({
@@ -136,6 +143,11 @@ export class CallManager {
136143console.log(`[voice-call] Restarted max-duration timer for restored call ${callId}`);
137144}
138145}
146+if (skippedAlreadyElapsedTimers > 0) {
147+console.log(
148+`[voice-call] Skipped ${skippedAlreadyElapsedTimers} restored call(s) whose max-duration timer already elapsed`,
149+);
150+}
139151140152if (verified.size > 0) {
141153console.log(`[voice-call] Restored ${verified.size} active call(s) from store`);
@@ -159,19 +171,23 @@ export class CallManager {
159171const now = Date.now();
160172const verified = new Map<CallId, CallRecord>();
161173const verifyTasks: Array<{ callId: CallId; call: CallRecord; promise: Promise<void> }> = [];
174+let skippedNoProviderCallId = 0;
175+let skippedOlderThanMaxDuration = 0;
176+const skippedTerminalStatuses = new Map<string, number>();
177+let keptVerifiedActive = 0;
178+let keptUnknownProviderStatus = 0;
179+let keptVerificationFailures = 0;
162180163181for (const [callId, call] of candidates) {
164182// Skip calls without a provider ID — can't verify
165183if (!call.providerCallId) {
166-console.log(`[voice-call] Skipping restored call ${callId} (no providerCallId)`);
184+skippedNoProviderCallId += 1;
167185continue;
168186}
169187170188// Skip calls older than maxDurationSeconds (time-based fallback)
171189if (now - call.startedAt > maxAgeMs) {
172-console.log(
173-`[voice-call] Skipping restored call ${callId} (older than maxDurationSeconds)`,
174-);
190+skippedOlderThanMaxDuration += 1;
175191markRestoredCallSkipped(call, "timeout");
176192persistCallRecord(this.storePath, call);
177193await provider
@@ -196,32 +212,57 @@ export class CallManager {
196212.getCallStatus({ providerCallId: call.providerCallId })
197213.then((result) => {
198214if (result.isTerminal) {
199-console.log(
200-`[voice-call] Skipping restored call ${callId} (provider status: ${result.status})`,
201-);
215+incrementRestoreStatusCount(skippedTerminalStatuses, result.status);
202216markRestoredCallSkipped(call, "completed");
203217persistCallRecord(this.storePath, call);
204218} else if (result.isUnknown) {
205-console.log(
206-`[voice-call] Keeping restored call ${callId} (provider status unknown, relying on timer)`,
207-);
219+keptUnknownProviderStatus += 1;
208220verified.set(callId, call);
209221} else {
222+keptVerifiedActive += 1;
210223verified.set(callId, call);
211224}
212225})
213226.catch(() => {
214227// Verification failed entirely — keep the call, rely on timer
215-console.log(
216-`[voice-call] Keeping restored call ${callId} (verification failed, relying on timer)`,
217-);
228+keptVerificationFailures += 1;
218229verified.set(callId, call);
219230}),
220231};
221232verifyTasks.push(task);
222233}
223234224235await Promise.allSettled(verifyTasks.map((t) => t.promise));
236+if (skippedNoProviderCallId > 0) {
237+console.log(
238+`[voice-call] Skipped ${skippedNoProviderCallId} restored call(s) with no providerCallId`,
239+);
240+}
241+if (skippedOlderThanMaxDuration > 0) {
242+console.log(
243+`[voice-call] Skipped ${skippedOlderThanMaxDuration} restored call(s) older than maxDurationSeconds`,
244+);
245+}
246+for (const [status, count] of [...skippedTerminalStatuses].toSorted(([a], [b]) =>
247+a.localeCompare(b),
248+)) {
249+console.log(`[voice-call] Skipped ${count} restored call(s) with provider status: ${status}`);
250+}
251+if (keptVerifiedActive > 0) {
252+console.log(
253+`[voice-call] Kept ${keptVerifiedActive} restored call(s) confirmed active by provider`,
254+);
255+}
256+if (keptUnknownProviderStatus > 0) {
257+console.log(
258+`[voice-call] Kept ${keptUnknownProviderStatus} restored call(s) with unknown provider status (relying on timer)`,
259+);
260+}
261+if (keptVerificationFailures > 0) {
262+console.log(
263+`[voice-call] Kept ${keptVerificationFailures} restored call(s) after verification failure (relying on timer)`,
264+);
265+}
225266return verified;
226267}
227268此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。