fix(mcp): declare labs availability metadata

(cherry picked from commit c1a5861fdcbfe374fcbb5362eed3717a5bd9b15d)
This commit is contained in:
Usama Muhammad committed 2026-10-25 22:29:12 +11:00
1 parent cf61bd1c85
commit 93fb0f68d8
2 files changed
+48 -5

No files matched your search

+46
View File
@@ -510,6 +510,52 @@ describe("get_illness_recovery — condition body site", () => {
});
describe("get_labs", () => {
it.each([{}, { analyte: "LDL" }])(
"declares empty-read availability for ordinary and filtered reads: %j",
async (args) => {
const { z } = await import("zod/v4");
const empty = {
present: false,
reason: "out_of_window",
searchedWindow: "lastYear",
available: {
count: 2,
firstDate: "2020-01-01",
lastDate: "2020-01-02",
reachableWithWindow: null,
},
};
vi.mocked(executeCoachTool).mockResolvedValue(empty);
const def = tool("get_labs");
const result = await def.run(CTX, args);
expect(executeCoachTool).toHaveBeenCalledWith({
userId: CTX.userId,
name: "get_labs",
rawArguments: JSON.stringify(args),
});
expect(z.object(def.outputShape!).strict().parse(result)).toEqual(empty);
},
);
it("keeps output validation closed and availability typed", async () => {
const { z } = await import("zod/v4");
const schema = z.object(tool("get_labs").outputShape!).strict();
expect(z.toJSONSchema(schema).additionalProperties).toBe(false);
expect(schema.safeParse({ present: false, unexpected: true }).success).toBe(
false,
);
expect(
schema.safeParse({ present: false, searchedWindow: 7 }).success,
).toBe(false);
expect(
schema.safeParse({ present: false, available: { count: "2" } }).success,
).toBe(false);
expect(schema.parse({ present: false, reason: "no_data" })).toEqual({
present: false,
reason: "no_data",
});
});
it("forwards the optional analyte filter and returns readings with units + bands", async () => {
vi.mocked(executeCoachTool).mockResolvedValue({
present: true,
+2 -5
View File
@@ -1201,11 +1201,8 @@ const listMetricsOutput: z.ZodRawShape = {
/** Output schema for `get_labs` — latest-per-biomarker OR a paginated history. */
const getLabsOutput: z.ZodRawShape = {
present: z.boolean(),
reason: z.string().optional(),
// Latest-mode payload (the Coach labs section, carried opaque).
data: z.unknown().optional(),
grounding: z.string().optional(),
// Latest-mode payload, including typed empty-read availability metadata.
...coachReadOutput,
// History-mode payload (per-analyte trajectory + pagination).
analyte: z.string().optional(),
readings: z