Skip to main content
A Prism session holds one conversation, from connect until the connection closes. Its settings, instructions, and history decide how each reply sounds and what each reply knows. The snippets use the Rime SDK in Python and Node.js, with these names:
  • client is an open Rime client.
  • microphone yields the PCM16 frames from your capture.
  • player is your audio output.

Open one session per call

Open a session when the call starts, and close it when the caller hangs up. This code holds one call. It sends the caller’s audio on a separate task and reads Prism’s events in play_replies, which Live conversations builds. When the caller hangs up, the capture loop closes the session, and the events loop ends.
In Python, stream_caller_audio closes the session when the capture stops for any reason, so a failed microphone ends the call. In Node.js, background runs work beside the events loop, and it closes the session if that work fails. The snippets in Live conversations and Tools also use it.

Configure a session

Set the voice, instructions, tools, and turn settings when the session opens. The SDK sends them when you connect, and over the WebSocket API, the first session.update sets them. During the call, update in the SDK, or a later session.update, can change most of them: Node.js uses the same names in camelCase: interruptOnSpeech, turnDetection, endOfTurnTimeoutMs, responseMetadata, and setResponseMetadata. In Go and Rust, Update and update take the same settings. These SDK calls need Python 0.1.0a22, Node.js 0.1.0-alpha.22, Go v0.1.0-alpha.13, Rust 0.1.0-alpha.11, or later, as the Prism SDK reference lists. The two turn settings work like this:
  • Eagerness: how readily Prism decides that the caller has finished. low cuts in less and replies later, and high replies sooner and cuts in more. medium and auto, the default, use Prism’s standard setting.
  • End-of-turn timeout: the silence that ends the turn, even when Prism is not sure that the caller has finished. It runs from 1 to 10 seconds, and the default is 5 seconds.
Prism refuses a new eagerness or timeout with session_setting_fixed, and that update changes nothing, not even its other fields. Session configuration in the WebSocket reference lists every field, its default, and its values.

Choose a voice

Prism has four voices. Pick the one that suits your callers, and set it when you connect. Without a voice, Prism uses astra.

Write instructions for a phone call

Prism speaks every word that it writes, so the caller hears whatever format the reply takes. Start the instructions with rules for speech, and put your agent’s role, task, and policy after them. Write them in plain sentences, because replies follow their style. Write instructions that Prism follows gives a starter prompt with these rules, and shows how to improve it with test calls.

Update instructions or history during a call

You can update Prism while a call runs. add_message (addMessage in Node.js) adds a line to the history. With create_item (createItem in Node.js) or over the WebSocket API, you can also add a system message, which is a note for the model, and delete_item (deleteItem) removes an item. Read and edit the history in the SDK reference shows both. update in the SDK, or a later session.update, can change the instructions, the voice, and the tools. Prism caches the start of the conversation between turns. After you change the instructions, the next reply builds that cache again, so its first audio comes a little later. A change never interrupts the reply that is playing. That reply keeps the settings that it started with, and the next reply uses the change. To make a change count at once, follow these steps:
  1. Make the change.
  2. Cancel the reply that is playing, with cancel in the SDK or response.cancel over the WebSocket API.
  3. Report what the caller heard, and report that playback stopped. Stop playback when the caller talks over a reply and Report when a reply finishes playing show how.
  4. Ask for a nudge, such as “Tell the caller about the change.”
Prism takes a nudge only while it is idle. Until both reports arrive, Prism counts the cancelled reply as still playing.

Start from an earlier conversation

A new session is a new conversation with no memory of the old one. A session also ends when its connection drops, and the SDK does not reconnect. So to go on with an earlier call, give the new session what the agent must remember. Add that history right after connect, before you stream the caller’s audio, so that the first reply already sees it. With the SDK, add each line with add_message (addMessage in Node.js), as Typed turns and nudges shows. A "user" line is something that the caller said, and an "assistant" line is a reply that the caller heard:
To carry over notes and past tool calls too, add each item with create_item (createItem in Node.js), as Start from an earlier call shows. Over the WebSocket API, send one conversation.item.create for each item, after session.updated. Both take three kinds of items:
  • Past messages: user and assistant messages, as with the SDK.
  • Notes: a system message, such as “The caller called back after the line dropped.” The model sees the note at its place in the conversation.
  • Past tool calls: a function_call item, and then a function_call_output item with the same call_id. A past call never starts a tool round.
To resume after a disconnect, save the conversation while the call runs. get_history (getHistory in Node.js) in the SDK, or prism.conversation.get over the WebSocket API, lists every item in the order the next reply sees them, including turns that a long call leaves out of the prompt, and a new session accepts the listed items as they are. Keep each message within the text limit.

What each reply sees

Each reply sees your instructions and tools, and the conversation so far, unless a long call outgrows the context:
  • the caller’s turns. Prism keeps each earlier turn as its transcript.
  • Prism’s earlier replies. After an interruption, your playback report keeps only what the caller heard.
  • every tool call and its result
  • every message that you added
When the conversation outgrows the context, Prism leaves out the oldest turns, as Handle long calls explains. get_history (getHistory in Node.js) in the SDK, or prism.conversation.get over the WebSocket API, lists the conversation.

Handle long calls

A call has no time limit. When a long call outgrows the context, Prism leaves the oldest turns out of each reply’s prompt by default, and the call goes on. So put what the agent must always know in the instructions, because a system message that you add leaves the prompt with its turn. Over the WebSocket API, truncation sets this. usage in each response.done shows how many tokens the prompt uses, and prism_truncation says how many earlier items Prism left out.

Label replies for your logs

You can label every reply with your own values, such as your call ID, to match Prism’s events to your records. With the SDK, pass response_metadata (responseMetadata in Node.js) when you connect, or call set_response_metadata (setResponseMetadata) during the call. Over the WebSocket API, set the labels in prism_response_metadata, and Prism copies them into the metadata of each reply’s response.created and response.done:
A label in the metadata of a response.create replaces the session label with the same name, for that reply only. This metadata came from the reply to a typed turn that set agent to after-hours. Prism adds its own fields, whose names start with prism_. prism_drain_token is the token for the reply’s playback receipt:
A later session.update with prism_response_metadata replaces all the labels, and {} clears them. Leave the field out to keep the current labels. Labels have limits on their number and length.

End a session

Close the session when the caller hangs up. With the SDK, leave the async with block, or call await session.close(). Over the WebSocket API, close the connection. A closed connection ends the conversation, and a new connection starts a new conversation. Prism also closes a quiet conversation after 5 minutes, even while you send audio. It sends session.idle_timeout first, and then it closes the connection with code 1000 and reason idle. The time starts again with any other client event, with speech that Prism detects, or with a reply. So a nudge that checks on a quiet caller keeps the conversation open. Most errors do not end the session. Errors and limits explains each error code and close code, and what to do about it.