Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
b21459e
fix: surface Ollama recovery failures
prekshivyas Sep 2, 2026
433c1b2
test: keep Windows readiness coverage behavioral
prekshivyas Sep 2, 2026
cff68c1
fix: harden Ollama recovery diagnostics
prekshivyas Sep 2, 2026
d119c19
fix: preserve Ollama recovery display semantics
prekshivyas Sep 2, 2026
d2fe951
fix: make Ollama recovery actionable
prekshivyas Sep 2, 2026
e8a9d98
test: validate Ollama readiness URL semantics
prekshivyas Sep 2, 2026
31460b7
fix: constrain Ollama recovery safety
prekshivyas Sep 2, 2026
6de489f
fix: share Ollama recovery deadline
prekshivyas Sep 2, 2026
fb700e2
Merge remote-tracking branch 'origin/main' into pr-10855-probe-bounds
prekshivyas Sep 2, 2026
d065f67
fix(agent): bound Ollama recovery probes
prekshivyas Sep 2, 2026
d071aaf
fix(agent): finish Ollama recovery follow-up
prekshivyas Sep 2, 2026
136ca06
fix: reject invalid Ollama status shapes
prekshivyas Sep 2, 2026
6767b5f
fix: preserve Ollama recovery diagnostics
prekshivyas Sep 2, 2026
eace473
fix(agent): make Ollama recovery interruptible
prekshivyas Sep 2, 2026
8698c48
Merge remote-tracking branch 'origin/main' into pr-10855-advisor-4
prekshivyas Sep 2, 2026
0643151
fix(doctor): reject invalid Ollama inventory
prekshivyas Sep 2, 2026
24e1942
Merge remote-tracking branch 'origin/codex/fix-ollama-review-followup…
prekshivyas Sep 2, 2026
713b22b
test(inference): prove Ollama receipt retirement
prekshivyas Sep 2, 2026
55f3308
merge: sync concurrent PR updates
prekshivyas Sep 2, 2026
3def062
fix(ollama): consolidate isolated recovery probes
prekshivyas Sep 2, 2026
b7645e4
fix(inference): unify Windows Ollama probes
prekshivyas Sep 2, 2026
26d64ee
merge: reconcile concurrent Ollama probe follow-ups
prekshivyas Sep 2, 2026
ca8a31d
fix(inference): remove redundant status fallback
prekshivyas Sep 2, 2026
8168f2c
fix(ollama): restore Windows state after failed rebind
prekshivyas Sep 2, 2026
b778698
test(ollama): verify restart recovery boundaries
prekshivyas Sep 2, 2026
72685a9
test(ollama): model Windows rollback state
prekshivyas Sep 2, 2026
802e353
fix(ollama): restore Windows state on interrupt
prekshivyas Sep 2, 2026
6690fb9
refactor(ollama): name Windows launch attempts
prekshivyas Sep 2, 2026
957776b
refactor(inference): reuse validated doctor inventory
prekshivyas Sep 2, 2026
8e8f3b5
fix(inference): validate discovered Ollama inventory
prekshivyas Sep 2, 2026
ca75e6c
fix(cli): keep Ollama rollback state out of argv
prekshivyas Sep 2, 2026
bd77a21
refactor(cli): reuse Ollama transport owner
prekshivyas Sep 2, 2026
3a952ef
fix(cli): roll back failed Windows installs
prekshivyas Sep 2, 2026
805b0ac
fix(cli): roll back abandoned Windows restarts
prekshivyas Sep 2, 2026
087b940
test(cli): isolate doctor Ollama inventory
prekshivyas Sep 2, 2026
9423bb8
fix(cli): align Windows Ollama diagnostics
prekshivyas Sep 2, 2026
e4d1570
test(policy): assert missing OpenShell exit
prekshivyas Sep 2, 2026
15aa6a8
fix(cli): close Windows Ollama review gaps
prekshivyas Sep 2, 2026
3309602
fix(deps): update transitive fast-uri security patch
prekshivyas Sep 2, 2026
0611fde
merge: resolve conflicts with main
github-actions[bot] Sep 2, 2026
6681f6a
merge: sync main for CI
prekshivyas Sep 2, 2026
ad04a91
test(onboard): use exact Ollama URL assertion
prekshivyas Sep 3, 2026
156f1fc
merge: sync main for CI
prekshivyas Sep 3, 2026
e523825
fix(agent): resolve ambiguous Ollama recovery host
prekshivyas Sep 3, 2026
aec4513
merge(main): resolve conflicts for #10855
prekshivyas Sep 3, 2026
d3286d2
fix(ollama): make recovery rollback transactional
prekshivyas Sep 3, 2026
a6e5be4
test(ollama): cover guarded provider host probe
prekshivyas Sep 3, 2026
4b83043
fix(ollama): terminate pre-sentinel installer
prekshivyas Sep 3, 2026
cb67f74
merge: update Ollama recovery from main
prekshivyas Sep 5, 2026
561e44f
test(inference): align protected Windows route fixtures
prekshivyas Sep 5, 2026
680d3a7
test(inference): run doctor fixture across test modes
prekshivyas Sep 5, 2026
e55ea2e
Merge remote-tracking branch 'origin/main' into codex/fix-ollama-revi…
prekshivyas Sep 5, 2026
6494b03
Merge remote-tracking branch 'origin/main' into codex/fix-ollama-revi…
prekshivyas Sep 5, 2026
c948b80
fix(inference): bound Windows Ollama cancellation
prekshivyas Sep 5, 2026
35751ed
fix(agent): force timed-out Ollama recovery exit
prekshivyas Sep 5, 2026
bdf3bdd
merge: refresh from upstream main
prekshivyas Sep 6, 2026
e93da29
fix(onboard): bound Windows installer PID prefix
prekshivyas Sep 6, 2026
6ac0a77
test(onboard): remove duplicate Windows boundary suite
prekshivyas Sep 7, 2026
a89c99a
docs(inference): document Windows installer recovery
prekshivyas Sep 6, 2026
08047c6
merge: refresh from upstream main
prekshivyas Sep 8, 2026
90eb9a7
fix(inference): address Ollama review findings
prekshivyas Sep 8, 2026
169620a
test(inference): compose Windows warmup guards
prekshivyas Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 97 additions & 16 deletions src/lib/actions/sandbox/agent/ollama-restart-recovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import { describe, expect, it, vi } from "vitest";
import { OLLAMA_PORT, OLLAMA_PROXY_PORT } from "../../../core/ports";
import { prepareOllamaApiExecution } from "../../../inference/local";
import {
maybeWarmOllamaAfterDaemonRestart,
type OllamaRestartRecoveryDeps,
Expand Down Expand Up @@ -76,14 +75,9 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
runCaptureImpl,
runCaptureExImpl,
prepareDockerEnvironment,
prepareOllamaApiExecution: (command, host, options) =>
prepareOllamaApiExecution(command, host, {
...options,
prepareDockerEnvironment,
}),
},
),
).toEqual({ kind: "warmed", ok: true, timedOut: false });
).toEqual({ kind: "warmed", ok: true });

expect(getCommandUrl(runCaptureImpl.mock.calls[0][0])).toBe(
`http://host.docker.internal:${OLLAMA_PORT}/api/ps`,
Expand Down Expand Up @@ -199,7 +193,11 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
{ provider: "ollama-local", model: "qwen3.6:35b" },
{ runCaptureImpl: () => "", runCaptureExImpl },
),
).toEqual({ kind: "skipped", reason: "unreachable" });
).toEqual({
kind: "skipped",
reason: "unreachable",
endpoint: `http://127.0.0.1:${OLLAMA_PORT}`,
});
expect(runCaptureExImpl).not.toHaveBeenCalled();
});

Expand All @@ -219,13 +217,97 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
).toEqual({
kind: "warmed",
ok: false,
timedOut: true,
reason: "timeout",
endpoint: "http://127.0.0.1:11434",
detail: "warm-up exceeded 300 seconds",
});
});

it("limits warm-up to the command timeout budget remaining after the probe", () => {
let nowMs = 1_000;
const runCaptureExImpl = vi.fn(
(_command: string[], _options?: { env?: NodeJS.ProcessEnv; timeout?: number }) =>
successfulWarmResult(),
);
const probeRuntimeModelStatus = vi.fn(() => {
nowMs = 6_000;
return unloadedStatus;
});

expect(
maybeWarmOllamaAfterDaemonRestart(
{ provider: "ollama-local", model: "qwen3.6:35b" },
{
probeRuntimeModelStatus,
runCaptureExImpl,
timeoutSeconds: 30,
now: () => nowMs,
},
),
).toEqual({ kind: "warmed", ok: true });

const warmCommand = runCaptureExImpl.mock.calls[0][0];
expect(warmCommand[warmCommand.indexOf("--max-time") + 1]).toBe("25");
expect(runCaptureExImpl.mock.calls[0][1]?.timeout).toBe(25_000);
expect(probeRuntimeModelStatus).toHaveBeenCalledWith(
"qwen3.6:35b",
expect.any(Function),
expect.any(Function),
5_000,
);
});

it("skips warm-up when the probe consumes the command timeout budget", () => {
let nowMs = 1_000;
const runCaptureExImpl = vi.fn(() => successfulWarmResult());
const probeRuntimeModelStatus = vi.fn(() => {
nowMs = 31_000;
return unloadedStatus;
});

expect(
maybeWarmOllamaAfterDaemonRestart(
{ provider: "ollama-local", model: "qwen3.6:35b" },
{
probeRuntimeModelStatus,
runCaptureExImpl,
timeoutSeconds: 30,
now: () => nowMs,
},
),
).toEqual({
kind: "skipped",
reason: "deadline-exhausted",
endpoint: `http://127.0.0.1:${OLLAMA_PORT}`,
});
expect(runCaptureExImpl).not.toHaveBeenCalled();
});

it("bounds the daemon probe and skips warm-up when a short timeout is consumed", () => {
let nowMs = 1_000;
const probeRuntimeModelStatus = vi.fn(() => {
nowMs = 3_000;
return unloadedStatus;
});

expect(
maybeWarmOllamaAfterDaemonRestart(
{ provider: "ollama-local", model: "qwen3.6:35b" },
{ probeRuntimeModelStatus, timeoutSeconds: 2, now: () => nowMs },
),
).toEqual({
kind: "skipped",
reason: "deadline-exhausted",
endpoint: `http://127.0.0.1:${OLLAMA_PORT}`,
});
expect(probeRuntimeModelStatus).toHaveBeenCalledWith(
"qwen3.6:35b",
expect.any(Function),
expect.any(Function),
2_000,
);
});

it("does not treat an exit-zero Ollama error body as a successful warm-up", () => {
expect(
maybeWarmOllamaAfterDaemonRestart(
Expand All @@ -243,7 +325,6 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
).toMatchObject({
kind: "warmed",
ok: false,
timedOut: false,
reason: "ollama-error",
endpoint: "http://127.0.0.1:11434",
detail: expect.stringContaining("model not found"),
Expand Down Expand Up @@ -276,7 +357,11 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
endpoint: `http://host.docker.internal:${OLLAMA_PORT}`,
inventoryLabel: "llama3.2:1b",
});
expect(probeModelInventory).toHaveBeenCalledWith("host.docker.internal", expect.any(Function));
expect(probeModelInventory).toHaveBeenCalledWith(
"host.docker.internal",
expect.any(Function),
5_000,
);
});

it("keeps the warm failure when the daemon does hold the model (#9455)", () => {
Expand All @@ -296,7 +381,6 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
).toMatchObject({
kind: "warmed",
ok: false,
timedOut: false,
reason: "ollama-error",
endpoint: "http://127.0.0.1:11434",
detail: expect.stringContaining("runner stopped unexpectedly"),
Expand All @@ -316,7 +400,7 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
}),
},
),
).toEqual({ kind: "warmed", ok: true, timedOut: false });
).toEqual({ kind: "warmed", ok: true });
});

it.each([
Expand All @@ -336,7 +420,6 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
).toMatchObject({
kind: "warmed",
ok: false,
timedOut: false,
reason: "invalid-response",
endpoint: "http://127.0.0.1:11434",
});
Expand All @@ -354,7 +437,6 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
).toEqual({
kind: "warmed",
ok: false,
timedOut: false,
reason: "command-failed",
endpoint: "http://127.0.0.1:11434",
detail: "warm-up exited 7",
Expand All @@ -374,7 +456,6 @@ describe("maybeWarmOllamaAfterDaemonRestart", () => {
).toEqual({
kind: "warmed",
ok: false,
timedOut: false,
reason: "spawn-failed",
endpoint: "http://127.0.0.1:11434",
detail: "spawn failed",
Expand Down
Loading
Loading