feat(models): add per-provider timeoutSeconds config#65143
feat(models): add per-provider timeoutSeconds config#65143uninhibited-scholar wants to merge 3 commits into
Conversation
Allow each model provider to specify a custom stream timeout via timeoutSeconds in the provider config. Useful for slow local providers (e.g. Ollama, LM Studio) that need longer than the 30-minute default. Changes: - Add timeoutSeconds field to ModelProviderConfig type - Add Zod validation (positive integer) - Read provider-specific timeout in runEmbeddedAttempt
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 37f5774f20
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| ensureGlobalUndiciStreamTimeouts( | ||
| providerTimeoutSeconds != null ? { timeoutMs: providerTimeoutSeconds * 1000 } : undefined, |
There was a problem hiding this comment.
Scope timeout changes to per-request dispatcher
This call applies provider-specific timeout by invoking ensureGlobalUndiciStreamTimeouts, but that helper rewrites Undici's process-global dispatcher. If two embedded attempts overlap (for example, different sessions/providers running at the same time), the later attempt overwrites the timeout for the whole process, so the first attempt and other concurrent network calls can run with the wrong timeout and fail unpredictably. Per-provider timeout needs to be bound to the provider request path (or a per-request dispatcher) instead of mutating global state on each attempt.
Useful? React with 👍 / 👎.
Greptile SummaryThis PR adds a
Confidence Score: 4/5Safe to merge after adding the missing help entry and regenerating the config baseline sha256. One P1 finding: the config doc baseline was not regenerated after modifying ModelProviderSchema, and the help text for the new field is absent from schema.help.ts — this will cause pnpm config:docs:check to fail in CI. The feature logic itself is correct. src/config/schema.help.ts (missing help entry) and docs/.generated/config-baseline.sha256 (stale hash)
|
| (params.config?.models?.providers?.[params.provider] as { timeoutSeconds?: number } | undefined) | ||
| ?.timeoutSeconds; |
There was a problem hiding this comment.
Unnecessary type cast —
timeoutSeconds is already in ModelProviderConfig
params.config?.models?.providers?.[params.provider] resolves to ModelProviderConfig | undefined, and ModelProviderConfig now declares timeoutSeconds?: number, so the as { timeoutSeconds?: number } | undefined cast is redundant and silently bypasses TypeScript's structural checking for that expression. Drop the cast:
| (params.config?.models?.providers?.[params.provider] as { timeoutSeconds?: number } | undefined) | |
| ?.timeoutSeconds; | |
| const providerTimeoutSeconds = | |
| params.config?.models?.providers?.[params.provider]?.timeoutSeconds; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/run/attempt.ts
Line: 348-349
Comment:
**Unnecessary type cast — `timeoutSeconds` is already in `ModelProviderConfig`**
`params.config?.models?.providers?.[params.provider]` resolves to `ModelProviderConfig | undefined`, and `ModelProviderConfig` now declares `timeoutSeconds?: number`, so the `as { timeoutSeconds?: number } | undefined` cast is redundant and silently bypasses TypeScript's structural checking for that expression. Drop the cast:
```suggestion
const providerTimeoutSeconds =
params.config?.models?.providers?.[params.provider]?.timeoutSeconds;
```
How can I resolve this? If you propose a fix, please make it concise.- Add models.providers.*.timeoutSeconds help entry to schema.help.ts - Regenerate config-baseline.sha256 - Remove redundant type cast in attempt.ts (ModelProviderConfig already declares timeoutSeconds)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 471db1e354
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| injectNumCtxForOpenAICompat: z.boolean().optional(), | ||
| headers: z.record(z.string(), SecretInputSchema.register(sensitive)).optional(), | ||
| authHeader: z.boolean().optional(), | ||
| timeoutSeconds: z.number().int().positive().optional(), |
There was a problem hiding this comment.
Regenerate base config schema for timeoutSeconds
Adding timeoutSeconds to ModelProviderSchema updates parsing, but the runtime schema payload comes from src/config/schema.base.generated.ts via src/config/schema.ts, and this commit does not regenerate that artifact. The generated schema still omits models.providers.*.timeoutSeconds, so Control UI / schema consumers cannot discover or configure the new field even though the parser accepts it in raw config.
Useful? React with 👍 / 👎.
|
Hey, any updates on this feature? |
|
Codex automated review: keeping this open. Keep this PR open. Current main still does not implement Best possible solution: Keep the PR open and adapt it. The best path is to add What I checked:
Remaining risk / open question:
Codex Review notes: model gpt-5.5, reasoning high; reviewed against 4878d3e059ce. |
|
Thanks @uninhibite-scholar — this was the right config surface. Superseded on Validation on the landed fix:
Closing this PR as superseded by the maintainer-owned implementation. Thanks again. |
Summary
Allow each model provider to specify a custom stream timeout via
timeoutSecondsin the provider config. Useful for slow local providers (e.g. Ollama, LM Studio) that need longer than the 30-minute default.Changes
timeoutSeconds?: numberfield toModelProviderConfigtypez.number().int().positive().optional())runEmbeddedAttemptand pass toensureGlobalUndiciStreamTimeoutsUsage Example
{ "models": { "providers": { "ollama": { "baseUrl": "http://localhost:11434", "timeoutSeconds": 600, // 10 minutes for slow local inference "models": [{ "id": "llama3" }] } } } }Testing
timeoutSecondsis not set, behavior is unchanged (falls through to 30-min default)ensureGlobalUndiciStreamTimeouts({ timeoutMs })APINotes
Clean rewrite of #63191 — this PR contains only the timeoutSeconds feature without unrelated changes (tar bump, parse.ts refactor, etc.).