feat(chat): file attachments as chips, CoT closed, AI add-to-inventory

Chat fixes (#1/#6/#7):
- chat-input passes raw File[] up instead of inlining file text
- chat-panel sends files as FileUIPart and renders them with the
  ai-elements Attachments component (no more raw text dumps)
- backend extracts text-like file content for the model in routes/chat
- Chain-of-Thought now defaults to collapsed
- file upload works regardless of whether the input has text

AI add-to-inventory (#2):
- new proposeInventory tool (validates items, streams an approval card)
- system prompt distinguishes stocking inventory vs. billing a patient
- ActionPreviewCard commits inventory via POST /api/inventory

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-15 18:27:43 +03:00
parent 3aa699aefe
commit 6e5598262e
7 changed files with 235 additions and 51 deletions
+2 -1
View File
@@ -56,7 +56,8 @@ export type ActionPreviewKind =
| "appointment"
| "task"
| "prescription"
| "invoice";
| "invoice"
| "inventory";
export type ActionPreviewData = {
token: string;
kind: ActionPreviewKind;
@@ -795,7 +795,8 @@
},
"queue": {
"label": "Queued · {{count}}",
"remove": "Remove from queue"
"remove": "Remove from queue",
"attachmentsOnly": "{{count}} attachment(s)"
},
"veil": {
"title": "Veil",
@@ -810,14 +811,17 @@
"appointment": "Proposed appointment",
"task": "Proposed task",
"prescription": "Proposed prescription",
"invoice": "Proposed invoice"
"invoice": "Proposed invoice",
"inventory": "Proposed inventory"
},
"kind": {
"appointment": "Appointment added.",
"task": "Task added.",
"prescription": "Prescription added.",
"invoice": "Invoice added."
"invoice": "Invoice added.",
"inventory": "Inventory updated."
},
"inventoryItems": "{{count}} item(s)",
"approve": "Add",
"adding": "Adding…",
"discard": "Discard",