Skip to content

Commit 348728c

Browse files
committed
fix(providers): bound native fetch timeouts
1 parent dc78d58 commit 348728c

5 files changed

Lines changed: 14 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai
3535
- Providers/Ollama: move memory embeddings to Ollama's current `/api/embed` endpoint with batched `input` requests while preserving vector normalization and custom provider auth/header overrides. Fixes #39983. Thanks @sskkcc and @LiudengZhang.
3636
- Providers/Ollama: route local web search through Ollama's signed `/api/experimental/web_search` daemon proxy, use hosted `/api/web_search` directly for `ollama.com`, and keep `OLLAMA_API_KEY` scoped to cloud fallback auth. Fixes #69132. Thanks @yoon1012 and @hyspacex.
3737
- Providers/Ollama: accept OpenAI SDK-style `baseURL` as an alias for `baseUrl` across discovery, streaming, setup pulls, embeddings, and web search so remote Ollama hosts are not silently ignored. Fixes #62533; supersedes #62549. Thanks @Julien-BKK and @Linux2010.
38+
- Providers/PDF/Ollama: add bounded network timeouts for Ollama model pulls and native Anthropic/Gemini PDF analysis requests so unresponsive provider endpoints no longer hang sessions indefinitely. Fixes #54142; supersedes #54144 and #54145. Thanks @jinduwang1001-max and @arkyu2077.
3839
- Memory/doctor: treat Ollama memory embeddings as key-optional so `openclaw doctor` no longer warns about a missing API key when the gateway reports embeddings are ready. Fixes #46584. Thanks @fengly78.
3940
- Agents/Ollama: apply provider-owned replay turn normalization to native Ollama chat so Cloud models no longer reject non-alternating replay history in agent/Gateway runs. Fixes #71697. Thanks @ismael-81.
4041
- Control UI/Ollama: show the resolved configured thinking default in chat and session thinking dropdowns so inherited `adaptive`/per-model thinking config no longer appears as `Default (off)` or a generic inherit value. Fixes #72407. Thanks @NotecAG.

extensions/ollama/src/setup.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ describe("ollama setup", () => {
417417

418418
expect(fetchMock).toHaveBeenCalledTimes(2);
419419
expect(fetchMock.mock.calls[1][0]).toContain("/api/pull");
420+
const pullInit = fetchMock.mock.calls[1][1];
421+
expect(pullInit?.signal).toBeInstanceOf(AbortSignal);
422+
expect(pullInit?.signal?.aborted).toBe(false);
420423
});
421424

422425
it("skips pull when model is already available", async () => {

extensions/ollama/src/setup.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const OLLAMA_SUGGESTED_MODELS_LOCAL = [OLLAMA_DEFAULT_MODEL];
4242
const OLLAMA_SUGGESTED_MODELS_CLOUD = ["kimi-k2.5:cloud", "minimax-m2.7:cloud", "glm-5.1:cloud"];
4343
const OLLAMA_CONTEXT_ENRICH_LIMIT = 200;
4444
const OLLAMA_CLOUD_MAX_DISCOVERED_MODELS = 500;
45+
const OLLAMA_PULL_REQUEST_TIMEOUT_MS = 30_000;
4546

4647
type OllamaSetupOptions = {
4748
customBaseUrl?: string;
@@ -172,6 +173,7 @@ async function pullOllamaModelCore(params: {
172173
headers: { "Content-Type": "application/json" },
173174
body: JSON.stringify({ name: modelName }),
174175
},
176+
timeoutMs: OLLAMA_PULL_REQUEST_TIMEOUT_MS,
175177
policy: buildOllamaBaseUrlSsrFPolicy(baseUrl),
176178
auditContext: "ollama-setup.pull",
177179
});

src/agents/tools/pdf-native-providers.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ describe("native PDF provider API calls", () => {
7878
expect(fetchMock).toHaveBeenCalledTimes(1);
7979
const [url, opts] = fetchMock.mock.calls[0];
8080
expect(url).toContain("/v1/messages");
81+
expect(opts.signal).toBeInstanceOf(AbortSignal);
82+
expect(opts.signal.aborted).toBe(false);
8183
const body = JSON.parse(opts.body);
8284
expect(body.model).toBe("claude-opus-4-6");
8385
expect(body.messages[0].content).toHaveLength(2);
@@ -132,6 +134,8 @@ describe("native PDF provider API calls", () => {
132134
const [url, opts] = fetchMock.mock.calls[0];
133135
expect(url).toContain("generateContent");
134136
expect(url).toContain("gemini-2.5-pro");
137+
expect(opts.signal).toBeInstanceOf(AbortSignal);
138+
expect(opts.signal.aborted).toBe(false);
135139
const body = JSON.parse(opts.body);
136140
expect(body.contents[0].parts).toHaveLength(2);
137141
expect(body.contents[0].parts[0].inline_data.mime_type).toBe("application/pdf");

src/agents/tools/pdf-native-providers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ type PdfInput = {
1212
filename?: string;
1313
};
1414

15+
const NATIVE_PDF_PROVIDER_FETCH_TIMEOUT_MS = 120_000;
16+
1517
// ---------------------------------------------------------------------------
1618
// Anthropic – native PDF via Messages API
1719
// ---------------------------------------------------------------------------
@@ -74,6 +76,7 @@ export async function anthropicAnalyzePdf(params: {
7476
max_tokens: params.maxTokens ?? 4096,
7577
messages: [{ role: "user", content }],
7678
}),
79+
signal: AbortSignal.timeout(NATIVE_PDF_PROVIDER_FETCH_TIMEOUT_MS),
7780
});
7881

7982
if (!res.ok) {
@@ -158,6 +161,7 @@ export async function geminiAnalyzePdf(params: {
158161
body: JSON.stringify({
159162
contents: [{ role: "user", parts }],
160163
}),
164+
signal: AbortSignal.timeout(NATIVE_PDF_PROVIDER_FETCH_TIMEOUT_MS),
161165
});
162166

163167
if (!res.ok) {

0 commit comments

Comments
 (0)