Documentation Index
Fetch the complete documentation index at: https://docs.usecompassai.com/llms.txt
Use this file to discover all available pages before exploring further.
The chat agent translates natural language into a structured plan, asks the user for any missing detail, and hands off. It never signs transactions, never bypasses the policy engine, and is constrained by a fabrication detector that catches plans referencing things that don’t exist.This is the only component in Compass that calls a language model. Everything else — scheduling, evaluation, policy checks, signing — runs on deterministic code. See The deterministic loop for what’s on the other side of the handoff.
What the chat agent does
The chat agent has three jobs, in order:- Parse the user’s intent. Take a free-text message like
"move 5 USDC to the best lending venue on an L2"and identify the action, amount, target protocol, and target chain. - Fill in missing detail. If the user named a protocol that’s whitelisted on multiple chains, ask which chain. If the amount is ambiguous, ask. The agent never guesses on safety-relevant fields.
- Emit a structured plan. Once everything is unambiguous, produce a
JSON
Planobject and hand it to the deterministic layer.
The Plan schema
The chat agent’s output is constrained to a fixed JSON schema. The LLM is called with structured-output enforcement — it cannot return free-form text when generating a plan, only validPlan JSON or a clarification question.
- All enum fields are whitelisted.
target_chain,target_protocol, andactioncan only contain values the system recognizes. The LLM cannot fabricate a protocol name — the structured-output layer rejects it before it reaches the deterministic engine. - Amounts are strings, in micro-USDC. No floating-point parsing risk; the LLM has to commit to an exact integer the user can verify.
requires_user_confirmationis always true for routes that move funds. The chat agent cannot generate a “silent execute” plan even if the user asks for one.
How fabrication is caught
Structured output prevents most LLM hallucination by construction — the model can’t return a protocol name that isn’t in the enum. But it can still generate plans that are structurally valid but semantically wrong. For example:- A plan to supply more USDC than the user has.
- A plan targeting a
(protocol, chain)pair the user’s policy doesn’t whitelist. - A plan with an
amount_usdcthat doesn’t match what the user typed.
Fabrication detector
Between the LLM output and the handoff to the deterministic layer, a detector runs a small set of semantic checks:- Reference check. Every entity in the plan (protocol, chain, action) is verified against the live registry. Pairs that exist in the schema but not in the current deployment are flagged.
- Quantity check.
amount_usdcis checked against the user’s balance and against any number explicitly mentioned inuser_message. A plan for “5 USDC” that emits5000000000(5000 USDC) is rejected. - Action check. The
actionfield is checked against what thetarget_protocol’s facet actually supports.
Corrective re-prompt
When the detector rejects a plan, the original user message is re-sent to the LLM with the detector’s failure injected as an additional instruction:Clarification turns
When the user’s intent is incomplete, the chat agent does not fill in defaults. Instead it emits aClarification rather than a Plan:
Plan with the additional context.
The asymmetry here is intentional: the chat agent is encouraged to ask
clarifying questions and discouraged from guessing. Guessing wrong on
target_chain could send USDC to the wrong place; asking adds one turn but
guarantees the user agreed.
What the chat agent doesn’t do
| Action | Done by |
|---|---|
| Validate the plan against the user’s rules | Policy engine |
| Sign or broadcast transactions | Session keys |
| Decide when to re-evaluate a position | Deterministic loop (scheduler) |
| Move USDC across chains | Circle Gateway |
| Write to the audit trail | The component performing the action; the chat agent’s output is logged by the layer below |
user_message, or a model that simply gets confused cannot
escalate beyond producing a Plan that the policy engine will check and the
session key will validate again on-chain.
When does the chat agent run
Unlike the deterministic loop, the chat agent runs only when the user sends a message. It is not part of any scheduled or event-driven path. For a typical account:- The deterministic loop ticks dozens of times a day on yield-source updates.
- The chat agent runs zero to a few times — only when the user actively chats.
EvaluatorThought
records originate from a chat-generated plan. The other 95%+ come from the
event-driven scheduler with no LLM involvement at all.
Next steps
The deterministic loop
What happens on the other side of the handoff.
Policy engine
Every chat-generated plan goes through this gate.
Audit trail
How chat-originated plans are tagged and recorded.
System overview
Back to the full three-layer picture.