Skip to content

Chat & Conversations

Tavora exposes two distinct chat-style surfaces, with deliberately different shapes for deliberately different jobs.

Use thisWhen
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 + sendMessageStored, multi-turn LLM chat. Tavora persists messages, applies RAG, returns the assistant reply. Still LLM-only — no think step, no JS sandbox.
AgentSession + runAgentThe 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.

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)

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.

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 history
got, _ := client.GetConversation(ctx, conv.ID)
for _, m := range got.Messages {
fmt.Printf("[%s] %s\n", 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”
NeedUse
Pure LLM Q&A grounded in your docsConversation
The model needs to call tools, retrieve, or branchAgentSession
You want a readable post-mortem trace over what the model didAgentSession
You want code-first authoring, version history, and advisory evalsAgentSession (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.