From 9d2d10d1fa20b442ca06e2e156a5aaed8afef5d1 Mon Sep 17 00:00:00 2001 From: openperf <16864032@qq.com> Date: Sun, 3 May 2026 16:17:22 +0800 Subject: [PATCH] test: cover IPv4-mapped loopback URL and maxTokens num_ctx fallback --- extensions/ollama/src/stream-runtime.test.ts | 29 +++++++++++++++++++ .../run/llm-idle-timeout.test.ts | 13 +++++++++ 2 files changed, 42 insertions(+) diff --git a/extensions/ollama/src/stream-runtime.test.ts b/extensions/ollama/src/stream-runtime.test.ts index 5adbaded8bb..1d4dea85289 100644 --- a/extensions/ollama/src/stream-runtime.test.ts +++ b/extensions/ollama/src/stream-runtime.test.ts @@ -1713,6 +1713,35 @@ describe("createOllamaStreamFn", () => { ); }); + it("falls back to catalog maxTokens as num_ctx when contextWindow is absent", async () => { + await withMockNdjsonFetch( + [ + '{"model":"m","created_at":"t","message":{"role":"assistant","content":"ok"},"done":false}', + '{"model":"m","created_at":"t","message":{"role":"assistant","content":""},"done":true,"prompt_eval_count":1,"eval_count":1}', + ], + async (fetchMock) => { + const stream = await createOllamaTestStream({ + baseUrl: "http://ollama-host:11434", + // The helper default contextWindow is overridden back to undefined so + // the right side of `model.contextWindow ?? model.maxTokens` is the + // load-bearing branch. + model: { contextWindow: undefined, maxTokens: 65536 }, + }); + + await collectStreamEvents(stream); + + const requestInit = getGuardedFetchCall(fetchMock).init ?? {}; + if (typeof requestInit.body !== "string") { + throw new Error("Expected string request body"); + } + const requestBody = JSON.parse(requestInit.body) as { + options?: { num_ctx?: number }; + }; + expect(requestBody.options?.num_ctx).toBe(65536); + }, + ); + }); + it("maps configured native Ollama params.thinking=max to the stable top-level think value", async () => { await withMockNdjsonFetch( [ diff --git a/src/agents/pi-embedded-runner/run/llm-idle-timeout.test.ts b/src/agents/pi-embedded-runner/run/llm-idle-timeout.test.ts index de03d8244fb..151efee66c5 100644 --- a/src/agents/pi-embedded-runner/run/llm-idle-timeout.test.ts +++ b/src/agents/pi-embedded-runner/run/llm-idle-timeout.test.ts @@ -124,6 +124,19 @@ describe("resolveLlmIdleTimeoutMs", () => { expect(resolveLlmIdleTimeoutMs({ model: { baseUrl } })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS); }); + // Node's URL parser normalizes every IPv4-mapped loopback form + // (`::ffff:127.0.0.1`, `::ffff:7F00:1`, mixed case, …) to the canonical + // `::ffff:7f00:1`. Exercise the user-facing input shapes here so the full + // parse → lowercase → bracket-strip → exact-match chain is regression-tested + // against future URL parser behavior, not just the canonical literal. + it.each([ + "http://[::ffff:127.0.0.1]:11434", + "http://[::ffff:7f00:1]:11434", + "http://[::FFFF:127.0.0.1]:11434", + ])("disables the default idle watchdog for IPv4-mapped loopback baseUrl %s", (baseUrl) => { + expect(resolveLlmIdleTimeoutMs({ model: { baseUrl } })).toBe(0); + }); + it.each([ // Just outside fc00::/7 (fe.. and 00fc::/16 are not unique-local). "http://[fec0::1]:11434",