fix(chat): graph mode renders the record graph, not cards

In Graph mode, a natural-language request ("graph for John Smith") went
through the getPatient tool, which always emitted record cards — so the
clinician got Summary/Vitals cards instead of a graph (the mode prompt
even wrongly claimed the graph rendered automatically). Thread the
composer mode into the chat tools and have getPatient emit
data-recordGraph in graph mode (matching the client-side /patient
fast-path), with the cards kept for chat/analysis modes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-18 21:43:37 +03:00
parent 5cbc7411c0
commit 1c52dcaf84
2 changed files with 14 additions and 6 deletions
+2 -2
View File
@@ -90,7 +90,7 @@ function modeDirective(mode: string | undefined): string {
return "Mode — Analysis: the clinician wants interpretation, not just retrieval. After fetching a patient's data, surface patterns and correlations across their problems, labs and visits (e.g. recurring complaints, trends, likely links) and call out anything notable. Stay grounded in the tool results.";
}
if (mode === "graph") {
return "Mode — Graph: the clinician wants to see how a patient's problems and visits connect. When they reference a patient, call getPatient (its record graph renders automatically) and briefly describe the key relationships between illnesses and encounters.";
return "Mode — Graph: the clinician wants to see how a patient's problems and visits connect. When they reference a patient, call getPatient — in this mode it renders the patient's record GRAPH (not cards) automatically — then briefly describe the key relationships between illnesses and encounters. Do not say you cannot draw a graph; getPatient produces it.";
}
return "";
}
@@ -222,7 +222,7 @@ chatRouter.post("/", async (req, res, next) => {
});
}
const tools = createChatTools({ ...ctx, veil, writer });
const tools = createChatTools({ ...ctx, mode, veil, writer });
if (resolved.isExternal && veil.active) {
// Non-streamed pass so we can rehydrate identifier tokens before the
+12 -4
View File
@@ -33,6 +33,9 @@ export type ToolContext = {
// The signed-in clinician — needed to scope task visibility (and to stamp the
// creator when an add is committed via the REST endpoints on approval).
viewer: { userId: string; userName: string; memberRole: string };
// The composer's "situation" mode (chat | analysis | graph). In graph mode
// getPatient renders the record graph instead of the record cards.
mode?: string;
veil: Veil;
writer: UIMessageStreamWriter;
};
@@ -57,7 +60,7 @@ function forModel(p: Patient) {
}
export function createChatTools(ctx: ToolContext) {
const { orgId, demographicsOnly, scopeProviderId, viewer, veil, writer } =
const { orgId, demographicsOnly, scopeProviderId, viewer, mode, veil, writer } =
ctx;
// Emit a Chain-of-Thought step to the UI as the agent works. Steps stream live
@@ -86,7 +89,7 @@ export function createChatTools(ctx: ToolContext) {
// Look up one patient by file number (MRN) and show their record cards.
getPatient: tool({
description:
"Retrieve a patient's full record by file number (MRN) and display it as record cards. Use when the clinician asks about a specific patient.",
"Retrieve a patient's full record by file number (MRN). Displays it as record cards (or, in Graph mode, as the patient's record graph). Use when the clinician asks about a specific patient.",
inputSchema: z.object({
fileNumber: z
.string()
@@ -102,8 +105,13 @@ export function createChatTools(ctx: ToolContext) {
scopeProviderId,
);
if (!patient) return { found: false as const, fileNumber };
// Real data → clinician UI (cards). Redacted data → model.
writer.write({ type: "data-patientCard", data: patient });
// Real data → clinician UI. In graph mode render the record graph; in
// chat/analysis modes render the record cards. Redacted data → model.
writer.write(
mode === "graph"
? { type: "data-recordGraph", data: patient }
: { type: "data-patientCard", data: patient },
);
return { found: true as const, patient: forModel(veil.redactPatient(patient)) };
},
}),