Chat
Control your whole stack from chat — run workflows and agents, read metrics and logs, and stand cloud resources up or tear them down on any criteria, behind a human-approval gate on writes.
You already know chat. Here’s what’s different: this one drives your whole stack.
From a single conversation you operate the real thing — read metrics, tail logs, inspect clusters, and act: launch Flows, run agents, and stand whole cloud environments up or tear them down on whatever criteria you give it (“spin down every dev cluster with no traffic in 7 days”). It isn’t a chatbot bolted onto a dashboard — it’s the control surface for everything below it.
And every action is on the record. Cloud tool calls run with the service-account credentials you configure for the self-hosted build, each tool gets only the credentials it needs, and every call lands in a tamper-evident audit trail. Anything that changes state pauses for your approval first. (Per-user identity — running each action as the signed-in human via SSO / on-behalf-of — is an enterprise feature; see AgenticWork.)
OpenAgentics is self-hosted: chat runs against the providers you configure, and no request leaves your infrastructure unless you point a turn at a cloud model.
Select a model
Each conversation can run on a different model. By default OpenAgentic talks to a local Ollama model — private, offline, zero-cost, no API key — and you can switch to a frontier provider when a task warrants it. Providers are pluggable: the platform reads its model registry from the database, and you wire up whichever providers you have credentials for.
The following provider types are supported:
| Provider type | Notes |
|---|---|
ollama | Local model runtime. Default bootstrap provider. |
anthropic | Claude models via the Anthropic API. |
openai | OpenAI API. |
azure-openai | Azure OpenAI Service. |
google-vertex | Vertex AI (Gemini, embeddings, Imagen). |
aws-bedrock | Amazon Bedrock. |
Install seeds exactly one provider. You add more from the admin console (Admin > LLM Providers), which writes to the llm_providers table. The model for a turn is resolved by input.model (the model string the caller passes), which the ProviderManager routes to the matching provider client. There is no hardcoded vendor assumption.
Note: The
SmartModelRouterperforms capability gating during tool selection (it enforces the hard tool ceiling described below). It does not silently downgrade a turn to a different vendor.
The agent loop
Chat is agentic end to end. Each turn runs a single streaming provider call, collects the tool calls the model requested, dispatches them, appends the results to the message history, and repeats until the model returns end_turn.
A turn proceeds through these stages:
- Streaming provider call. One call per iteration with the current messages, the
toolsarray, the system prompt, and the model. - Tool partitioning. Requested tool calls are classified by
PermissionServiceinto read-only (parallel-safe) and write (serial) batches based on glob-pattern rules (e.g.,list_*,get_*,describe_*are read-only;*_delete_*,*_drop_*,*_truncate_*are write). - Parallel dispatch. Read-only tools run concurrently.
- Serial dispatch. Write tools run one at a time and are gated behind human-in-the-loop approval when triggered.
- Result processing. Tool results are appended to the message history as tool-role blocks.
- Repeat until
end_turnor the maximum turn count is reached.
The maximum number of turns is admin-tunable through ChatLoopConfigService (stored in the admin.system_configuration row keyed chat_loop). There is no hardcoded default.
Two terminal guards keep a run from ending without a usable answer:
- Synthesis guard. If the model returns
end_turnwith no text after tool results, the loop forces one final turn withtool_choice='none'so the model produces a prose answer. This is bounded to one retry (bounded fallback). - Discovery dead-end guard. After two consecutive
tool_searchcalls that add no new tools to the catalog, the loop forces synthesis with a directive that the requested capability is not connected.
Operate your stack
Chat acts on your infrastructure through the bundled MCP servers, rather than only reporting on it. It shares the same MCP ecosystem as Flows: the cloud servers (AWS, Azure, GCP), Kubernetes, observability (Prometheus, Loki), GitHub, web search, and the admin server. For the full server list and the self-hosted credential model, see MCP servers.
Chat does not place every tool in the model’s context. Instead, it narrows the catalog through a three-layer selection cascade (described next) before the model sees any tool definitions.
Tool selection cascade (T1/T2/T3)
OpenAgentics ships nine built-in MCP servers with well over a hundred tools. Presenting all of them to the model degrades tool-use accuracy, so chat narrows the catalog through three layers. Models choose far more reliably from a short, relevant list.
| Layer | Name | What it does |
|---|---|---|
| L1 | Intent routing | The query is classified into action verbs (for example, kubectl, github pr, search web) and topic nouns (Azure, AWS, GCP, Kubernetes, web, GitHub, admin, Prometheus, Loki), then routed to the matching MCP servers. This narrows the full catalog to roughly 8–40 candidate tools. |
| L2 | Pgvector semantic search | Within the targeted servers, each tool description is vector-searched in PostgreSQL pgvector (HNSW index) by cosine similarity, then trimmed at the natural score gap. Only tools that fit the task survive. PostgreSQL pgvector is the source of truth. |
| L3 | Hard ceiling | A final cap of 15 tools is enforced regardless of semantic scores. The model receives a short, sharp list. |
Action queries are scored against their primary servers first and given a similarity boost; context servers contribute a few supporting tools. The selection backend has a resilience fallback chain: pgvector (primary) -> Milvus -> Redis, where the Redis path is an unfiltered all-tools dump used only as a last resort.
Note: The tool selection cascade is a separate concept from the context budget. The cascade decides which tools reach the model; the context budget decides how the model’s context window is spent.
Turn one ships only a small set of built-in meta-tools. The model then calls tool_search to pull in MCP tools as it needs them; discovered tool definitions are appended to the tools array for the same turn (the loop tracks discovered names to avoid re-adding duplicates). A reserved set of always-on tools (memory primitives, data-layer tools, and a handful of domain-essential tools) is never trimmed.
k8s_list_pods, prometheus_query, create_pull_request, web_news_search) with its source server. No keyword map.Context budget
Separate from tool selection, every model has a finite context window. The ContextManagementService tracks token usage and compacts the conversation automatically so the window does not overflow. Token counts use a character-based approximation (roughly 3.5 characters per token for English). Per-model context windows are defined centrally in MODEL_CONTEXT_WINDOWS; there is no global hardcoded limit.
Compaction runs on usage thresholds:
| Usage | Action |
|---|---|
| 70% | Light compaction prep. No messages are dropped yet. |
| 85% | Medium compaction. Old messages are pruned and summarized. |
| 95% | Aggressive compaction. Entire old turns are dropped and a summary is forced. |
Compaction is not on the agent loop’s critical path. It runs in the pre-loop phase of runChat before tool execution begins.
How prompts work
Chat’s system prompt is keyed to your RBAC role, either admin or member, so an operator and a platform admin get a different posture by default. The base prompt is a static file on disk:
prompts/chat-system-admin.mdfor the admin role.prompts/chat-system-member.mdfor the member role.
The role is selected by an isAdmin boolean, and the file is loaded once and cached in memory. Editing the on-disk prompt is a deploy-time change (pull request plus redeploy), which makes it a compliance boundary rather than a runtime toggle.
Note: An optional live override exists. When
RBACSystemPromptServiceis enabled, it reads admin-edited prompts from thesystem_promptstable and invalidates the cache over Redis pub/sub, so changes apply without a rebuild. If the database read fails, the service falls back to the on-disk.mdfile.
The static base is stable; the agent’s current context is injected at runtime. Assembly happens once per loop invocation and stays within a budget of about 5,000 tokens. The injected blocks are:
| Block | Contents |
|---|---|
<session-facts> | Turn 1 only. ISO timestamp, user role, tenant ID, session ID, model in use, prior-turn count. |
<memories> | Persistent user memories recalled via AgentMemoryService.recall() using Milvus embedding-based top-K search (by meaning, not substring match). Capped at 2 KB. |
<tool-catalog> | The list of currently enabled tools, threaded from the live tools array. |
<connected-capabilities> | MCP server availability ground truth (which clouds and clusters are connected, which need authentication). |
<grounding-mode> | Optional. Added when grounding is enabled; injects a web-search verification directive. |
<read-only-mode> | Optional. Added when the platform is in read-only mode; notifies the model that write calls will be rejected. |
Important: Prompt routing is RBAC-role only. There are no per-user custom system prompts. User-specific personalization is delivered through the
<memories>block, not by rewriting prompts. The legacy “intelligence slider” and “prompt module composer” do not exist in chat; both were removed.
The same RBAC that governs the rest of the platform decides which prompt a user gets and which tools they are allowed to call.
Approval and audit
Every tool call is classified as read-only or mutating and written to an append-only audit log. Auditing of every tool call is always on.
Read calls run immediately. When the approval gate is enabled, a mutating call is classified as ask-tier by PermissionService based on glob patterns (e.g., tools matching *_delete_*, *_drop_*, *_truncate_*, etc.). An approval_required event is surfaced to you, and the call waits for a human decision. On timeout, the call is denied. If the platform is in read-only mode, the model is told up front that write calls will be rejected.
The gate fails safe: if an approval cannot be recorded, the mutating call is blocked rather than allowed through.
Note: Tool classification also includes arg-aware inspection for passthrough CLI tools (
call_aws,call_azure,call_gcp,call_kubectl). These tools inspect thecli_commandargument to distinguish read verbs (e.g.,list,get,describe) from mutating verbs (e.g.,create,delete,update), and compound commands (pipes, redirects, &&, etc.) always gate to approval.
Memory
Chat recalls relevant context from past sessions by meaning rather than keyword. Memories are stored as embeddings in Milvus (the agent_memory collection) and recalled with a top-K semantic search through AgentMemoryService.recall(). The recalled memories are injected into the system prompt as the <memories> block (capped at 2 KB), so prior work follows you across sessions.
Note: Cross-session memory recall uses Milvus, which is optional. The default Compose stack runs pgvector-only; enable Milvus (
docker compose --profile milvus up -dwithMILVUS_ENABLED=trueandSKIP_TOOL_SEMANTIC_CACHE=false) to turn on the Milvus-backed memory and RAG features. In pgvector-only mode the platform still runs; the Milvus-backed memory recall stays dormant. See Configuration for the Milvus environment variables.
Extended thinking
Chat supports per-turn extended thinking (when the model supports it). Extended thinking allows the model to reason through complex problems before responding. This is controlled by a per-turn toggle (Z.ET) and can be disabled on individual turns if needed. The thinking process is streamed to the UI for live preview and is included in the message history for subsequent turns.
Self-hosted by default
Chat runs on your infrastructure, against your providers. There is no phone-home and no usage cap. Point a turn at a local model and no data leaves the box; point it at a cloud provider and only that request goes out.
Note: OpenAgentics is v1.0.0 and is not FedRAMP authorized. It is self-hosted; it emits full OpenTelemetry for observability, but nothing leaves your boundary — no export to any external endpoint.
What’s next
- Review the MCP servers and the self-hosted service-account credential model.
- Build deterministic, graph-based automations with Flows.
- Configure providers, auth, and Milvus in Configuration.