Skip to content

fix(voice-call): add persisted store fallback to getCall/getCallByProviderCallId#96802

Closed
ZOOWH wants to merge 1 commit into
openclaw:mainfrom
ZOOWH:fix/96586-voice-call-store-fallback
Closed

fix(voice-call): add persisted store fallback to getCall/getCallByProviderCallId#96802
ZOOWH wants to merge 1 commit into
openclaw:mainfrom
ZOOWH:fix/96586-voice-call-store-fallback

Conversation

@ZOOWH

@ZOOWH ZOOWH commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: voice_call tool get_status returns { found: false } for completed calls once the in-memory call record is evicted, even though the full call record (with transcript) is persisted in the plugin state store.
  • Root cause: CallManager.getCall() and getCallByProviderCallId() only check the in-memory activeCalls / providerCallIdMap — there is no fallback to the persisted call store.
  • Fix: Add getCallFromStore / getCallByProviderCallIdFromStore helpers in store.ts that look up individual call records from the persisted plugin state store, then wire them as fallback paths in CallManager.getCall() / getCallByProviderCallId().
  • What did NOT change: The fix is purely additive — if a call is found in the in-memory active map, the store is never consulted. All existing call sites (get_status, legacy status mode, resolveCallMessageRequest) benefit from the manager-level fallback without any caller-side changes.

Closes #96586

Change Type

  • Bug fix

Scope

  • Integrations (voice-call extension)

Root Cause

In CallManager.getCall() and getCallByProviderCallId(), only the in-memory maps are checked. Calls in completed, failed, no-answer, or busy state are classified as terminal by TerminalStates and are not restored into activeCalls during loadActiveCallsFromStore(). Once the gateway restarts or the manager evicts the call, getCall / getCallByProviderCallId return undefined for those calls, causing get_status to report { found: false }.

Real behavior proof

Behavior addressed: getCall / getCallByProviderCallId now fall back to the persisted plugin state store when a call is not found in the in-memory active maps.

Environment tested: Node 24.13.1 on Linux, node --import tsx calling the real call manager and store helpers from the fix branch.

Steps run after the patch: Created a completed call record, persisted it to the plugin state store via persistCallRecord(), then verified that getCall() and getCallByProviderCallId() find it via store fallback.

Evidence after fix:

=== BEFORE FIX (upstream/main behavior) ===
BEFORE: Looking up completed call in activeCalls (empty — call evicted):
  getCall("call-completed-proof-1") → undefined (BUG: call not found!)
BEFORE: Looking up by providerCallId (empty — call evicted):
  getCallByProviderCallId("CA-proof-provider-1") → undefined (BUG: call not found!)
Verification: call IS persisted in store → found (callId=call-completed-proof-1, state=completed)

=== AFTER FIX (PR branch) ===
AFTER: getCall with store fallback:
  getCall("call-completed-proof-1") → FOUND (callId=call-completed-proof-1, state=completed, endReason=completed)
AFTER: getCallByProviderCallId with store fallback:
  getCallByProviderCallId("CA-proof-provider-1") → FOUND (callId=call-completed-proof-1, providerCallId=CA-proof-provider-1, state=completed)
AFTER: Non-existent call still returns undefined:
  getCall("nonexistent-call") → undefined (correct)

=== VERDICT ===
RESULT: PASS — store fallback correctly falls back to persisted store

Observed result after the fix: Completed calls that have been evicted from the in-memory activeCalls map are now correctly retrieved from the persisted plugin state store. Non-existent calls still return undefined (no false positives).

Not tested: Live voice-call gateway session with real Twilio/Plivo provider webhook and natural call lifecycle. The store fallback path is verified via the real production functions persistCallRecord + getCallFromStore / getCallByProviderCallIdFromStore + getCall / getCallByProviderCallId.

Security Impact

  • New permissions? No
  • Secrets handling changed? No
  • New network calls? No

…viderCallId

When a voice call completes, the call record is evicted from the in-memory
activeCalls map. Subsequent get_status requests return { found: false } despite
the full call record (with transcript) being persisted in the plugin state store.

Add getCallFromStore/getCallByProviderCallIdFromStore lookup helpers in store.ts
and wire them as fallback paths in CallManager.getCall/getCallByProviderCallId.
All existing callers (get_status, status mode, resolveCallMessageRequest) benefit
automatically from the manager-level fallback without caller-side changes.

Closes openclaw#96586
@openclaw-barnacle openclaw-barnacle Bot added channel: voice-call Channel integration: voice-call size: S labels Jun 25, 2026
@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(voice-call): add persisted store fallback to getCall/getCallByProviderCallId This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@ZOOWH

ZOOWH commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Closing — the fix approach is materially identical to #96727. Will find a different issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: voice-call Channel integration: voice-call size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[voice-call] get_status returns found:false for completed calls once evicted from in-memory manager — no fallback to persisted call store

1 participant