LlamaChat is a multipage Streamlit app for chatting with an LLM via an OGX / Llama-Stack OpenAI-compatible backend, with optional:
- Agentic mode (tool use + MCP connectors)
- Safety shields (moderation models)
- RAG (document ingestion + embeddings + vector stores)
- Audio (Whisper ASR + Kokoro TTS; experimental)
This README documents the current implementation in this repository (files, config keys, and backend API requirements).
- Entrypoint:
main.pyregisters Streamlit pages and runs navigation. - Pages:
pages/agentic_chat.py: main chat UI. Supports:- Chat mode (LLM only) and Agentic mode (tools/MCP + optional file search toolgroup)
- Optional input/output shields
- Optional RAG via vector store IDs (backend-provided)
- Chat history save/load/export (JSON + Markdown)
- File upload:
- Images are sent as
input_imagecontent (base64 data URL) - Documents are converted with Docling and appended as markdown context
- Images are sent as
pages/embeddings.py: document ingestion pipeline:- Convert files with Docling, chunk with
HybridChunker - Create/select a vector store collection
- Compute embeddings via backend and insert chunks via
vector_io.insert
- Convert files with Docling, chunk with
pages/whisper_audio.py: audio → text (Whisper viatransformerspipeline; usestorchcodec)pages/tts_audio.py: text → audio (Kokoro TTS; usestorchcodec)
- Configuration loader:
libs/shared/settings.pyloads YAML intolibs/utils/parameters.pyand performs boot checks (creates chat history dir). - Session + persistence:
libs/shared/session.py- Manages
st.session_statedefaults - Lists models/providers/shields via backend HTTP endpoints
- Saves/loads chat histories (JSON) and exports to Markdown
- Manages
- Agent wrapper:
libs/shared/agent.py- Uses the backend’s Responses API (
client.responses.create) with optional tools + continuity viaprevious_response_id - Applies shields via
libs/shared/shields.py(Moderations API)
- Uses the backend’s Responses API (
- Agent message model:
libs/shared/state.py(AgentMessagedataclass) - Tool / connector discovery:
libs/shared/connectors_wrapper.pyGET /v1/toolsandGET /v1beta/connectors- MCP connectors are recognized by
connector_idprefixmcp::
- Response formatting for UI:
libs/shared/responses.py(formats responses + tool call summaries) - RAG ingestion utilities:
libs/embeddings/embeddings.py,libs/embeddings/vectorio.py - Audio utilities:
libs/utils/audio_pipelines.py
Configuration is loaded in this order:
.env(optional) → selects config file- YAML config file (default:
parameters.yaml)
CONFIG_FILE: YAML file to load (default:parameters.yaml)
Example:
CONFIG_FILE="parameters.yaml"-
openai.default_local_api: backend base URL (default ishttp://localhost:8321) -
openai.api_key: bearer token used for some HTTP calls (model/provider listing) -
openai.model: default LLM model ID (selected from/v1/models) -
openai.shield_model: default shield model (used for moderation calls) -
openai.stream: default streaming toggle for chat responses -
openai.history_dir: directory where chat histories are written (defaultchat_histories) -
openai.latest_history_filename: autosave filename (defaultlatest_chat.json) -
llm.system_prompt: default system prompt (editable in UI) -
llm.temperature,llm.timeout,llm.max_output_tokens -
llm.max_infer_iters,llm.max_tool_calls,llm.parallel_tool_calls -
vectorstore.embedding_dimensions: expected embedding dimensionality for new vector collections -
features.supported_data_formats,features.supported_img_formats,features.supported_audio_formats -
huggingface.apitoken,huggingface.local_dir,huggingface.cache_dir: used by Whisper/Kokoro pages to download model snapshots.
This repo does not ship the backend. The Streamlit app expects an OGX/Llama-Stack style backend that exposes (at minimum) the following APIs under openai.default_local_api:
GET /v1/models- Used by
libs/shared/session.pyto list models; LLM and embedding models are filtered viacustom_metadata.model_type(llm,embedding).
- Used by
GET /v1/shields- Used to list shield models for input/output shielding.
GET /v1/providers- Used to list providers (e.g.
vector_io) for embeddings/vector store operations.
- Used to list providers (e.g.
GET /v1/tools- Lists toolgroups/tools available on the backend.
GET /v1beta/connectors- Lists connectors. MCP connectors are selected when
connector_idstarts withmcp::.
- Lists connectors. MCP connectors are selected when
- Responses API: used by
libs/shared/agent.pyviaclient.responses.create(...)previous_response_idis used for multi-turn continuity.- In agentic mode,
tools=[...]includes MCP server entries and optionally afile_searchtoolgroup with vector store ids.
- Moderations API (optional; required if you want shields)
- Used by
libs/shared/shields.pyviaclient.moderations.create(input=..., model=...).
- Used by
Used by pages/embeddings.py and (optionally) pages/agentic_chat.py:
vector_stores.list()/vector_stores.create(...)embeddings.create(input=[...], model=..., dimensions=...)vector_io.insert(vector_store_id=..., chunks=[...])
- Python:
>= 3.13(seepyproject.toml) - Runtime: Streamlit (installed via project dependencies)
- Audio features (experimental):
torch,torchcodec,torchaudio,ffmpegavailable on your system - Backend: an OGX/Llama-Stack OpenAI-compatible endpoint reachable at
openai.default_local_api
This repo is set up for uv (uv.lock is present).
uv sync
uv run streamlit run main.pyStreamlit defaults to http://localhost:8501.
Dockerfile starts Streamlit like this:
streamlit run --server.address $HOST --server.port $PORT main.pyNotes:
- The Dockerfile currently installs dependencies only from
requirements.txt(or a single*.txtfile). This repo’s primary dependency source ispyproject.toml/uv.lock. - If you want to build the current Dockerfile without changing it, generate a
requirements.txtfrom the lockfile (uv supports exporting requirements) and then build. - You must still provide a reachable backend URL (via
parameters.yamland/or.env).
On macOS (notably macOS 26+), importing torchcodec can fail if dynamic libraries for ffmpeg are not visible.
Workaround (Homebrew + temporary DYLD_LIBRARY_PATH):
brew install ffmpeg@7
DYLD_LIBRARY_PATH="/opt/homebrew/opt/ffmpeg@7/lib:$DYLD_LIBRARY_PATH" uv run streamlit run main.py