# Build a Personal Assistant That Continues from Phone to Desktop

Design a phone\-to\-desktop assistant handoff with confirmed trip context, authenticated resume, fresh calls, and safeguards against stale device commands\.

Published: 2026-10-12T15:04:23.773Z
Updated: 2026-10-12T15:04:23.773Z
Canonical: https://realtimeavatar.ai/blog/personal-assistant-phone-to-desktop-handoff
Markdown: [en](https://realtimeavatar.ai/blog/personal-assistant-phone-to-desktop-handoff.md)

Move the task, not the live connection. Save user-confirmed trip details in your application, authenticate the desktop resume request, and start a fresh avatar call with server-selected context. Retire the phone's authority separately from ending its media session. This preserves the useful plan without pretending Bluetooth, a shared account, or Realtime Avatar automatically transfers a conversation between devices.

## One trip, two different interfaces

On a walk, a traveler uses your app's voice call through earbuds to discuss a weekend away. They confirm departure city, exact dates, two travelers, and a total budget with currency. At home, they explicitly open your desktop app to compare train times and hotel cancellation terms. The avatar can explain the tradeoffs while the application shows the options.

Google's Pixel Buds page describes hands-free Gemini Live conversations. Its Gemini Live page describes switching between voice and typing within a conversation. These are useful examples of changing interaction modes, not evidence of a Pixel-to-Realtime-Avatar integration or a cross-vendor handoff protocol. Here, both device experiences belong to your application.

- [Google Pixel Buds Pro 2: hands-free Gemini Live](https://store.google.com/product/pixel_buds_pro_2?hl=en-US)
- [Google Gemini Live: voice and typing](https://gemini.google/overview/gemini-live/)

## Save a travel decision, not an assumed transcript

Keep confirmed requirements separate from conversation. A task snapshot should distinguish the agreed dates and budget from unresolved questions such as whether a late return is acceptable. Record its version and confirmation time. An assistant's suggestion is not a traveler-approved requirement, and a misheard amount must remain unconfirmed.

Persist confirmations through your authenticated application tools while the phone call is active. Realtime Avatar's optional signed transcript arrives after a call; it is not a guaranteed live handover feed. If the latest detail was never saved, show the last confirmed snapshot and ask again. Keep saved options as references with retrieval times, then refresh external prices and availability on desktop.

## Make resume an authenticated transaction

Offer Continue on desktop on the phone and a pending-trip entry in the signed-in desktop app. Use a short-lived, opaque, single-use resume handle. Keep it in an authenticated response and submit it in a POST body, not a URL. Do not put transcripts, provider credentials, or session grants in links, QR codes, or analytics events. The handle locates a request; possession alone never authorizes it.

1. After desktop sign-in, show a minimal trip label and ask the user to continue here. Bind the resume request to that authenticated account and destination app session.
2. On redemption, check expiry, ownership, current permissions, and the expected task version. Reject a changed plan for review rather than silently resuming an older snapshot. Protect the mutation against cross-site request forgery and rate-limit failed attempts.
3. In one application-store transaction, consume the handle and advance the task's active-device generation. Concurrent redemptions must have one winner. Return an existing authorized transfer status on retries, not another live grant.
4. Resolve the approved snapshot on the server and mint a new Realtime Avatar call with its own identity. Supply behavior through instructions and relevant context through context. Never copy the phone's connection credentials to the desktop.

Keep the trip identity stable while correlating both distinct call identities with the transfer. If the new mint fails, retain the saved plan and show a retry or text-only comparison. Do not silently restore the retired phone's authority. This transaction governs your database, not an atomic change across your database and the media service.

## End the old call without inventing certainty

Ask the phone client to end its call, and have your server request release of the old session. The documented rta.endCall method is best-effort and idempotent: true means acknowledged; false leaves the outcome unknown. Record that distinction. An acknowledgement is not proof that a disconnected phone has updated its microphone indicator.

Set a bounded maxSeconds policy when each call starts so an unreachable client cannot leave it open indefinitely. Track local capture cleanup separately from server release. If closure is uncertain, show that warning and keep desktop comparison silent until the user explicitly chooses to start audio. Never report that the phone stopped listening merely because desktop video appeared.

- [Realtime Avatar Calls: context, hard stops, and server release](https://realtimeavatar.ai/docs/sessions)

## Fence stale commands at your application tools

Two devices can remain connected even when only one may edit the trip. Bind each authenticated call to the generation your server assigned; never trust a client to claim the newest generation. Check that binding at the write boundary. An old phone's delayed instruction to change the destination must fail after desktop takeover, not overwrite the comparison.

Application pseudocode follows. These are design steps for your own transactional store, not Realtime Avatar SDK methods.

```
APPLICATION PSEUDOCODE
transaction:
  resolve authenticated call binding and authorized trip
  require current permission to read the operation outcome
  if an operation receipt exists:
    require receipt owner, trip and arguments match this request
    return existing receipt without executing another write
  require binding.generation == trip.activeGeneration
  require proposedChange.baseVersion == trip.version
  require current permission to edit this trip
  enforce unique operation ID for this owner and trip
  apply confirmed change and advance trip version
  persist operation receipt
commit
```

Make the checks and write atomic. Mark the phone view as read-only after takeover; another takeover requires another explicit confirmation. Tool abort is cooperative, and Realtime Avatar's tool deadline is 2.5 seconds. Neither cancels an external action already dispatched. Keep this first handover flow read-only toward travel providers, and discard stale lookup results instead of letting them replace newer options.

## Respect the room around the user

Switching Bluetooth output changes an audio route, not application identity or task ownership. Test earbud disconnects explicitly; do not assume private playback continues. Avoid speaking names, booking references, or sensitive details during transition. On desktop, show the plan before starting sound and ask before enabling the microphone. Mount the call only after the user's start action; the React integration begins connecting when mounted.

## Failure tests for the transfer boundary

- Replay a handle, expire it, and redeem it from another account. No case may disclose the trip or mint a call.
- Resume from two desktop tabs simultaneously. Only one acquires editing authority; the other shows current transfer status.
- Delay a phone edit until after desktop takeover. The server rejects its old generation, including when the phone reconnects.
- Lose the release response and fail desktop mint. Preserve the plan, label phone closure unknown, and offer an explicit retry without restoring stale authority.
- Change a provider price between devices and disconnect earbuds during speech. Refresh the quote and test the actual audio route; neither cached prices nor transport state prove the user saw or heard the right thing.

## Frequently asked questions

### Does Realtime Avatar migrate the phone session?

No native device-handoff mechanism is documented here. Your application restores an authorized task snapshot into a new call. It owns authentication, memory, tools, and transfer coordination.

### Can both devices stay open?

Yes, as an application design: keep one active editor and make the other view read-only. Opening a second screen must not silently grant it microphone access or command authority.

### Can I pipe Gemini or another assistant's live audio into the avatar?

The public SDK does not accept arbitrary external live audio input. Realtime Avatar manages speech recognition, the language model, speech synthesis, and video. External model endpoints require approval and host allowlisting.

### Must desktop continuation include video?

No. Offer your application's comparison screen without a call. Add an optional avatar when an explanation helps; continuing a task should not require broadcasting a private conversation.

## Build the smallest honest handover

Start with one confirmed trip, one authenticated resume, and one fresh call. Prove stale commands are rejected before adding booking actions. Use the quickstart for the call integration, not as a substitute for transfer authorization.

- [Build your first call with the Realtime Avatar quickstart](https://realtimeavatar.ai/docs/quickstart)
- [Read the application-owned tool boundary](https://realtimeavatar.ai/docs/tool-calling)
- [Control when React and Native calls start](https://realtimeavatar.ai/docs/react)
