feat: upgrade investigation and presentation runtime
Generic Container CI/CD / test-build-publish (push) Successful in 1m6s
Agent CI/CD / build-test-publish-and-deploy (push) Successful in 1m7s

This commit is contained in:
2026-10-30 17:30:19 +08:00
parent 3b52a0ddab
commit 6336157ff4
104 changed files with 6541 additions and 961 deletions
+17 -22
View File
@@ -1,34 +1,29 @@
import { expect, it } from "bun:test";
import type { Tool } from "@modelcontextprotocol/client";
import { nativeQueryTimeout, queryTimeouts } from "../../src/mcp/query-timeouts.js";
import { boundedQuery, nativeQueryTimeout, queryTimeouts } from "../../src/mcp/query-timeouts.js";
const simulation: Tool = { name: "run_simulation", inputSchema: { type: "object", properties: {
timeout_seconds: { type: "integer", minimum: 1, maximum: 3600, default: 120 },
timeout_seconds: { type: "integer", minimum: 1, maximum: 240, default: 120 },
} } };
it("budgets calculations independently from their simulated duration and from ordinary reads", () => {
expect(queryTimeouts(simulation, { duration: 86400, timeout_seconds: 900 })).toEqual({ executionMs: 900_000, callMs: 30_000, requestMs: 35_000 });
expect(queryTimeouts(simulation, {})).toEqual({ executionMs: 120_000, callMs: 30_000, requestMs: 35_000 });
expect(queryTimeouts({ name: "list_elements", inputSchema: { type: "object" } }, {})).toEqual({ executionMs: 30_000, callMs: 30_000, requestMs: 35_000 });
it("keeps HTTP budgets host-owned and separate from calculation duration", () => {
expect(queryTimeouts(simulation, { duration: 86400, timeout_seconds: 240 })).toEqual({ serverMs: 120_000, callMs: 180_000, requestMs: 180_000 });
expect(queryTimeouts({ name: "list_elements", inputSchema: { type: "object" }, _meta: {
"io.tjwater/request-timeout": { defaultSeconds: 240, maxSeconds: 240 },
} }).requestMs).toBe(270_000);
expect(nativeQueryTimeout([simulation])).toBe(300_000);
expect(nativeQueryTimeout([])).toBe(300_000);
});
it("honors the effective advertised maximum and rejects invalid per-call budgets", () => {
for (const timeout_seconds of [0, -1, 1.5, 3601, "900", null, true, NaN, Infinity]) {
expect(() => queryTimeouts(simulation, { timeout_seconds })).toThrow();
it("falls back safely for malformed advertised budgets", () => {
for (const metadata of [null, [], { defaultSeconds: 999, maxSeconds: 999 }, { defaultSeconds: 240, maxSeconds: 120 }, { defaultSeconds: "120", maxSeconds: 240 }]) {
expect(queryTimeouts({ ...simulation, _meta: { "io.tjwater/request-timeout": metadata } }).requestMs).toBe(180_000);
}
const limited = { ...simulation, inputSchema: { type: "object" as const, properties: {
timeout_seconds: { type: "integer", maximum: 120, default: 120 },
} } };
expect(queryTimeouts(limited, { timeout_seconds: 120 }).executionMs).toBe(120_000);
expect(() => queryTimeouts(limited, { timeout_seconds: 121 })).toThrow();
expect(nativeQueryTimeout([simulation, limited])).toBe(35_000);
expect(nativeQueryTimeout([limited])).toBe(35_000);
expect(queryTimeouts({ ...simulation, inputSchema: { type: "object", properties: {
timeout_seconds: { type: "integer", maximum: 3600, default: 1800 },
} } }).requestMs).toBe(180_000);
});
it("uses the catalog's thirty-minute burst-location default as a worker execution budget", () => {
const location: Tool = { name: "run_burst_location", inputSchema: { type: "object", properties: {
timeout_seconds: { type: "integer", minimum: 1, maximum: 3600, default: 1800 },
} } };
expect(queryTimeouts(location, {})).toEqual({ executionMs: 1_800_000, callMs: 30_000, requestMs: 35_000 });
expect(nativeQueryTimeout([location])).toBe(35_000);
it("returns on deadline even when the underlying adapter ignores cancellation", async () => {
await expect(boundedQuery(() => new Promise(() => {}), AbortSignal.timeout(10))).rejects.toThrow();
});