Files
temetro/frontend/lib/ai-chat.ts
T
Khalid Abdi 31d86bb5dd frontend: wire chat to the real agent + lab charts + import approval
Replace the mock chat with the live backend agent:
- chat-panel uses @ai-sdk/react useChat against /api/chat (credentials included),
  passing the selected model + effort per send. The `/patient <file#>` fast-path
  is kept as an instant client-side shortcut.
- Renders the agent's streamed data parts: patientCard → record cards
  (PatientResult), labCard → new LabChartCard (visx area chart with a high/low
  flag badge in the top-right corner + recent values), importPreview →
  ImportPreviewCard (the human approval gate: review counts/issues, then commit
  via POST /api/ai/import — nothing is written until approved).
- Veil consent: a one-time dialog before the first send to a cloud model,
  explaining that identifiers are de-identified before leaving the clinic.
- Attached text files (csv/json/txt…) now include their content in the message
  so the agent can parse an export for import.

Shared chat message/data-part types in lib/ai-chat.ts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 18:44:20 +03:00

38 lines
1.1 KiB
TypeScript

import type { UIMessage } from "ai";
import type { Lab, Patient, Trend } from "@/lib/patients";
// Custom data parts the backend agent streams alongside its text. They carry
// REAL (un-redacted) record data straight to the clinician's screen for rich
// rendering — the model itself only ever sees Veil-redacted tool results.
export type LabCardData = {
fileNumber: string;
name: string;
labs: Lab[];
labTrend: Trend;
};
export type ImportPreviewData = {
// Validated, ready-to-commit records (server re-validates on commit).
valid: unknown[];
invalid: { index: number; errors: string[] }[];
total: number;
};
export type VeilNoticeData = {
provider: string;
level: string;
};
// Maps each data part name → its payload. Part `type` strings are the key
// prefixed with `data-` (e.g. `data-patientCard`), per the AI SDK convention.
export type TemetroDataParts = {
patientCard: Patient;
labCard: LabCardData;
importPreview: ImportPreviewData;
veilNotice: VeilNoticeData;
};
export type TemetroUIMessage = UIMessage<never, TemetroDataParts>;