llm-pi-ai Timeout increase for local LLMs #3157
Replies: 10 comments 4 replies
|
having the same issue as you , i tried settings.yaml too , didn't work i also tried to manually change it in llm-pi-ai/src/adapter.ts but still get a timeout |
|
Even after updating settings.yaml, the issue persists with a different error. Exactly at the 5-minute mark, the failure reason now changes from 'timeout' to 'terminated'. For context, I can run this exact same local LLM successfully without any timeout issues in OpenCode. |
|
The 5-minute cutoff is the pi-ai adapter default, not Ollama. llm-pi-ai:
providers:
ollama:
streamIdleTimeoutMs: 1200000
timeoutMs: 1200000Then check the composed tree with Patching If dump-config is already 20 minutes and the failure still flips to |
|
I have had exactly the same problem: first a timeout, and then when that was fixed a "terminated" error. In my case it was always failing while trying to write out the file whose contents it had worked out. The cause seems to be a timeout under Plugins->Plugin Configuration->Shell where there is a command timeout of 120s by default. This should be more than enough to write out a short code segment. But the time limit seems to be applied from the time when the agent starts to create the tool call - which with a local model can take a considerable amount of time. I have bumped up this limit to a very large number and so far this seems to have resolved the problem. One thing I hadn't realised was that in several cases, the harness had stopped the turn and then rerun it up to 5 times, stopping it each time it reached the point of writing the file but discarding all trace of the run that it killed. So it never left a usable log of exactly what was going on at the moment of failure. I am not sure whether these aborted turns are logged somewhere unobvious but it would help if it didn't completely erase all trace of them. EDIT: It hasn't fixed the problem. It has just failed again. But it is definitely somehow linked to the "write file" tool call taking a long time. |
|
@njcray2 Two clocks. The Shell plugin’s 120s timeout is measured from when the tool call is created, so a slow local model filling If it still dies at ~5:00 with |
|
Thanks, this explains why changing settings.yaml only changed the error from timeout to terminated for some people. |
|
@ylwl1997 I don't actually see any of the config in settings.yaml reflected in the output from --dump-config but they are being honoured. Your confirmation that the shell tool timing does include the time it takes the model to fill the arguments is very useful. I am going to check again in case I didn't restart a new session before. Ollama's server log reports that it received a "cancel task" and the time of the previous completion is often suspiciously close to 5m. So either I didn't correctly increase the shell command timeout or there is another 5m limit somewhere. All these failures occur during the write tool call though so it is definitely pointing at the requirement that the LLM must create the tool call within 5m. |
|
Hello everyone, I resolved this by adding a dispatcher that adjusts the timeout to match the adapter's timeout. Here are the changes: llm-pi-ai -> adapter.tsfunction profileOptions( openai-completions.jsimport { Agent, fetch } from "undici"; const dispatchers = new Map(); function dispatcherFor(timeoutMs) { if (dispatcher === undefined) { return dispatcher; const client = createClient( const requestOptions = { return new OpenAI({ Final changessettings.yaml |
|
Confirming the fix on macOS (M1 Max, LM Studio + llama.cpp backend, dsh 0.1.1-rc.2). One step is missing from the recipe above, and it is probably why some of us could not reproduce it: undici is not a dependency of dsh. The import throws ERR_MODULE_NOT_FOUND. Run "npm install undici" in the harness folder first. Also, patch the COMPILED file, not the sources, as ylwl1997 already noted: node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js A diagnostic that costs nothing, for anyone unsure whether they are hitting this rather than a backend timeout. If you have any proxy or relay between dsh and your model server, look at the request sizes it logs. The signature is the SAME byte size resent every five minutes: 23:15:28 120 493 bytes Identical size means a retry of the same request, not a conversation moving forward. That is the client giving up at 300 s, not the backend closing. Before and after on our side. Short turns always landed, long ones never did: answers under 400 tokens completed every time, answers over 2500 tokens died every time with "Failure reason: terminated", at exactly the 5:00 mark. After the patch, one turn ran 5 min 54 s and completed: 02:45:44 request sent, 101 381 bytes Different size, so the conversation moved on instead of retrying. That same turn wrote a 5.8 KB test file in a single tool call, which is precisely the gesture that died before. Worth stating for future readers: this patch lives in node_modules and is lost on every reinstall of dsh. An upstream fix, or a postinstall patch, would help a lot of local-model users. |
|
Hello again, have been following and attempting changes as suggested but
here on Win11 get many errors from code added to src/adapter.ts - It is
difficult for an amateur to understand and likely have placed code in wrong
place or was that the fix for linux or mac? Would really like to get this
sorted as I can see some potential.
@***@***.*** build:lib:host
tsc -b tsconfig.host.json && tsdown --env.DSH_BUILD_FACE host
packages/llm/llm-pi-ai/src/adapter.ts:99:3 - error TS18004: No value exists
in scope for the shorthand property 'maxRetries'. Either declare one or
provide an initializer.
99 maxRetries,
~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:100:3 - error TS18004: No value
exists in scope for the shorthand property 'websocketConnectTimeoutMs'.
Either declare one or provide an initializer.
100 websocketConnectTimeoutMs,
~~~~~~~~~~~~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:101:3 - error TS18004: No value
exists in scope for the shorthand property 'timeoutMs'. Either declare one
or provide an initializer.
101 timeoutMs,
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:102:3 - error TS2552: Cannot find
name 'transport'. Did you mean 'WebTransport'?
102 transport,
~~~~~~~~~
***@***.***
/node_modules/typescript/lib/lib.dom.d.ts:41001:13
41001 declare var WebTransport: {
~~~~~~~~~~~~
'WebTransport' is declared here.
packages/llm/llm-pi-ai/src/adapter.ts:103:3 - error TS18004: No value
exists in scope for the shorthand property 'cacheRetention'. Either declare
one or provide an initializer.
103 cacheRetention,
~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:104:3 - error TS18004: No value
exists in scope for the shorthand property 'thinkingBudgets'. Either
declare one or provide an initializer.
104 thinkingBudgets,
~~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:113:1 - error TS2375: Type '{
maxRetries: number; websocketConnectTimeoutMs?: number; timeoutMs?: number;
transport?: Transport; cacheRetention?: CacheRetention; thinkingBudgets?:
ThinkingBudgets; reasoning?: ModelThinkingLevel | undefined; apiKey?:
string | undefined; }' is not assignable to type 'SimpleStreamOptions & {
streamIdleTimeoutMs: number; }' with 'exactOptionalPropertyTypes: true'.
Consider adding 'undefined' to the types of the target's properties.
Type '{ maxRetries: number; websocketConnectTimeoutMs?: number;
timeoutMs?: number; transport?: Transport; cacheRetention?: CacheRetention;
thinkingBudgets?: ThinkingBudgets; reasoning?: ModelThinkingLevel |
undefined; apiKey?: string | undefined; }' is not assignable to type
'SimpleStreamOptions' with 'exactOptionalPropertyTypes: true'. Consider
adding 'undefined' to the types of the target's properties.
Types of property 'reasoning' are incompatible.
Type 'ModelThinkingLevel | undefined' is not assignable to type
'ThinkingLevel'.
Type 'undefined' is not assignable to type 'ThinkingLevel'.
113 return {
~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:144:3 - error TS18004: No value
exists in scope for the shorthand property 'maxRetries'. Either declare one
or provide an initializer.
144 maxRetries,
~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:148:5 - error TS2304: Cannot find
name 'websocketConnectTimeoutMs'.
148 if (websocketConnectTimeoutMs !== undefined)
options.websocketConnectTimeoutMs = websocketConnectTimeoutMs;
~~~~~~~~~~~~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:148:82 - error TS2304: Cannot find
name 'websocketConnectTimeoutMs'.
148 if (websocketConnectTimeoutMs !== undefined)
options.websocketConnectTimeoutMs = websocketConnectTimeoutMs;
~~~~~~~~~~~~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:149:5 - error TS2304: Cannot find
name 'timeoutMs'.
149 if (timeoutMs !== undefined) options.timeoutMs = timeoutMs;
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:149:50 - error TS2304: Cannot find
name 'timeoutMs'.
149 if (timeoutMs !== undefined) options.timeoutMs = timeoutMs;
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:150:5 - error TS2304: Cannot find
name 'transport'.
150 if (transport !== undefined) options.transport = transport;
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:150:50 - error TS2304: Cannot find
name 'transport'.
150 if (transport !== undefined) options.transport = transport;
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:151:5 - error TS2304: Cannot find
name 'cacheRetention'.
151 if (cacheRetention !== undefined) options.cacheRetention =
cacheRetention;
~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:151:60 - error TS2304: Cannot find
name 'cacheRetention'.
151 if (cacheRetention !== undefined) options.cacheRetention =
cacheRetention;
~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:152:5 - error TS2304: Cannot find
name 'thinkingBudgets'.
152 if (thinkingBudgets !== undefined) options.thinkingBudgets =
thinkingBudgets;
~~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:152:62 - error TS2304: Cannot find
name 'thinkingBudgets'.
152 if (thinkingBudgets !== undefined) options.thinkingBudgets =
thinkingBudgets;
~~~~~~~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:153:5 - error TS2304: Cannot find
name 'apiKey'.
153 if (apiKey !== undefined) options.apiKey = apiKey;
~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:153:44 - error TS2304: Cannot find
name 'apiKey'.
153 if (apiKey !== undefined) options.apiKey = apiKey;
~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:156:5 - error TS2304: Cannot find
name 'reasoning'.
156 if (reasoning && reasoning !== 'off') {
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:156:18 - error TS2304: Cannot find
name 'reasoning'.
156 if (reasoning && reasoning !== 'off') {
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:157:23 - error TS2304: Cannot find
name 'reasoning'.
157 options.reasoning = reasoning;
~~~~~~~~~
packages/llm/llm-pi-ai/src/adapter.ts:160:1 - error TS1108: A 'return'
statement can only be used within a function body.
160 return options as SimpleStreamOptions & { streamIdleTimeoutMs: number };
~~~~~~
Found 24 errors.
[ELIFECYCLE] Command failed with exit code 2.
PS C:\users\user\deepseek-harness>
…On Mon, Aug 24, 2026 at 8:44 PM Mcbest06 ***@***.***> wrote:
Hello everyone,
I had the same problem.
It stems from the dynamic Undici HTTP Dispatcher layer, which has a
timeout of 300,000ms.
So, whenever the configured timeout exceeds that limit, the connection
cuts off with the error: "Failure reason: terminated"
I resolved this by adding a dispatcher that adjusts the timeout to match
the adapter's timeout.
Here are the changes:
llm-pi-ai -> adapter.ts
function profileOptions(
profile: ResolvedPiAiProviderProfile,
reasoning: ModelThinkingLevel | undefined,
apiKey: string | undefined,
): SimpleStreamOptions & { streamIdleTimeoutMs: number } {
return {
...apiKey === undefined ? {} : { apiKey },
...profile.timeoutMs === undefined ? {} : { timeoutMs: profile.timeoutMs },
streamIdleTimeoutMs: profile.streamIdleTimeoutMs,
maxRetries: 0,
}
}
openai-completions.js
import { Agent, fetch } from "undici";
const dispatchers = new Map();
function dispatcherFor(timeoutMs) {
let dispatcher = dispatchers.get(timeoutMs);
if (dispatcher === undefined) {
dispatcher = new Agent({
bodyTimeout: timeoutMs,
headersTimeout: timeoutMs,
});
dispatchers.set(timeoutMs, dispatcher);
}
return dispatcher;
}
const client = createClient(
model,
context,
apiKey,
options?.headers,
cacheSessionId,
compat,
options?.streamIdleTimeoutMs,
);
const requestOptions = {
...(options?.signal ? { signal: options.signal } : {}),
timeout: options?.streamIdleTimeoutMs,
maxRetries: 0,
};
return new OpenAI({
apiKey,
baseURL: model.baseUrl,
dangerouslyAllowBrowser: true,
defaultHeaders: headers,
...(streamIdleTimeoutMs === undefined
? {}
: {
fetch: (input, init) => fetch(input, {
...init,
dispatcher: dispatcherFor(streamIdleTimeoutMs),
}),
}),
});
Final changes
settings.yaml
→ profile.streamIdleTimeoutMs
→ dsh-llm-pi-ai profileOptions()
→ pi-ai streamSimple()
→ buildBaseOptions()
→ openai-completions.stream()
→ timeout OpenAI SDK
→ dispatcher Undici bodyTimeout / headersTimeout
→ requête HTTP To Ollama/LM Studio...
—
Reply to this email directly, view it on GitHub
<#3157?email_source=notifications&email_token=AGEDREIZBYY4D5NNG3WKXEL5LQ2DXA5CNFSNUABIM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63SDN5WW2ZLOOQXTCOBRGM2DSNRQUZZGKYLTN5XKMYLVORUG64VFMV3GK3TUVRTG633UMVZF6Y3MNFRWW#discussioncomment-18134960>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AGEDREJ3JATQWL52W75YNTT5LQ2DXAVCNFSNUABJKJSXA33TNF2G64TZHMYTGMZTGA3DKMBZGE5UI2LTMN2XG43JN5XDWMJQGY2DAMJYGOQXMAQ>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AGEDRENPIARTJIGAZVVIMGT5LQ2DXA5CNFSNUABIM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63SDN5WW2ZLOOQXTCOBRGM2DSNRQUZZGKYLTN5XKMYLVORUG64VFMV3GK3TUVJTG633UMVZF62LPOM>
and Android
<https://github.com/notifications/mobile/android/AGEDREMRN57Y7ASDGFRCATT5LQ2DXA5CNFSNUABIM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63SDN5WW2ZLOOQXTCOBRGM2DSNRQUZZGKYLTN5XKMYLVORUG64VFMV3GK3TUVZTG633UMVZF6YLOMRZG62LE>.
Download it today!
You are receiving this because you authored the thread.Message ID:
<deepseek-ai/deepseek-harness/repo-discussions/3157/comments/18134960@
github.com>
--
*Kununurra Historical Society* Inc. (*Est. 1986*)
Archive, Library, Museum & Research
72 Coolibah Drive near the corner of Messmate Way (100m from the PO)
PO Box 77 KUNUNURRA WA 6743 - Phone: +61 (0) 8 9169 3331
*http://www.kununurra.org.au/ <http://www.kununurra.org.au/>*
*Please update your contacts as this REPLY is from an old email address.The
address on this eMail will remain - However we
prefer... ***@***.*** ***@***.***>*
If you do not wish to receive emails reply and change *subject* to "REMOVE"
|
Uh oh!
There was an error while loading. Please reload this page.
Hello anybody interested, after great successful start with Ollama Gemma4:12b on Win11, found any longer prompts end up with a 300,000 millisecond (5min) timeout - I'd like to get a 20 minute timeout in there for local LLMs but how? Tried adding a line in settings.yaml but no or got it wrong?
All reactions