Honor local agent timeout defaults
This commit is contained in:
1 parent
e53c61e712
commit
75b7ca02ef
3 files changed
+26
-10
No files matched your search
+8
-7
@@ -821,13 +821,14 @@ export class TempestCommand extends EventEmitter<CommandEvents> {
|
||||
* GENEROUS per-dispatch wall-clock backstop (ms). If a single task dispatch stays
|
||||
* in-flight longer than this, the tick loop force-resolves it as a timeout so
|
||||
* pendingOrActive can reach 0 and the mission can advance/complete even when an
|
||||
* operator promise wedges. Deliberately large (default 5 min) so it NEVER kills a
|
||||
* legitimately-slow-but-working LLM task (e.g. opus planning ~165s); it only fires
|
||||
* on truly-hung dispatches. Override via T3MP3ST_TASK_TIMEOUT_MS.
|
||||
* operator promise wedges. Deliberately large (default 5 min for API models,
|
||||
* 30 min for local-agent backends) so it does not kill legitimately slow local
|
||||
* CLI work; it only fires on truly-hung dispatches. Override via
|
||||
* T3MP3ST_TASK_TIMEOUT_MS.
|
||||
*/
|
||||
/**
|
||||
* Resolve the dispatch timeout from the environment, falling back to the 5-minute
|
||||
* default. Guards against a non-numeric / non-positive override.
|
||||
* Resolve the dispatch timeout from the environment, falling back to the
|
||||
* provider-specific default. Guards against a non-numeric / non-positive override.
|
||||
*/
|
||||
private static resolveTaskTimeoutMs(provider?: LLMProvider): number {
|
||||
const DEFAULT_TASK_TIMEOUT_MS = 300000; // 5 minutes — generous backstop, not a deadline
|
||||
@@ -1035,8 +1036,8 @@ export class TempestCommand extends EventEmitter<CommandEvents> {
|
||||
* never advances, and completeMission() is never called: the mission HANGS.
|
||||
*
|
||||
* On every tick we scan the in-flight dispatches and force-resolve any that have
|
||||
* exceeded the GENEROUS wall-clock backstop (taskTimeoutMs, default 5 min), or
|
||||
* that exhibit the exact wedge symptom (owning operator is `executing`/`tasked`
|
||||
* exceeded the GENEROUS wall-clock backstop (taskTimeoutMs), or that exhibit
|
||||
* the exact wedge symptom (owning operator is `executing`/`tasked`
|
||||
* but its currentTask is null — i.e. it has silently dropped the task). For each
|
||||
* we: (1) mark the task failed/timed-out in the queue, (2) clear its dispatch
|
||||
* bookkeeping, and (3) reset the owning operator back to idle so it can take new
|
||||
|
||||
+2
-1
@@ -1070,7 +1070,8 @@ class LocalAgentAdapter implements LLMProviderAdapter {
|
||||
async chat(messages: LLMMessage[], options?: ChatOptions): Promise<LLMResponse> {
|
||||
const agentId = this.config.model || 'codex';
|
||||
const prompt = this.formatPrompt(messages, options);
|
||||
const content = (await localAgentChat(agentId, prompt, { timeoutMs: this.config.timeout || 240000 })).trim();
|
||||
const timeoutMs = typeof this.config.timeout === 'number' && this.config.timeout > 0 ? this.config.timeout : undefined;
|
||||
const content = (await localAgentChat(agentId, prompt, { timeoutMs })).trim();
|
||||
// Tool-calling over text: if the Arsenal was offered, parse the agent's tool requests so the
|
||||
// ReAct loop EXECUTES them instead of treating this planning turn as the (abstaining) final answer.
|
||||
const toolCalls = options?.tools?.length ? parseTextToolCalls(content) : undefined;
|
||||
|
||||
+16
-2
@@ -6478,6 +6478,18 @@ function providerNeedsApiKey(provider: string): boolean {
|
||||
return !['codex', 'mock', 'local', 'local-agent'].includes(provider);
|
||||
}
|
||||
|
||||
function readPositiveTimeoutEnv(name: string): number | undefined {
|
||||
const raw = process.env[name];
|
||||
if (raw == null || raw.trim() === '') return undefined;
|
||||
const parsed = Number(raw);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
||||
}
|
||||
|
||||
function readGeneralTimeoutEnv(): number | undefined {
|
||||
return readPositiveTimeoutEnv('TEMPEST_GENERAL_TIMEOUT_MS')
|
||||
?? readPositiveTimeoutEnv('T3MP3ST_GENERAL_TIMEOUT_MS');
|
||||
}
|
||||
|
||||
// SECURITY NOTE: `apiKey` is accepted from the request BODY here (and in the
|
||||
// mission/general routes that call this). Sending secrets in the body is not
|
||||
// ideal — an Authorization header is preferred — but the same-origin UI posts
|
||||
@@ -6501,7 +6513,9 @@ function resolveGeneralLLMConfig(provider: string, model: string | undefined, ap
|
||||
model: model || 'codex',
|
||||
maxTokens: 8192,
|
||||
temperature: 0.4,
|
||||
timeout: Number(process.env.TEMPEST_GENERAL_TIMEOUT_MS) || 300000,
|
||||
timeout: readGeneralTimeoutEnv()
|
||||
?? readPositiveTimeoutEnv('T3MP3ST_LOCAL_AGENT_TIMEOUT_MS')
|
||||
?? 600000,
|
||||
};
|
||||
}
|
||||
const baseConfig = config.getLLMConfig(selectedProvider as any, model);
|
||||
@@ -6515,7 +6529,7 @@ function resolveGeneralLLMConfig(provider: string, model: string | undefined, ap
|
||||
apiKey: effectiveKey,
|
||||
maxTokens: 8192,
|
||||
temperature: 0.4,
|
||||
timeout: Number(process.env.TEMPEST_GENERAL_TIMEOUT_MS) || 300000, // General planning needs room (was a hardcoded 60s); override via env
|
||||
timeout: readGeneralTimeoutEnv() ?? 300000, // General planning needs room (was a hardcoded 60s); override via env
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user