Chat & Conversations
Tavora exposes two distinct chat-style surfaces, with deliberately different shapes for deliberately different jobs.
| Use this | When |
|---|---|
chatCompletion (stateless) | OpenAI-compatible single-shot LLM call. RAG-aware if you pass use_rag: true + an index_id. No persistence. This is the LLM-gateway role. |
createConversation + sendMessage | Stored, multi-turn LLM chat. Tavora persists messages, applies RAG, returns the assistant reply. Still LLM-only — no think step, no JS sandbox. |
AgentSession + runAgent | The agent. Reasons by writing JS in the Goja sandbox, calls tools, retrieves, leaves a readable trace. This is what you want for anything beyond plain LLM chat. See the Quickstart. |
If your use case fits in one LLM call, use chatCompletion. If you
need a persisted thread for the LLM to read, use Conversation. If
you need reasoning — multi-step, tool-using, retrieval-augmented —
use an agent session.
Stateless chatCompletion
Section titled “Stateless chatCompletion”OpenAI-compatible request shape, served from the same provider router as the rest of the platform — so you get the same audit log, the same token metering, and the same secret-vault-backed BYO model keys.
resp, _ := client.ChatCompletion(ctx, tavora.ChatCompletionRequest{ Messages: []tavora.Message{ {Role: "user", Content: "What is our refund policy?"}, }, Model: "gemini-2.0-flash", UseRAG: true, IndexID: indexID, // ground in this index})fmt.Println(resp.Choices[0].Message.Content)const resp = await client.chatCompletion({ messages: [{ role: 'user', content: 'What is our refund policy?' }], model: 'gemini-2.0-flash', use_rag: true, index_id: indexId,});console.log(resp.choices[0].message.content);use_rag: true instructs the platform to embed the latest user
message, search the supplied index, and inject the top-K chunks as
context before the LLM call. Skip it (or pass an empty index_id) for
plain LLM completion.
Stored conversations
Section titled “Stored conversations”Conversations are project-scoped, multi-turn LLM threads. The platform persists messages and runs the same RAG-aware completion path under the hood — useful for product UIs that want a “thread that remembers” without the cost or complexity of an agent.
conv, _ := client.CreateConversation(ctx, tavora.CreateConversationInput{ Title: "Refund policy chat", UseRAG: true, IndexID: &indexID,})
reply, _ := client.SendMessage(ctx, conv.ID, "What is our refund policy?")fmt.Println(reply.Content)
// Inspect historygot, _ := client.GetConversation(ctx, conv.ID)for _, m := range got.Messages { fmt.Printf("[%s] %s\n", m.Role, m.Content)}const conv = await client.createConversation({ title: 'Refund policy chat', use_rag: true, index_id: indexId,});
const reply = await client.sendMessage(conv.id, 'What is our refund policy?');console.log(reply.content);
const got = await client.getConversation(conv.id);for (const m of got.messages) console.log(`[${m.role}] ${m.content}`);Why this surface is not “Tavora’s chat product”
Section titled “Why this surface is not “Tavora’s chat product””Tavora is the agent layer for your stack — not a consumer chatbot product. The chat APIs above exist as gateway primitives so you can serve the LLM-only slice of your product through the same audit log, metering, and BYO-keys path as the rest of your agentic features.
A consumer chat surface (claude.ai-style) is out of scope for this codebase. Build your own chat UI in your own project and back it with these APIs — that’s the integrator pattern.
Choosing between conversation and agent session
Section titled “Choosing between conversation and agent session”| Need | Use |
|---|---|
| Pure LLM Q&A grounded in your docs | Conversation |
| The model needs to call tools, retrieve, or branch | AgentSession |
| You want a readable post-mortem trace over what the model did | AgentSession |
| You want code-first authoring, version history, and advisory evals | AgentSession (the agent is authored under tavora/) |
When in doubt, use an AgentSession — its single-turn shape is roughly
as cheap as a Conversation turn, and it grows with you.