mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(mcp): stabilize lab search pagination (#578)
This commit is contained in:
1 parent
b20f1b5c66
commit
0d5d61bc36
3 files changed
+48
No files matched your search
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- **MCP search cursors keep lab results stable across pages.** Distinct analyte
|
||||
names are ordered before offset pagination, preventing repeated or skipped
|
||||
lab entries when a client follows `nextCursor`.
|
||||
|
||||
## [1.31.7] — 2026-07-20
|
||||
|
||||
- **Current OpenAI reasoning models use their supported request contract.**
|
||||
|
||||
@@ -120,6 +120,49 @@ describe("search", () => {
|
||||
expect(result.results.map((r) => r.id)).toContain("lab:LDL");
|
||||
expect(result.results.some((r) => r.id.startsWith("med:"))).toBe(false);
|
||||
});
|
||||
it("keeps distinct lab analytes stable across cursor pages", async () => {
|
||||
vi.mocked(buildCoachDataInventory).mockResolvedValue({
|
||||
entries: [],
|
||||
window: "90d",
|
||||
restMode: false,
|
||||
cycleEnabled: false,
|
||||
} as never);
|
||||
vi.mocked(prisma.medication.findMany).mockResolvedValue([]);
|
||||
|
||||
const analytes = Array.from({ length: 60 }, (_, index) => ({
|
||||
analyte: `Analyte ${String(index).padStart(2, "0")}`,
|
||||
}));
|
||||
let callCount = 0;
|
||||
vi.mocked(prisma.labResult.findMany).mockImplementation((args) => {
|
||||
const ordered =
|
||||
(args as { orderBy?: { analyte?: string } }).orderBy?.analyte === "asc";
|
||||
const rows =
|
||||
ordered || callCount++ % 2 === 0 ? analytes : [...analytes].reverse();
|
||||
return Promise.resolve(rows) as ReturnType<
|
||||
typeof prisma.labResult.findMany
|
||||
>;
|
||||
});
|
||||
|
||||
const def = tool("search");
|
||||
const first = (await def.run(CTX, { query: "" })) as {
|
||||
results: Array<{ id: string }>;
|
||||
nextCursor?: string;
|
||||
};
|
||||
const second = (await def.run(CTX, {
|
||||
query: "",
|
||||
cursor: first.nextCursor,
|
||||
})) as {
|
||||
results: Array<{ id: string }>;
|
||||
};
|
||||
|
||||
const labIds = [...first.results, ...second.results]
|
||||
.map((result) => result.id)
|
||||
.filter((id) => id.startsWith("lab:"));
|
||||
expect(new Set(labIds)).toHaveLength(60);
|
||||
expect(prisma.labResult.findMany).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ orderBy: { analyte: "asc" } }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fetch", () => {
|
||||
|
||||
@@ -385,6 +385,7 @@ function searchAndFetchTools(): McpToolDefinition[] {
|
||||
where: { userId: ctx.userId, deletedAt: null },
|
||||
select: { analyte: true },
|
||||
distinct: ["analyte"],
|
||||
orderBy: { analyte: "asc" },
|
||||
take: SEARCH_RESULT_SCAN_CAP,
|
||||
});
|
||||
for (const lab of labs) {
|
||||
|
||||
Reference in new issue
Block a user