Skip to content

fix: add timeoutSeconds config for model providers#63191

Closed
uninhibited-scholar wants to merge 4 commits into
openclaw:mainfrom
uninhibited-scholar:main
Closed

fix: add timeoutSeconds config for model providers#63191
uninhibited-scholar wants to merge 4 commits into
openclaw:mainfrom
uninhibited-scholar:main

Conversation

@uninhibited-scholar

Copy link
Copy Markdown

Summary

This PR adds a configurable timeoutSeconds field to model provider configuration, allowing users to customize HTTP client timeouts for different providers.

Changes

  1. types.models.ts: Added timeoutSeconds?: number to ModelProviderConfig type
  2. zod-schema.core.ts: Added validation for timeoutSeconds field in ModelProviderSchema
  3. run/attempt.ts: Use provider-specific timeout when configuring undici HTTP client

Motivation

Fixes issue #63156 where HTTP client timeout was effectively hardcoded, causing request failures when prompt processing exceeded the default timeout. This is especially problematic for:

  • Local LLM providers (LM Studio, Ollama) with slower inference
  • Large context injections requiring longer processing time
  • Models with variable response times

Usage

Users can now configure provider-specific timeouts:

{
  "models": {
    "providers": {
      "lm-studio": {
        "baseUrl": "http://127.0.0.1:1234/v1",
        "api": "openai-completions",
        "timeoutSeconds": 180
      },
      "ollama": {
        "baseUrl": "http://127.0.0.1:11434",
        "api": "ollama",
        "timeoutSeconds": 300
      }
    }
  }
}

Testing

  • Type checking passes
  • Backward compatible (timeoutSeconds is optional)
  • Falls back to undici default (30 minutes) when not configured

Related Issues

uninhibite-scholar added 4 commits March 10, 2026 13:25
- Extract path from image content blocks in tool results
- This fixes Feishu image delivery when using the read tool
- Previously, media paths were only extracted from MEDIA: tokens
  in text content, but read tool returns paths in image blocks

Fixes issue where read tool image results lost media before
final outbound payload assembly in Feishu channel.

Closes openclaw#41744
- Extract MEDIA: tokens even when wrapped in code blocks
- LLMs frequently format paths in code fences
- Previously these were silently ignored causing delivery failures
- Now tokens are extracted and delivered correctly

Fixes openclaw#41966
Fixes tar security vulnerability (Symlink Path Traversal)

Applied same fix as PR openclaw#42768 by futuremind2026
- Add timeoutSeconds field to ModelProviderConfig type and schema
- Use provider-specific timeout for undici HTTP client
- Fixes issue openclaw#63156 where HTTP client timeout was hardcoded
- Allows users to configure custom timeouts for LM Studio, Ollama, and other providers

Example config:
```json
{
  "models": {
    "providers": {
      "lm-studio": {
        "baseUrl": "http://127.0.0.1:1234/v1",
        "api": "openai-completions",
        "timeoutSeconds": 180
      }
    }
  }
}
```
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Apr 8, 2026
@greptile-apps

greptile-apps Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a timeoutSeconds field to ModelProviderConfig (type + Zod validation) and reads it in runEmbeddedAttempt to configure the undici global dispatcher timeout — useful for slow local providers like Ollama and LM Studio. However, the PR also includes changes to src/media/parse.ts that introduce a duplicate const matches declaration (lines 134 and 146, same block scope), which is a TypeScript compile error that will prevent the build from succeeding.

  • P0 — src/media/parse.ts: Duplicate const matches declaration causes a compile-time error; the second declaration and its redundant guard block must be removed.

Confidence Score: 2/5

Not safe to merge — the parse.ts duplicate const matches declaration is a compile error that breaks the build.

The timeout feature itself (types, schema, attempt.ts wiring) is sound and well-structured, but the accompanying parse.ts change introduces a duplicate block-scoped variable that TypeScript will reject at compile time, making the entire build non-functional.

src/media/parse.ts — duplicate const matches on lines 134 and 146 must be fixed before merge.

Vulnerabilities

No security concerns identified. The timeoutSeconds value goes through Zod validation (int().positive()) before use and is only applied to HTTP client timeout configuration, not exposed to external callers.

Comments Outside Diff (1)

  1. src/media/parse.ts, line 146-151 (link)

    P0 Duplicate const matches declaration — compile error

    matches is already declared with const at line 134 in the same block scope. TypeScript will reject this with Cannot redeclare block-scoped variable 'matches', so this file will not compile. The second declaration (and its guard) is a copy-paste artifact that should be removed; the fence-tracking block at lines 141–144 should simply come before the original matches declaration or after it, without re-declaring the variable.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/media/parse.ts
    Line: 146-151
    
    Comment:
    **Duplicate `const matches` declaration — compile error**
    
    `matches` is already declared with `const` at line 134 in the same block scope. TypeScript will reject this with `Cannot redeclare block-scoped variable 'matches'`, so this file will not compile. The second declaration (and its guard) is a copy-paste artifact that should be removed; the fence-tracking block at lines 141–144 should simply come before the original `matches` declaration or after it, without re-declaring the variable.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/media/parse.ts
Line: 146-151

Comment:
**Duplicate `const matches` declaration — compile error**

`matches` is already declared with `const` at line 134 in the same block scope. TypeScript will reject this with `Cannot redeclare block-scoped variable 'matches'`, so this file will not compile. The second declaration (and its guard) is a copy-paste artifact that should be removed; the fence-tracking block at lines 141–144 should simply come before the original `matches` declaration or after it, without re-declaring the variable.

```suggestion
    if (isInsideFenceBlock) {
      foundMediaInFence = true;
    }

    const pieces: string[] = [];
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/run/attempt.ts
Line: 753-759

Comment:
**Global dispatcher replaced per-attempt — concurrent providers share one timeout**

`ensureGlobalUndiciStreamTimeouts` replaces the single process-wide undici dispatcher. When two agents run concurrently (e.g. a 180 s lm-studio run and a default openai run), the second call overwrites the timeout for all in-flight HTTP requests, including the first agent's ongoing stream. The last `runEmbeddedAttempt` to start wins, which makes provider-specific timeouts non-deterministic under concurrency. Consider gating this only when a value is explicitly set and, longer-term, using per-client dispatchers rather than the global one.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: add timeoutSeconds config for model..." | Re-trigger Greptile

Comment on lines +753 to +759
// Use provider-specific timeout if configured, otherwise use agent default
const providerConfig = params.config?.models?.providers?.[params.provider];
const providerTimeoutSeconds = providerConfig?.timeoutSeconds;
const timeoutMs = providerTimeoutSeconds
? providerTimeoutSeconds * 1000
: undefined;
ensureGlobalUndiciStreamTimeouts({ timeoutMs });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Global dispatcher replaced per-attempt — concurrent providers share one timeout

ensureGlobalUndiciStreamTimeouts replaces the single process-wide undici dispatcher. When two agents run concurrently (e.g. a 180 s lm-studio run and a default openai run), the second call overwrites the timeout for all in-flight HTTP requests, including the first agent's ongoing stream. The last runEmbeddedAttempt to start wins, which makes provider-specific timeouts non-deterministic under concurrency. Consider gating this only when a value is explicitly set and, longer-term, using per-client dispatchers rather than the global one.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/run/attempt.ts
Line: 753-759

Comment:
**Global dispatcher replaced per-attempt — concurrent providers share one timeout**

`ensureGlobalUndiciStreamTimeouts` replaces the single process-wide undici dispatcher. When two agents run concurrently (e.g. a 180 s lm-studio run and a default openai run), the second call overwrites the timeout for all in-flight HTTP requests, including the first agent's ongoing stream. The last `runEmbeddedAttempt` to start wins, which makes provider-specific timeouts non-deterministic under concurrency. Consider gating this only when a value is explicitly set and, longer-term, using per-client dispatchers rather than the global one.

How can I resolve this? If you propose a fix, please make it concise.

@uninhibited-scholar

Copy link
Copy Markdown
Author

Closing in favor of #65143 — clean rewrite with only the timeoutSeconds feature, without the unrelated tar bump and parse.ts changes that caused compile errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: HTTP client timeout hardcoded to 15s, cannot be configured or increased

1 participant