Chat

An agent is one definition. Nothing forces it to do both text and voice - a text agent needs no voice, no transcriber and no phone number, and a voice agent needs no chat widget. The prompt, the tools, the knowledge base and variables behave identically either way.

TextVoice
What you build withthreads, or the browser chat widgetcalls, phoneNumbers, campaigns
How it is meteredper token, plus a flat fee per messageper token, per character and per minute by component, plus a flat platform fee per minute
Settings that applymodel, prompt, tools, knowledge, variablesthose, plus voice, transcriber and turn-taking

The same agent can do both if you want it to. See Pricing for how each is metered.

Threads and runs

A thread holds one conversation. A run is one turn on it: you add a user message, the agent replies, and the thread keeps the history so you never resend it.

A run completes before the call returns, so there is nothing to poll - the reply is already in the result. The thread carries the agent id it was opened against, so no later call has to repeat it.

import { Glytos } from '@glytos/node';

const glytos = new Glytos(process.env.GLYTOS_API_KEY!);

const thread = await glytos.threads.create({ agent: agentUuid });
const run = await glytos.threads.runs.create(thread, 'What are your opening hours?');

console.log(run.messages.at(-1)?.content);

A run returns only that turn's messages. The whole conversation is on the thread:

const history = await glytos.threads.messages.list(thread);

Opening a thread with variables seeds it, and those values are available to the prompt for the rest of the conversation - see Variables.

Streaming

A long answer should not arrive as one silent wait. Streaming yields the reply as it is written, then a terminal done event carrying the same payload the non-streamed call returns. Routing, persistence and billing are identical either way.

for await (const event of glytos.threads.runs.stream(thread, 'Summarise the policy')) {
  if (event.type === 'token') process.stdout.write(event.delta);
  if (event.type === 'done') console.log(event.run.status);
}

The stream is Server-Sent Events. Calling the API directly, each frame is event: token, done or error followed by a data: JSON line, with a blank line between frames.

Per-turn instructions

Extra context that applies to one run only. It sits below the agent's own instructions and is never saved to the agent, so a scoring pass or a one-off format demand does not permanently change how the agent behaves.

await glytos.threads.runs.create(thread, {
  content: 'Rate this transcript',
  instructions: 'Score 1-5 and reply as JSON.',
});

The message may be empty when the instructions carry the turn: re-running a conversation with new instructions and no new message is a legitimate run.

Images and attachments

Images ride on a single turn, and a text-only model simply ignores them:

await glytos.threads.runs.create(thread, {
  content: 'What is on this label?',
  images: [dataUri],
});

A file is attached to one conversation. Its text is put in front of the agent for that conversation only - it does not join the knowledge base and it does not reach any other thread:

await glytos.chat.uploadFile({
  token,
  sessionUuid: thread.id,
  file: buffer,
  filename: 'policy.txt',
});

For documents every conversation should be able to reach, use the knowledge base instead.

In the browser

For a chat widget on your own site, use @glytos/web with a short-lived chat token you mint on your backend - never an API key.

import { GlytosChat } from '@glytos/web';

const chat = new GlytosChat({ token });

chat.on('token', t => append(t.delta));
chat.on('message', m => render(m));

await chat.start();
await chat.stream('Hello!');

The conversation id is on chat.sessionId; persist it and pass it back as sessionUuid to pick the same conversation up later.

Per-turn instructions are deliberately not available in the browser: the widget runs on a public page, so such a field would let anyone rewrite your agent's behaviour on your own site. Use a server SDK for that.

See the Web SDK.

Organising agents

Folders group agents inside one environment, so Development and Production organise independently:

const folder = await glytos.folders.create('Support');
await glytos.agents.moveToFolder(agentUuid, folder.uuid);

Deleting a folder deletes the agents filed in it, so the confirmation states the count. Their financial records survive; their own call history does not.

What it costs

Text is metered per token at the model's own rate, plus a small flat fee per message. A canned message step that runs no model is not billed. Bring your own provider key and the token cost is yours - only the flat fee applies. See Pricing.

Where to look next

  • Tools - text runs the same saved tools voice does.
  • Sessions - every thread is a session, with its full transcript, cost breakdown and event log.
  • API reference - every endpoint.
Chat · Glytos Docs