AI Capabilities and Guardrails
This page describes what the Cashlytics AI assistant can do, what it is explicitly not allowed to do, and where human approval is required.
All statements are derived from runtime behavior in:
cashlytics/src/app/api/chat/route.tscashlytics/src/lib/ai/tools.tscashlytics/src/lib/auth/require-auth.tscashlytics/src/proxy.tscashlytics/src/components/molecules/chat-message.tsxcashlytics/src/components/molecules/tool-confirmation-card.tsx
Scope: what the AI is designed for
The assistant is finance-scoped. It is intended to help with:
- expenses (one-time and recurring)
- incomes
- accounts and balances
- transfers
- category management
- analytics and forecasting
The system prompt in route.ts enforces this scope and instructs the model to refuse non-finance topics.
What the AI can do
Read operations
The assistant can read user-owned financial data via tools:
- accounts (
getAccounts) - categories (
getCategories) - recurring expenses (
getExpenses) - one-time expenses (
getDailyExpenses) - incomes (
getIncomes) - transfers (
getTransfers) - monthly overview (
getMonthlyOverview) - forecast (
getForecast) - category breakdown (
getCategoryBreakdown) - normalized monthly expenses (
getNormalizedMonthlyExpenses)
Write operations
The assistant can prepare write actions for:
- create/update/delete account
- create/update/delete recurring expense
- create/update/delete one-time expense
- create/update/delete income
- create category
- create transfer
Every write action is gated by explicit user approval before execution.
What the AI is not allowed to do
Out-of-domain requests
The prompt instructs the model to handle only finance requests and refuse unrelated requests (for example weather, coding, music, sports).
Document and file content access
The assistant must not read uploaded user documents (receipts, invoices, statements). This is explicitly stated in the chat system prompt.
In addition, tool outputs use explicit response allowlists for expense retrieval and intentionally exclude document payloads from AI context.
Unauthenticated access
The assistant does not bypass authentication:
- route protection in
proxy.tsrequires login for protected routes, including chat - server actions called by tools enforce
requireAuth() - unauthenticated access resolves to
Unauthorized
Human-in-the-loop approvals
The tool catalog marks write and destructive actions with needsApproval: true.
At runtime, this means:
- the assistant proposes a tool action
- the UI shows a confirmation card
- the user must accept or deny
- only accepted actions are executed
Approval UI behavior is implemented in:
chat-message.tsx(renders pending approval parts)tool-confirmation-card.tsx(accept/deny controls with operation summary)
Runtime safety limits
The chat endpoint enforces several hard limits:
- rate limiting:
20requests per minute per IP - message payload limit:
100messages per request - tool/reasoning step cap:
stepCountIs(10) - invalid JSON or invalid message shape returns
400
These controls reduce abuse and runaway tool execution.
Behavioral notes for developers
- The model is instructed to respond in German in the system prompt.
- For expense capture, the prompt pushes category-first behavior and asks for category confirmation when needed.
- The prompt also injects current date plus account/category context to reduce unnecessary discovery calls.
Practical expectation for users
- The assistant can automate common finance workflows quickly.
- The assistant cannot act outside finance scope.
- The assistant cannot read uploaded document content.
- Sensitive modifications are never silent; they always require explicit approval.