← Insider Cat

Codex provides Voice.
OpenHands does the work.

Source reviewed · Draft integration · Last recorded live checks: 26 October

Voice is another way to talk to a saved Insider Cat. The OpenHands conversation owns the requests, tools, approvals, and answers. Codex supplies the authenticated audio connection; Agent Server passes each received handoff directly to that same Cat.

This describes the current feature branches, including Agent Server draft PR #5180 and Canvas draft PR #17558. It is not a claim that the integration is released or running on a particular server.

One call, one saved Cat

Talk starts a WebRTC connection after microphone permission. The call is bound to one eligible, top-level Insider conversation on one backend. Opening that Cat in the regular Canvas view keeps the same conversation and active call. Selecting work on the Projects board does not move execution into the selected worker. The selection is included with typed messages; Codex Voice does not automatically receive it.

  1. Voice hands over the request. Codex emits a handoff_request containing a handoff ID and the spoken request. The browser does not submit that transcript a second time.
  2. Agent Server saves and runs it. The server validates the handoff, checks that the Cat can accept work, and calls send_message(run=True) on the bound OpenHands conversation.
  3. The Cat uses its tools. Its normal model, workspace, skills, and approval policy govern execution. The bridge waits for the run to settle, including stop hooks.
  4. Voice speaks the saved answer. The server selects the new answer associated with this request and sends it through thread/realtime/appendSpeech. Acceptance or a running status is not a completed answer.

The ephemeral Codex thread has no dispatch tool or independent task role. It starts with dynamicTools: [] and restricted tool sources. The direct handoff needs no second reasoning model to decide whether to call ask_agent or send_to_insider.

Voice is instructed to hand over every new conversational request, including greetings and recall questions. It must still emit that handoff: plausible speech by itself does not prove that OpenHands received anything. Inspect the saved conversation for the request and result.

Source: call setup, handoff admission, execution, and answer selection.

Tools belong to the OpenHands Cat

A newly created Cat inherits the active OpenHands agent profile. Its default tool set includes terminal, file editor, task tracker, and model switching, plus browser tools when the runtime supports them. A custom profile can restrict that set or deliberately create a bare agent. Voice does not add missing tools. Resuming a Cat keeps its saved configuration; selecting a different profile does not silently replace it.

Skills follow the same normal launch path: discovered user and public skills, plus project skills loaded for the workspace. The profile can select public skills and disable named skills. The App does not hard-code a skill count or override that selection.

For a backend question, the Cat can use the OpenHands API skill and terminal with the owning server’s runtime context. An authoritative conversation count comes from GET /api/conversations/count; a list must be paginated. Skills explain how to work with available tools. They do not grant permissions or create credentials.

Approval still happens in the saved OpenHands conversation. If an action needs confirmation, open that conversation and review it there. Voice cannot approve it or announce an approval pause as successful completion.

Source: profile tool and skill selection, profile resolution and project skills.

Two transports, separate authentication

TransportServer setupRequest handoff
Codex VoiceOH_VOICE_PROVIDER=codex; a dedicated Codex home, a ChatGPT-authenticated account, and the supported codex-cli 0.154.0 executable.Agent Server receives the Codex V3 handoff and runs the saved Cat directly. Canvas polls call status.
OpenAI Realtime APIThe default openai provider; an OpenAI API key held by Agent Server.Voice calls send_to_insider through the browser bridge. The session also exposes end_voice_call.

Codex Voice uses its own authenticated app-server path. The public Realtime API path still requires an API key. The recorded Codex call worked with an authorized existing ChatGPT sign-in; that observation does not establish access or billing terms for every account.

Set OH_CODEX_VOICE_HOME to a dedicated sign-in directory, separate from the ordinary Codex home. The broker checks the executable version, requires a ChatGPT account, and rejects enabled MCP servers. Its temporary thread is read-only, has no tool approvals, and disables other tool sources. Those restrictions apply to the audio bridge; the saved OpenHands Cat retains its own tools and approval policy.

The Voice model and the Cat’s reasoning model are separate. This bridge does not select a named Codex audio model or provide an arbitrary-model selector. An unsupported executable, unavailable account, or failed connection leaves typed conversation available.

Source: restricted process configuration, version and account checks, provider selection and API transport.

Resume and condense

Each call starts a fresh, ephemeral Codex thread with a bounded snapshot of the saved Cat’s active context. It includes summaries, user and assistant messages, and final answers: at most the last 40 blocks and 12,000 characters. It follows condensation and excludes abandoned branches. It is history to help Voice understand the conversation, not a second permanent conversation or an invitation to answer from memory.

New Cat and /new prepare a distinct conversation; the first typed send creates it. Resume selects an existing Cat with its own history. /condense keeps the same Cat ID and durable history while shortening the active context. It ends the old call so the next Talk starts from the updated context. Condensation is unavailable while work or approval is pending.

Long answers stay complete in OpenHands. Speech uses a bounded excerpt and says when the full answer is saved in the conversation. Live captions are transient call feedback.

Source: active-context snapshot, spoken excerpts, Canvas condensation.

Interruptions and call controls

A new spoken request does not steer or queue behind running work. If the Cat is busy, Voice reports that the new request was not sent. Wait for the current task to finish, then repeat it. Silence, interruption, and End call do not cancel an accepted OpenHands task.

New user speech invalidates a pending older spoken result. Before writing speech to Codex, the server checks that it still belongs to the current input. A concurrently typed message also prevents the bridge from assigning an ambiguous answer to the voice request. The accepted task and its answer remain saved even when its spoken result is suppressed.

Audio already queued by the provider cannot be recalled by the server’s stale-result check. Codex V3 output does not identify the originating request, so the browser suppresses output conservatively after reported speech starts, typing, or Stop. This reduces stale speech; it does not guarantee every interruption race is eliminated.

Each handoff ID is admitted at most once per call. This is not a global exactly-once guarantee across retries or new calls. A rejected request is distinguished from an uncertain saved outcome: inspect the conversation before retrying after a relay failure. The bridge waits up to five minutes for a result; accepted work can continue after that wait or after the call ends.

Source: playback and microphone controls, final speech guard, new input and busy handoffs, expiry, cleanup, and call ownership.

What has been verified

The 26 October verification record covers real Codex Voice and a real OpenHands Cat, with generated microphone input. It records a saved spoken request, terminal execution, the saved answer, and received spoken audio. It also covers skill-guided backend queries, editor use, conversation continuity, fresh-call recall after condensation, approval pauses, microphone denial, and call cleanup.

The current SDK PR head is the report commit e17f4e09b; its implementation includes the tested b09624ddb busy-request correction and stale-speech guards. The 31 October review checked source and PR state. It did not repeat the live calls.

Remaining live checks: physical microphone and speaker use, especially on iPad; the separate OpenAI API provider; live backend switching; and a complete keyboard-only traversal. Generated audio and transport statistics do not verify how a real device sounds or handles interruptions.

Implementation record

Follow the Insider App repository, Canvas PR #17558, and Agent Server PR #5180 for source and review status. For the user experience, see Insider Cat and the user scenarios.