feat(odin): Phase 2a read-only agentic assistant + tool-trace UI
- agentic chat loop (max 6 round-trips, budget re-checked between iterations) over 10 read-only, permission-delegated tools in src/services/ai-tools.ts - persist assistant tool trace in ai_chat_messages.content_json (+ migration) - consulted-tools chips in OdinThread; header now shows month spend only (budget cap hidden from the UI, server-side 402 guard unchanged) - seed: ai.use permission; Settings exposes the ai permission module - docs: REVIEW consolidation; deployment-guide.md superseded by docs/release.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
31
CLAUDE.md
31
CLAUDE.md
@@ -291,15 +291,28 @@ CSP blocks it and it would leak the secret).
|
||||
|
||||
## AI Assistant — "Odin"
|
||||
|
||||
Admin-only (`ai.use` permission) Claude assistant at `/odin`. **Phase-1 scope
|
||||
is invoice import ONLY** — general chat is guarded off in `OdinChat.submit`
|
||||
(text-only messages get a canned reply, no API call). Backend
|
||||
`src/services/ai.service.ts` + `src/routes/admin/ai.ts`; per-call cost ledger
|
||||
in `ai_usage` with a monthly budget cap (402 when exceeded). Invoice flow:
|
||||
PDF → `extract-invoices` (structured output) → review cards → existing
|
||||
`POST /received-invoices`. **`received_invoices.amount` is GROSS
|
||||
(VAT-inclusive)** — VAT is back-calculated (`vatFromGross`). Phase-2 design
|
||||
notes live in `docs/superpowers/specs/`.
|
||||
`ai.use`-gated Claude assistant at `/odin` (granted to admin). **Phase 2a:
|
||||
read-only agentic assistant** — chat turns run an agentic loop
|
||||
(`agenticChat` in `src/services/ai.service.ts`, max 6 round-trips, budget
|
||||
re-checked between iterations) over the read-only tools in
|
||||
`src/services/ai-tools.ts` (invoices, offers, orders, projects, customers,
|
||||
warehouse, attendance).
|
||||
|
||||
**Security model (do not weaken):** Odin is the **user's delegate** — the
|
||||
tool list is pre-filtered by the caller's permissions AND every handler
|
||||
re-checks them (`ctxCan`); there are **NO write tools** (writes come in
|
||||
Phase 2b as propose→confirm action cards, never autonomous). Tool handlers
|
||||
call the same service functions the routes use. Assistant turns persist
|
||||
their tool trace in `ai_chat_messages.content_json` (plain `content` stays
|
||||
the display text); the UI shows consulted-tool chips. The system prompt
|
||||
enforces plain-text replies (the chat renders pre-wrap text, no Markdown).
|
||||
|
||||
Per-call cost ledger in `ai_usage` with a monthly budget cap (402 when
|
||||
exceeded). Invoice flow unchanged: PDF → `extract-invoices` (structured
|
||||
output) → review cards → existing `POST /received-invoices`.
|
||||
**`received_invoices.amount` is GROSS (VAT-inclusive)** — VAT is
|
||||
back-calculated (`vatFromGross`). Phase-2 design notes live in
|
||||
`docs/superpowers/specs/`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user