Skip to content

GPTLiveModel: image input and backend-turn typed input parity with RealtimeModel #7291

Description

@abharw

Feature Type

Would make my life easier

Feature Description

Use case. A voice agent in a live meeting where a participant shares their screen. The agent needs to (a) inspect a screenshot on demand and reason over it in the delegated backend, and (b) accept a typed message from a participant in the same session. GPT-Live's full-duplex voice with a delegated Responses backend is the right shape for this: the voice model stays responsive while the backend handles the screenshot and the task context. The two gaps below are what blocked it. Both are supported by OpenAI's protocol today (see the Live delegation guide); the plugin just has no application path to them.

GPTLiveModel (livekit-plugins-openai 1.8.1, delegation="responses") has no application path for two inputs that RealtimeModel handles natively:

  1. Image input. ImageContent in the chat context is not translated into a Responses backend input item; the renderer reads message text only. OpenAI's Live delegation guide documents this: with a vision-capable backend model the client queues "a supported Responses image input item with response.item.create". Today an app has to upload the file itself and call send_event directly, and because send_event queues locally and the plugin retains its outgoing queue across reconnects, the app cannot know whether the item reached the session it was authored for. Request: push_video / ImageContent support on GPTLiveSession equivalent to RealtimeModel.push_video, or a documented submit_backend_item() that returns a receipt bound to the current connection.

  2. Typed user turns. RoomIO's default text callback calls generate_reply(user_input=...), which GPTLiveSession._generate_reply turns into append_commentary(_ASK_TYPED ...) — an ask to the voice model to talk about the text — rather than a backend user turn. OpenAI's guide documents typed input as exactly this: a response.item.create with a message item, role user, content {"type": "input_text", "text": ...}, followed by response.create "when ready to run or continue the backend". The plugin does not expose that path; it routes typed text to the voice model's commentary instead. Request: an option on GPTLiveModel (e.g. text_input="backend_turn" | "commentary") so apps do not have to reimplement turn admission and idle tracking against private event ordering.

Workarounds / Alternatives

We implemented both seams in-app (~1,100 lines: generation-lease bookkeeping, idle tracking on session.started / response.created / function_call, Files upload with expiry). It works but reimplements plugin-owned state and is fragile across reconnects (APIConnectOptions(max_retry=0) + max_session_duration=None to avoid queue replay). We have paused GPT-Live in our product until the plugin covers these.

Additional Context

Pinned: livekit-agents 1.8.1, livekit-plugins-openai 1.8.1, Python 3.12. Happy to share the fixture that reproduces queued-item replay across a reconnect.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions