Text chat
Open a text session when your app needs a typed conversation with no microphone or WebRTC setup. The SDK requests POST /api/v1/sessions/token with mode: 'text', connects the channel WebSocket, and routes your app's web_chat flow entry on the platform.
For the TelAPI wire format and REST upgrade/downgrade endpoints, see Browser SDK → Text chat.
Prerequisites
- An endpoint whose flow includes a
web_chatentry point (visible in TelWeb under the endpoint's entry-point configuration). DelphiClientconfigured withapiDomain+apiKey, or a same-originsessionTokenUrlproxy.- Platform
webrtcflag on (gates all SDK session routes, including text-only).
Check support before opening UI:
const caps = await delphi.getCapabilities(endpointId);
if (!caps.interactionModes.text) {
throw new Error('This endpoint does not support text chat.');
}
const canHandoff =
caps.runtime.migration.includes('text_to_voice') &&
caps.runtime.migration.includes('voice_to_text');
Minimal example
const session = await delphi.openSession({
endpointId: '24599c70-1e79-4e52-9819-e2d97acf45a5',
mode: 'text',
});
session.onChat((chat) => {
if (chat.role === 'assistant') {
console.log('AI:', chat.content);
}
});
session.sendTextChat('Hello — what can you help me with?');
sendTextChat sends a chat message with intent: 'conversation' and expects a text reply. For full control (context-only updates, read-aloud intents, preferred response mode), use sendChat() — see the API reference.
React — useDelphiSession
import {useDelphiSession} from '@ki-kombinat/delphi-client-js-sdk/react';
function ChatPanel({endpointId}: {endpointId: string}) {
const {connected, messages, sendTextChat} = useDelphiSession({
endpointId,
mode: 'text',
});
const [input, setInput] = useState('');
const visible = messages.filter(
(m) => m.type === 'chat' && m.chat?.content && m.chat.intent !== 'browser_context',
);
return (
<div>
{!connected && <p>Connecting…</p>}
<ul>
{visible.map((m) => (
<li key={m.messageId}>{m.chat!.content}</li>
))}
</ul>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter' && input.trim()) {
sendTextChat(input.trim());
setInput('');
}
}}
/>
</div>
);
}
Attach <DelphiProvider> at the app root with the same DelphiClient instance — same pattern as the voice quick start.
Page context without a reply
Keep the AI aware of what the user sees:
session.setBrowserContext({
text: document.body.innerText.slice(0, 4000),
identifier: window.location.pathname,
source: 'page',
});
This sends intent: 'browser_context' with responseExpected: false — no assistant turn is triggered.
Upgrade to voice
When the flow supports both web_chat and web_voice, migrate the live text session to a WebRTC call on the same sessionId:
delphi.setRemoteAudioElement(document.querySelector('#remote-audio')!);
await delphi.upgradeToVoice({
endpointId,
autoDial: true, // dial as soon as the SIP plugin registers
browserContext: {identifier: 'browser-user-1'}, // optional, sent before dial
});
What the SDK does internally:
- Confirms an open
textsession forendpointId. POST /api/v1/sessions/upgradewith the currentsessionId.- Closes the text WebSocket and opens
voice_conversationwith the upgraded token. - Re-imports prior chat messages into the new session for UI continuity.
- Connects WebRTC using
telproDomain/webrtcGatewayUrlfrom the upgrade response.
Attach the remote <audio> element before calling upgradeToVoice (same rule as Voice call).
Downgrade to text
Switch back to typed chat after a call:
const session = await delphi.downgradeToText({
endpointId,
endCallFirst: true, // default — hang up WebRTC before reopening text
});
session.sendTextChat('Thanks — can you summarise what we discussed?');
The SDK sends prepare_voice_to_text_handoff on the channel, calls POST /api/v1/sessions/downgrade, tears down WebRTC, and reopens mode: 'text' with the same sessionId.
Text overlay on a voice call (no migration)
If the user is already in a voice_conversation and you only want a typing panel alongside the call — without changing session mode:
const session = await delphi.startCall({endpointId, autoDial: true});
session.enableTextChat('text'); // AI replies in text; user can still speak
session.sendTextChat('Please email me the confirmation number.');
// later
session.disableTextChat();
Use upgradeToVoice / downgradeToText when the primary transport should switch between text-only and full voice. Use enableTextChat when voice remains the main session and text is auxiliary input.
Cleanup
await delphi.endSession(endpointId, 'text');
// or, if upgraded: await delphi.endCall()
Non-voice sessions also auto-close after sessionIdleTimeoutMs (default 5 minutes) when idle.
Common gotchas
openSession({ mode: 'text' })fails with 409 — endpoint flow lacks aweb_chatentry or the endpoint is archived.- Upgrade returns 503 —
FEATURE_WEBRTC=falseor TelPro is not configured on the deployment. - No assistant reply to typed text on a voice call — call
enableTextChat()first; by default voice sessions ignore chat unless text-chat mode is enabled. - Stale
getSession(endpointId)after handoff — pass the mode:getSession(endpointId, 'text')vs'voice_conversation'.
Next step
Voice call — start directly in voice_conversation when you do not need a text-first UX.