Conversation state

Keep a conversation going across turns, manage context size, and reconnect to a session.

The gateway does not keep a conversation for you. Each turn is independent: you send every message the model should see, and the model answers. This keeps you in charge of what is remembered, trimmed or corrected.

Build a multi-turn chat

After each turn, add the model’s reply to your history, then add the next user message and send it all again.

import { createInterface } from 'node:readline/promises';
import { connect } from './gateway.js';

const gateway = await connect();
const rl = createInterface({ input: process.stdin, output: process.stdout });

const messages = [
	{ role: 'system', content: [{ type: 'text', text: 'You are a friendly assistant.' }] }
];

while (true) {
	const line = await rl.question('you> ');
	if (!line) break;

	messages.push({ role: 'user', content: [{ type: 'text', text: line }] });

	const result = await gateway.turn(
		{ provider: 'auto', model: 'auto', messages },
		{ onText: (piece) => process.stdout.write(piece) }
	);
	console.log();

	// Remember what the model said.
	messages.push({ role: 'assistant', content: [{ type: 'text', text: result.text }] });
}

gateway.close();
rl.close();

If a turn ends with an error and no text, remove the user message you just added (or retry) so the history stays tidy. If a turn used tools, add the assistant tool calls and the tool results as shown in Function calling.

Stay inside the context window

Every model has a maximum context, shown as capabilities.max_context in the catalog. Your history plus the answer must fit. With auto, the gateway only picks models that fit. If you name a model and the conversation is too long, the turn fails with no_capable_model.

When a chat gets long:

  • Drop the oldest turns, but keep the system message.
  • Replace old turns with a short summary you generate in a separate turn.
  • Watch usage.input_tokens in turn.complete to see how big the history is.

Models you do not control may differ in how they count, so leave some headroom.

Switching models mid-conversation

Because history is yours, you can change provider and model between turns freely, for example to use a cheaper model for simple replies and a stronger one for hard questions. The gateway also does this for you in a single turn when it falls back after a failure. See Errors and handling.

Sessions

A session is the connection the gateway keeps open for you. Do not confuse it with the conversation: the session stores recent events so you can recover from a dropped connection, but it does not hold messages for the next turn.

When you connect, session.ready gives you a session_id:

{ "type": "session.ready", "session_id": "3f2a9c1e-7b4d-4e8a-9f61-0c2d5e8b7a10", "last_seq": null, "active_request_id": null }

Reconnect and resume

If your connection drops, you can pick up where you left off.

  1. Open wss://gateway.vaktex.com/vaktex/v1/stream/<session_id> with the same key that created the session.
  2. Wait for session.ready. last_seq is the newest event stored, and active_request_id tells you if a turn is still running.
  3. Send { "type": "resume", "from_seq": N }, where N is one more than the last seq you received.

The gateway replays everything you missed, in order, and then continues live.

let lastSeq = -1; // update this from every event you receive that has a seq

const ws = new WebSocket(`wss://gateway.vaktex.com/vaktex/v1/stream/${sessionId}`, {
	headers: { Authorization: `Bearer ${process.env.VAKTEX_KEY}` }
});

ws.once('open', () => {
	ws.send(JSON.stringify({ type: 'resume', from_seq: lastSeq + 1 }));
});

If you send any other frame instead of resume, you only get events after session.ready, with no replay.

How long sessions last

  • A turn that is running when you disconnect keeps going for up to five minutes. After that it ends with stop_reason: "disconnect".
  • A session with no connection and no running turn is erased after five minutes. After that, connect without a session id to start a new one, and send your history again.
  • Opening a second connection to a session closes the first with WebSocket close code 4000.
  • Reconnect with a key from the same licence that created the session. Other keys get HTTP 404.

Keep a copy of the conversation on your side. It is always the source of truth.

Keep a turn alive

While a turn runs, send { "type": "ping" } at least every 20 seconds. The gateway answers { "type": "pong" }.

Next steps

enesfrdenbsvfiplarhe