mstro-app 0.1.57 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/commands/login.js +27 -14
- package/bin/commands/logout.js +35 -1
- package/bin/commands/status.js +1 -1
- package/bin/mstro.js +5 -108
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +432 -103
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/index.d.ts +2 -1
- package/dist/server/cli/headless/index.d.ts.map +1 -1
- package/dist/server/cli/headless/index.js +2 -0
- package/dist/server/cli/headless/index.js.map +1 -1
- package/dist/server/cli/headless/prompt-utils.d.ts +5 -8
- package/dist/server/cli/headless/prompt-utils.d.ts.map +1 -1
- package/dist/server/cli/headless/prompt-utils.js +40 -5
- package/dist/server/cli/headless/prompt-utils.js.map +1 -1
- package/dist/server/cli/headless/runner.d.ts +1 -1
- package/dist/server/cli/headless/runner.d.ts.map +1 -1
- package/dist/server/cli/headless/runner.js +29 -7
- package/dist/server/cli/headless/runner.js.map +1 -1
- package/dist/server/cli/headless/stall-assessor.d.ts +77 -1
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +336 -20
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.d.ts +67 -0
- package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -0
- package/dist/server/cli/headless/tool-watchdog.js +296 -0
- package/dist/server/cli/headless/tool-watchdog.js.map +1 -0
- package/dist/server/cli/headless/types.d.ts +80 -1
- package/dist/server/cli/headless/types.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.d.ts +109 -2
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +737 -132
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/index.js +5 -10
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-integration.js +18 -0
- package/dist/server/mcp/bouncer-integration.js.map +1 -1
- package/dist/server/mcp/security-audit.d.ts +2 -2
- package/dist/server/mcp/security-audit.d.ts.map +1 -1
- package/dist/server/mcp/security-audit.js +12 -8
- package/dist/server/mcp/security-audit.js.map +1 -1
- package/dist/server/mcp/security-patterns.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.js +9 -4
- package/dist/server/mcp/security-patterns.js.map +1 -1
- package/dist/server/routes/improvise.js +6 -6
- package/dist/server/routes/improvise.js.map +1 -1
- package/dist/server/services/analytics.d.ts +2 -0
- package/dist/server/services/analytics.d.ts.map +1 -1
- package/dist/server/services/analytics.js +13 -3
- package/dist/server/services/analytics.js.map +1 -1
- package/dist/server/services/platform.d.ts.map +1 -1
- package/dist/server/services/platform.js +4 -9
- package/dist/server/services/platform.js.map +1 -1
- package/dist/server/services/sandbox-utils.d.ts +6 -0
- package/dist/server/services/sandbox-utils.d.ts.map +1 -0
- package/dist/server/services/sandbox-utils.js +72 -0
- package/dist/server/services/sandbox-utils.js.map +1 -0
- package/dist/server/services/settings.d.ts +6 -0
- package/dist/server/services/settings.d.ts.map +1 -1
- package/dist/server/services/settings.js +21 -0
- package/dist/server/services/settings.js.map +1 -1
- package/dist/server/services/terminal/pty-manager.d.ts +3 -51
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-manager.js +14 -100
- package/dist/server/services/terminal/pty-manager.js.map +1 -1
- package/dist/server/services/websocket/handler.d.ts +36 -15
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +452 -223
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/types.d.ts +6 -2
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/hooks/bouncer.sh +11 -4
- package/package.json +4 -1
- package/server/cli/headless/claude-invoker.ts +602 -119
- package/server/cli/headless/index.ts +7 -1
- package/server/cli/headless/prompt-utils.ts +37 -5
- package/server/cli/headless/runner.ts +30 -8
- package/server/cli/headless/stall-assessor.ts +453 -22
- package/server/cli/headless/tool-watchdog.ts +390 -0
- package/server/cli/headless/types.ts +84 -1
- package/server/cli/improvisation-session-manager.ts +884 -143
- package/server/index.ts +5 -10
- package/server/mcp/bouncer-integration.ts +28 -0
- package/server/mcp/security-audit.ts +12 -8
- package/server/mcp/security-patterns.ts +8 -2
- package/server/routes/improvise.ts +6 -6
- package/server/services/analytics.ts +13 -3
- package/server/services/platform.test.ts +0 -10
- package/server/services/platform.ts +4 -10
- package/server/services/sandbox-utils.ts +78 -0
- package/server/services/settings.ts +25 -0
- package/server/services/terminal/pty-manager.ts +16 -127
- package/server/services/websocket/handler.ts +515 -251
- package/server/services/websocket/types.ts +10 -4
- package/dist/server/services/terminal/tmux-manager.d.ts +0 -82
- package/dist/server/services/terminal/tmux-manager.d.ts.map +0 -1
- package/dist/server/services/terminal/tmux-manager.js +0 -352
- package/dist/server/services/terminal/tmux-manager.js.map +0 -1
- package/server/services/terminal/tmux-manager.ts +0 -426
|
@@ -1,26 +1,48 @@
|
|
|
1
1
|
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
2
|
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
3
|
/**
|
|
4
|
-
* Stall Assessor
|
|
4
|
+
* Stall Assessor & Haiku Assessment Hub
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Provides Haiku-based intelligent assessment for:
|
|
7
|
+
* - Stall detection (is a silent process working or hung?)
|
|
8
|
+
* - Context loss detection (did Claude lose context after timeouts?)
|
|
9
|
+
* - Approval prompt classification (is a user message an approval or new task?)
|
|
10
|
+
* - Best result comparison (which retry attempt produced better work?)
|
|
11
|
+
* - Error classification (what kind of error is in stderr?)
|
|
8
12
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* 2. Haiku assessment: for ambiguous cases, spawns a quick Claude Haiku
|
|
13
|
-
* call to evaluate the situation and recommend an extension (or kill).
|
|
13
|
+
* Stall detection uses a two-layer approach:
|
|
14
|
+
* 1. Fast heuristic: known long-running patterns get automatic extensions.
|
|
15
|
+
* 2. Haiku assessment: ambiguous cases get a quick AI evaluation.
|
|
14
16
|
*/
|
|
15
17
|
import { spawn } from 'node:child_process';
|
|
16
18
|
/**
|
|
17
19
|
* Fast heuristic for known long-running patterns.
|
|
18
20
|
* Returns a verdict immediately if the pattern is recognized, null otherwise.
|
|
21
|
+
* When toolWatchdogActive is true, defers entirely to the watchdog for any
|
|
22
|
+
* pending tool calls — the watchdog has per-tool adaptive timeouts that are
|
|
23
|
+
* more precise than the stall detector's silence-based approach.
|
|
19
24
|
*/
|
|
20
|
-
function quickHeuristic(ctx) {
|
|
25
|
+
function quickHeuristic(ctx, toolWatchdogActive = false) {
|
|
26
|
+
const pendingNames = ctx.pendingToolNames ?? new Set();
|
|
27
|
+
const hasPendingTools = ctx.pendingToolCount > 0;
|
|
28
|
+
// When the watchdog is active and tools are pending, always defer.
|
|
29
|
+
// The watchdog manages per-tool timeouts; the stall detector should only
|
|
30
|
+
// fire when no tools are running and there's genuine silence.
|
|
31
|
+
if (toolWatchdogActive && hasPendingTools) {
|
|
32
|
+
const toolList = pendingNames.size > 0
|
|
33
|
+
? Array.from(pendingNames).join(', ')
|
|
34
|
+
: `${ctx.pendingToolCount} tool(s)`;
|
|
35
|
+
return {
|
|
36
|
+
action: 'extend',
|
|
37
|
+
extensionMs: 15 * 60_000,
|
|
38
|
+
reason: `Watchdog active, deferring — pending: ${toolList}`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
21
41
|
// Task/subagent launches are known to produce long silence periods.
|
|
22
42
|
// The parent Claude process emits nothing while waiting for subagent results.
|
|
23
|
-
|
|
43
|
+
// Check pendingToolNames (reliable) first, fall back to lastToolName (legacy).
|
|
44
|
+
const hasTaskPending = pendingNames.has('Task') || (ctx.lastToolName === 'Task' && hasPendingTools);
|
|
45
|
+
if (hasTaskPending) {
|
|
24
46
|
const extensionMin = Math.min(30, 10 + ctx.pendingToolCount * 5);
|
|
25
47
|
return {
|
|
26
48
|
action: 'extend',
|
|
@@ -36,9 +58,9 @@ function quickHeuristic(ctx) {
|
|
|
36
58
|
reason: `${ctx.pendingToolCount} parallel tool calls in progress — extending 15 min`,
|
|
37
59
|
};
|
|
38
60
|
}
|
|
39
|
-
// WebSearch/WebFetch
|
|
40
|
-
if (
|
|
41
|
-
ctx.lastToolName === 'WebFetch') {
|
|
61
|
+
// WebSearch/WebFetch: skip when watchdog handles them more precisely
|
|
62
|
+
if (!toolWatchdogActive &&
|
|
63
|
+
(ctx.lastToolName === 'WebSearch' || ctx.lastToolName === 'WebFetch')) {
|
|
42
64
|
return {
|
|
43
65
|
action: 'extend',
|
|
44
66
|
extensionMs: 5 * 60_000,
|
|
@@ -51,9 +73,9 @@ function quickHeuristic(ctx) {
|
|
|
51
73
|
* Main assessment entry point. Tries the fast heuristic first,
|
|
52
74
|
* falls back to a Haiku model call for ambiguous cases.
|
|
53
75
|
*/
|
|
54
|
-
export async function assessStall(ctx, claudeCommand, verbose) {
|
|
76
|
+
export async function assessStall(ctx, claudeCommand, verbose, toolWatchdogActive = false) {
|
|
55
77
|
// Layer 1: fast heuristic
|
|
56
|
-
const quick = quickHeuristic(ctx);
|
|
78
|
+
const quick = quickHeuristic(ctx, toolWatchdogActive);
|
|
57
79
|
if (quick) {
|
|
58
80
|
if (verbose) {
|
|
59
81
|
console.log(`[STALL-ASSESS] Heuristic verdict: ${quick.reason}`);
|
|
@@ -79,6 +101,121 @@ export async function assessStall(ctx, claudeCommand, verbose) {
|
|
|
79
101
|
};
|
|
80
102
|
}
|
|
81
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Assess a specific tool timeout using Haiku.
|
|
106
|
+
* Used by ToolWatchdog as a tiebreaker before killing a tool.
|
|
107
|
+
*/
|
|
108
|
+
export async function assessToolTimeout(toolName, toolInput, elapsedMs, claudeCommand, verbose) {
|
|
109
|
+
const elapsedSec = Math.round(elapsedMs / 1000);
|
|
110
|
+
// Summarize what the tool is doing
|
|
111
|
+
let inputSummary = '';
|
|
112
|
+
if (toolInput.url) {
|
|
113
|
+
inputSummary = `URL: ${String(toolInput.url).slice(0, 200)}`;
|
|
114
|
+
}
|
|
115
|
+
else if (toolInput.query) {
|
|
116
|
+
inputSummary = `Query: ${String(toolInput.query).slice(0, 200)}`;
|
|
117
|
+
}
|
|
118
|
+
else if (toolInput.command) {
|
|
119
|
+
inputSummary = `Command: ${String(toolInput.command).slice(0, 200)}`;
|
|
120
|
+
}
|
|
121
|
+
else if (toolInput.prompt) {
|
|
122
|
+
inputSummary = `Prompt: ${String(toolInput.prompt).slice(0, 200)}`;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
inputSummary = JSON.stringify(toolInput).slice(0, 200);
|
|
126
|
+
}
|
|
127
|
+
const toolDescriptions = {
|
|
128
|
+
WebFetch: 'fetches a URL, converts HTML to markdown, and runs a Haiku summarization pass',
|
|
129
|
+
WebSearch: 'performs a web search and returns results',
|
|
130
|
+
Task: 'spawns a subagent that runs autonomously with its own tools',
|
|
131
|
+
Bash: 'executes a shell command',
|
|
132
|
+
};
|
|
133
|
+
const toolDesc = toolDescriptions[toolName] || `executes the ${toolName} tool`;
|
|
134
|
+
const prompt = [
|
|
135
|
+
`You are a process health monitor. A ${toolName} tool call has been running for ${elapsedSec}s.`,
|
|
136
|
+
`${toolName} ${toolDesc}.`,
|
|
137
|
+
`Tool input: ${inputSummary}`,
|
|
138
|
+
'',
|
|
139
|
+
`Is this tool call likely still working, or is it hung/frozen?`,
|
|
140
|
+
'Consider: network latency, server response times, anti-bot protections, large page sizes, complex operations.',
|
|
141
|
+
'',
|
|
142
|
+
'Respond in EXACTLY this format (3 lines, no extra text):',
|
|
143
|
+
'VERDICT: WORKING or STALLED',
|
|
144
|
+
'MINUTES: <number 1-10, only if WORKING, how many more minutes to allow>',
|
|
145
|
+
'REASON: <brief one-line explanation>',
|
|
146
|
+
].join('\n');
|
|
147
|
+
try {
|
|
148
|
+
if (verbose) {
|
|
149
|
+
console.log(`[TOOL-ASSESS] Running Haiku assessment for ${toolName} (${elapsedSec}s elapsed)...`);
|
|
150
|
+
}
|
|
151
|
+
return await spawnHaikuVerdict(prompt, claudeCommand, verbose, 'TOOL-ASSESS');
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
if (verbose) {
|
|
155
|
+
console.log(`[TOOL-ASSESS] Haiku assessment failed: ${err}`);
|
|
156
|
+
}
|
|
157
|
+
// On failure, default to kill (the tool has already exceeded its timeout)
|
|
158
|
+
return {
|
|
159
|
+
action: 'kill',
|
|
160
|
+
extensionMs: 0,
|
|
161
|
+
reason: `Tool timeout assessment failed: ${err}`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Assess whether a Claude Code session lost context after tool timeouts.
|
|
167
|
+
* Uses Haiku with enriched context signals — replaces brittle hardcoded
|
|
168
|
+
* thresholds (200 chars thinking, 2x ratio, 500 chars response) with
|
|
169
|
+
* a single LLM call that sees the full picture.
|
|
170
|
+
*
|
|
171
|
+
* Only call this when effectiveTimeouts > 0.
|
|
172
|
+
*/
|
|
173
|
+
export async function assessContextLoss(ctx, claudeCommand, verbose) {
|
|
174
|
+
const tail = ctx.assistantResponse.slice(-800);
|
|
175
|
+
const prompt = [
|
|
176
|
+
'You are analyzing a Claude Code agent session that experienced tool timeouts.',
|
|
177
|
+
'Determine whether the agent lost context (needs recovery) or is still productively working.',
|
|
178
|
+
'',
|
|
179
|
+
'Session signals:',
|
|
180
|
+
`- ${ctx.effectiveTimeouts} tools timed out (${ctx.nativeTimeoutCount} detected in text stream, ${ctx.effectiveTimeouts - ctx.nativeTimeoutCount} detected structurally)`,
|
|
181
|
+
`- ${ctx.successfulToolCalls} tools completed successfully`,
|
|
182
|
+
`- Thinking output: ${ctx.thinkingOutputLength} characters`,
|
|
183
|
+
`- Response length: ${ctx.assistantResponse.length} characters`,
|
|
184
|
+
`- Successful file writes (Edit/Write/MultiEdit): ${ctx.hasSuccessfulWrite ? 'YES' : 'NO'}`,
|
|
185
|
+
'',
|
|
186
|
+
`Final response (last ${tail.length} chars):`,
|
|
187
|
+
tail,
|
|
188
|
+
'',
|
|
189
|
+
'WORKING signals: continued tool calls after timeouts, substantial thinking about the task, producing code/analysis, writing files, referencing the original task.',
|
|
190
|
+
'STALLED signals: asking "how can I help?", starting fresh, offering generic help, not referencing the original task, very short response with no substance, task abandoned mid-research.',
|
|
191
|
+
'',
|
|
192
|
+
'Respond in EXACTLY this format (2 lines, no extra text):',
|
|
193
|
+
'VERDICT: WORKING or STALLED',
|
|
194
|
+
'REASON: <brief one-line explanation>',
|
|
195
|
+
].join('\n');
|
|
196
|
+
try {
|
|
197
|
+
if (verbose) {
|
|
198
|
+
console.log(`[CONTEXT-ASSESS] Running Haiku assessment (${ctx.effectiveTimeouts} timeouts, ${ctx.successfulToolCalls} successes, ${ctx.thinkingOutputLength} thinking chars)...`);
|
|
199
|
+
}
|
|
200
|
+
const raw = await spawnHaikuRaw(prompt, claudeCommand, verbose, 'CONTEXT-ASSESS');
|
|
201
|
+
const parsed = parseVerdictResponse(raw);
|
|
202
|
+
const contextLost = parsed.verdict === 'STALLED';
|
|
203
|
+
if (verbose) {
|
|
204
|
+
console.log(`[CONTEXT-ASSESS] Verdict: ${contextLost ? 'LOST' : 'CONTINUED'} — ${parsed.reason}`);
|
|
205
|
+
}
|
|
206
|
+
return { contextLost, reason: parsed.reason };
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
if (verbose) {
|
|
210
|
+
console.log(`[CONTEXT-ASSESS] Haiku assessment failed: ${err}`);
|
|
211
|
+
}
|
|
212
|
+
// On failure, assume context was lost (safer to retry than to show a confused response)
|
|
213
|
+
return {
|
|
214
|
+
contextLost: true,
|
|
215
|
+
reason: `Context loss assessment failed: ${err}`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
82
219
|
function buildAssessmentPrompt(ctx) {
|
|
83
220
|
const silenceMin = Math.round(ctx.silenceMs / 60_000);
|
|
84
221
|
const totalMin = Math.round(ctx.elapsedTotalMs / 60_000);
|
|
@@ -137,8 +274,8 @@ function parseAssessmentResponse(output) {
|
|
|
137
274
|
};
|
|
138
275
|
}
|
|
139
276
|
const HAIKU_TIMEOUT_MS = 30_000;
|
|
140
|
-
|
|
141
|
-
|
|
277
|
+
/** Low-level Haiku spawner: runs a prompt through `claude --print --model haiku` and returns raw text */
|
|
278
|
+
function spawnHaikuRaw(prompt, claudeCommand, verbose, label) {
|
|
142
279
|
return new Promise((resolve, reject) => {
|
|
143
280
|
let stdout = '';
|
|
144
281
|
let settled = false;
|
|
@@ -155,7 +292,7 @@ function runHaikuAssessment(ctx, claudeCommand, verbose) {
|
|
|
155
292
|
});
|
|
156
293
|
proc.stderr.on('data', (data) => {
|
|
157
294
|
if (verbose) {
|
|
158
|
-
console.log(`[
|
|
295
|
+
console.log(`[${label}] haiku stderr: ${data.toString().trim()}`);
|
|
159
296
|
}
|
|
160
297
|
});
|
|
161
298
|
proc.on('close', (code) => {
|
|
@@ -168,9 +305,9 @@ function runHaikuAssessment(ctx, claudeCommand, verbose) {
|
|
|
168
305
|
return;
|
|
169
306
|
}
|
|
170
307
|
if (verbose) {
|
|
171
|
-
console.log(`[
|
|
308
|
+
console.log(`[${label}] Haiku response: ${stdout.trim()}`);
|
|
172
309
|
}
|
|
173
|
-
resolve(
|
|
310
|
+
resolve(stdout.trim());
|
|
174
311
|
});
|
|
175
312
|
proc.on('error', (err) => {
|
|
176
313
|
clearTimeout(timer);
|
|
@@ -181,4 +318,183 @@ function runHaikuAssessment(ctx, claudeCommand, verbose) {
|
|
|
181
318
|
});
|
|
182
319
|
});
|
|
183
320
|
}
|
|
321
|
+
/** Parse VERDICT/REASON format from Haiku response */
|
|
322
|
+
function parseVerdictResponse(raw) {
|
|
323
|
+
const lines = raw.split('\n');
|
|
324
|
+
let verdict = 'STALLED';
|
|
325
|
+
let reason = 'Assessment inconclusive';
|
|
326
|
+
for (const line of lines) {
|
|
327
|
+
const trimmed = line.trim();
|
|
328
|
+
if (trimmed.startsWith('VERDICT:')) {
|
|
329
|
+
verdict = trimmed.slice('VERDICT:'.length).trim().toUpperCase();
|
|
330
|
+
}
|
|
331
|
+
else if (trimmed.startsWith('REASON:')) {
|
|
332
|
+
reason = trimmed.slice('REASON:'.length).trim();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return { verdict, reason };
|
|
336
|
+
}
|
|
337
|
+
/** Haiku spawner that returns a parsed StallVerdict (for stall assessment) */
|
|
338
|
+
async function spawnHaikuVerdict(prompt, claudeCommand, verbose, label = 'STALL-ASSESS') {
|
|
339
|
+
const raw = await spawnHaikuRaw(prompt, claudeCommand, verbose, label);
|
|
340
|
+
return parseAssessmentResponse(raw);
|
|
341
|
+
}
|
|
342
|
+
function runHaikuAssessment(ctx, claudeCommand, verbose) {
|
|
343
|
+
return spawnHaikuVerdict(buildAssessmentPrompt(ctx), claudeCommand, verbose);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Assess whether a user message is an approval/continuation or a new task.
|
|
347
|
+
* Uses Haiku to classify intent — handles natural language variations that
|
|
348
|
+
* regex patterns miss ("sounds good", "yep do it", "option 2", etc.).
|
|
349
|
+
*/
|
|
350
|
+
export async function assessApproval(userMessage, claudeCommand, verbose) {
|
|
351
|
+
const prompt = [
|
|
352
|
+
'You are classifying a user message in a multi-turn conversation with a coding assistant.',
|
|
353
|
+
'The assistant previously proposed a plan or asked a question, and the user is now responding.',
|
|
354
|
+
'',
|
|
355
|
+
`User's message: "${userMessage}"`,
|
|
356
|
+
'',
|
|
357
|
+
'Is this an approval/continuation (user agrees, says yes, wants to proceed) or a new task/question?',
|
|
358
|
+
'',
|
|
359
|
+
'APPROVAL signs: "yes", "sure", "go ahead", "sounds good", "do it", "yep", "option 2", "the first one", "proceed", references to previous proposal, short affirmative with modifications ("yes but use TypeScript").',
|
|
360
|
+
'NEW_TASK signs: asks a different question, gives new detailed instructions, changes topic, provides new requirements unrelated to any proposal.',
|
|
361
|
+
'',
|
|
362
|
+
'Respond in EXACTLY this format (2 lines, no extra text):',
|
|
363
|
+
'VERDICT: APPROVAL or NEW_TASK',
|
|
364
|
+
'REASON: <brief one-line explanation>',
|
|
365
|
+
].join('\n');
|
|
366
|
+
try {
|
|
367
|
+
if (verbose) {
|
|
368
|
+
console.log('[APPROVAL-ASSESS] Running Haiku assessment...');
|
|
369
|
+
}
|
|
370
|
+
const raw = await spawnHaikuRaw(prompt, claudeCommand, verbose, 'APPROVAL-ASSESS');
|
|
371
|
+
const parsed = parseVerdictResponse(raw);
|
|
372
|
+
const isApproval = parsed.verdict.includes('APPROVAL');
|
|
373
|
+
if (verbose) {
|
|
374
|
+
console.log(`[APPROVAL-ASSESS] Verdict: ${isApproval ? 'APPROVAL' : 'NEW_TASK'} — ${parsed.reason}`);
|
|
375
|
+
}
|
|
376
|
+
return { isApproval, reason: parsed.reason };
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
if (verbose) {
|
|
380
|
+
console.log(`[APPROVAL-ASSESS] Haiku assessment failed: ${err}`);
|
|
381
|
+
}
|
|
382
|
+
// On failure, assume not an approval (safer to treat as new task)
|
|
383
|
+
return { isApproval: false, reason: `Assessment failed: ${err}` };
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Compare two retry results and determine which made more meaningful progress.
|
|
388
|
+
* Uses Haiku to evaluate quality — replaces arbitrary numeric scoring
|
|
389
|
+
* (tool count * 10 + response length / 50 + thinking bonus).
|
|
390
|
+
*/
|
|
391
|
+
export async function assessBestResult(ctx, claudeCommand, verbose) {
|
|
392
|
+
const promptPreview = ctx.originalPrompt.length > 300
|
|
393
|
+
? `${ctx.originalPrompt.slice(0, 300)}...`
|
|
394
|
+
: ctx.originalPrompt;
|
|
395
|
+
const prompt = [
|
|
396
|
+
'You are comparing two AI assistant responses from retry attempts to determine which made more meaningful progress on the user\'s task.',
|
|
397
|
+
'',
|
|
398
|
+
`Original task: ${promptPreview}`,
|
|
399
|
+
'',
|
|
400
|
+
`Response A: ${ctx.resultA.successfulToolCalls} successful tool calls, ${ctx.resultA.responseLength} chars, ${ctx.resultA.hasThinking ? 'has' : 'no'} thinking output`,
|
|
401
|
+
`Last 500 chars of A: ${ctx.resultA.responseTail}`,
|
|
402
|
+
'',
|
|
403
|
+
`Response B: ${ctx.resultB.successfulToolCalls} successful tool calls, ${ctx.resultB.responseLength} chars, ${ctx.resultB.hasThinking ? 'has' : 'no'} thinking output`,
|
|
404
|
+
`Last 500 chars of B: ${ctx.resultB.responseTail}`,
|
|
405
|
+
'',
|
|
406
|
+
'Which response made more meaningful progress? Consider:',
|
|
407
|
+
'- Did it actually work on the task (tool calls, code changes) vs just talking about it?',
|
|
408
|
+
'- Is it confused/lost context ("How can I help?") vs engaged with the original task?',
|
|
409
|
+
'- Quality of analysis and output, not just quantity.',
|
|
410
|
+
'',
|
|
411
|
+
'Respond in EXACTLY this format (2 lines, no extra text):',
|
|
412
|
+
'VERDICT: A or B',
|
|
413
|
+
'REASON: <brief one-line explanation>',
|
|
414
|
+
].join('\n');
|
|
415
|
+
try {
|
|
416
|
+
if (verbose) {
|
|
417
|
+
console.log('[BEST-RESULT] Running Haiku assessment...');
|
|
418
|
+
}
|
|
419
|
+
const raw = await spawnHaikuRaw(prompt, claudeCommand, verbose, 'BEST-RESULT');
|
|
420
|
+
const parsed = parseVerdictResponse(raw);
|
|
421
|
+
const winner = parsed.verdict.includes('B') ? 'B' : 'A';
|
|
422
|
+
if (verbose) {
|
|
423
|
+
console.log(`[BEST-RESULT] Verdict: ${winner} — ${parsed.reason}`);
|
|
424
|
+
}
|
|
425
|
+
return { winner, reason: parsed.reason };
|
|
426
|
+
}
|
|
427
|
+
catch (err) {
|
|
428
|
+
if (verbose) {
|
|
429
|
+
console.log(`[BEST-RESULT] Haiku assessment failed: ${err}`);
|
|
430
|
+
}
|
|
431
|
+
// On failure, prefer A (the previously-tracked best result)
|
|
432
|
+
return { winner: 'A', reason: `Assessment failed: ${err}` };
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Classify an unrecognized error from stderr using Haiku.
|
|
437
|
+
* Called as a fallback when regex patterns in output-utils.ts don't match.
|
|
438
|
+
* Returns null if the stderr content isn't a real error (just warnings/debug info).
|
|
439
|
+
*/
|
|
440
|
+
export async function classifyError(stderrContent, claudeCommand, verbose) {
|
|
441
|
+
const tail = stderrContent.slice(-500);
|
|
442
|
+
if (!tail.trim())
|
|
443
|
+
return null;
|
|
444
|
+
const prompt = [
|
|
445
|
+
'You are classifying an error message from the Claude Code CLI that did not match known patterns.',
|
|
446
|
+
'',
|
|
447
|
+
`stderr (last ${tail.length} chars):`,
|
|
448
|
+
tail,
|
|
449
|
+
'',
|
|
450
|
+
'Classify into one of these categories:',
|
|
451
|
+
'- AUTH_REQUIRED: Authentication/login issues',
|
|
452
|
+
'- API_KEY_INVALID: API key problems',
|
|
453
|
+
'- QUOTA_EXCEEDED: Usage limits, billing, subscription',
|
|
454
|
+
'- RATE_LIMITED: Too many requests, throttling',
|
|
455
|
+
'- NETWORK_ERROR: Connection, DNS, timeout issues',
|
|
456
|
+
'- SSL_ERROR: Certificate/TLS problems',
|
|
457
|
+
'- SERVICE_UNAVAILABLE: Backend down (502/503/504)',
|
|
458
|
+
'- INTERNAL_ERROR: Server errors (500)',
|
|
459
|
+
'- CONTEXT_TOO_LONG: Token/context limit exceeded',
|
|
460
|
+
'- SESSION_NOT_FOUND: Invalid/expired session',
|
|
461
|
+
'- UNKNOWN: Cannot determine, not a real error, or just warnings/debug output',
|
|
462
|
+
'',
|
|
463
|
+
'If the stderr content is just warnings, debug info, or not an actual error, use UNKNOWN.',
|
|
464
|
+
'',
|
|
465
|
+
'Respond in EXACTLY this format (2 lines, no extra text):',
|
|
466
|
+
'CATEGORY: <one of the above>',
|
|
467
|
+
'MESSAGE: <brief user-friendly description of the error>',
|
|
468
|
+
].join('\n');
|
|
469
|
+
try {
|
|
470
|
+
if (verbose) {
|
|
471
|
+
console.log('[ERROR-CLASSIFY] Running Haiku assessment...');
|
|
472
|
+
}
|
|
473
|
+
const raw = await spawnHaikuRaw(prompt, claudeCommand, verbose, 'ERROR-CLASSIFY');
|
|
474
|
+
const lines = raw.split('\n');
|
|
475
|
+
let category = 'UNKNOWN';
|
|
476
|
+
let message = '';
|
|
477
|
+
for (const line of lines) {
|
|
478
|
+
const trimmed = line.trim();
|
|
479
|
+
if (trimmed.startsWith('CATEGORY:')) {
|
|
480
|
+
category = trimmed.slice('CATEGORY:'.length).trim().toUpperCase();
|
|
481
|
+
}
|
|
482
|
+
else if (trimmed.startsWith('MESSAGE:')) {
|
|
483
|
+
message = trimmed.slice('MESSAGE:'.length).trim();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (category === 'UNKNOWN' || !message)
|
|
487
|
+
return null;
|
|
488
|
+
if (verbose) {
|
|
489
|
+
console.log(`[ERROR-CLASSIFY] Verdict: ${category} — ${message}`);
|
|
490
|
+
}
|
|
491
|
+
return { errorCode: category, message };
|
|
492
|
+
}
|
|
493
|
+
catch (err) {
|
|
494
|
+
if (verbose) {
|
|
495
|
+
console.log(`[ERROR-CLASSIFY] Haiku assessment failed: ${err}`);
|
|
496
|
+
}
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
184
500
|
//# sourceMappingURL=stall-assessor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stall-assessor.js","sourceRoot":"","sources":["../../../../server/cli/headless/stall-assessor.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stall-assessor.js","sourceRoot":"","sources":["../../../../server/cli/headless/stall-assessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Watchdog
|
|
3
|
+
*
|
|
4
|
+
* Per-tool adaptive timeout system using TCP RTO-style EMA tracking (RFC 6298).
|
|
5
|
+
* Monitors individual tool call durations and kills tools that exceed their
|
|
6
|
+
* adaptive timeout, preserving work via checkpoint-and-retry.
|
|
7
|
+
*
|
|
8
|
+
* Three-tier timeout strategy:
|
|
9
|
+
* 1. EMA tracking: timeout = estimatedDuration + 4 * deviation
|
|
10
|
+
* 2. Floor/ceiling bounds: never kill below floor, always kill at ceiling
|
|
11
|
+
* 3. Haiku tiebreaker: optional AI assessment before killing ambiguous cases
|
|
12
|
+
*/
|
|
13
|
+
import type { ExecutionCheckpoint, ToolTimeoutProfile, ToolUseAccumulator } from './types.js';
|
|
14
|
+
/** Default timeout profiles per tool type */
|
|
15
|
+
export declare const DEFAULT_TOOL_TIMEOUT_PROFILES: Record<string, ToolTimeoutProfile>;
|
|
16
|
+
export interface ToolWatchdogOptions {
|
|
17
|
+
profiles?: Record<string, Partial<ToolTimeoutProfile>>;
|
|
18
|
+
verbose?: boolean;
|
|
19
|
+
/** Called before killing — if returns 'extend', reschedule with extensionMs */
|
|
20
|
+
onTiebreaker?: (toolName: string, toolInput: Record<string, unknown>, elapsedMs: number) => Promise<{
|
|
21
|
+
action: 'extend' | 'kill';
|
|
22
|
+
extensionMs: number;
|
|
23
|
+
reason: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
interface ActiveWatch {
|
|
27
|
+
toolName: string;
|
|
28
|
+
toolInput: Record<string, unknown>;
|
|
29
|
+
startTime: number;
|
|
30
|
+
timer: ReturnType<typeof setTimeout>;
|
|
31
|
+
timeoutMs: number;
|
|
32
|
+
tiebreakerAttempted: boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare class ToolWatchdog {
|
|
35
|
+
private trackers;
|
|
36
|
+
private profiles;
|
|
37
|
+
private activeWatches;
|
|
38
|
+
private verbose;
|
|
39
|
+
private onTiebreaker?;
|
|
40
|
+
constructor(options?: ToolWatchdogOptions);
|
|
41
|
+
/** Record a tool completion — updates the EMA tracker for its type */
|
|
42
|
+
recordCompletion(toolName: string, durationMs: number): void;
|
|
43
|
+
/** Compute the current timeout for a tool type */
|
|
44
|
+
getTimeout(toolName: string): number;
|
|
45
|
+
/** Get the profile for a tool (with fallback to default) */
|
|
46
|
+
getProfile(toolName: string): ToolTimeoutProfile;
|
|
47
|
+
/** Start watching a tool call */
|
|
48
|
+
startWatch(toolId: string, toolName: string, toolInput: Record<string, unknown>, onTimeout: () => void): void;
|
|
49
|
+
/** Handle timeout expiry: attempt tiebreaker if configured, return true if extended */
|
|
50
|
+
private handleTimeoutWithTiebreaker;
|
|
51
|
+
/** Execute the Haiku tiebreaker and reschedule if extended */
|
|
52
|
+
private runTiebreaker;
|
|
53
|
+
/** Schedule a post-extension timeout that kills without another tiebreaker */
|
|
54
|
+
private scheduleExtensionTimeout;
|
|
55
|
+
/** Stop watching a tool (it completed normally) */
|
|
56
|
+
clearWatch(toolId: string): void;
|
|
57
|
+
/** Clear all active watches (process ending) */
|
|
58
|
+
clearAll(): void;
|
|
59
|
+
/** Get the active watch for a tool ID (for checkpoint building) */
|
|
60
|
+
getActiveWatch(toolId: string): ActiveWatch | undefined;
|
|
61
|
+
/** Get all active watches */
|
|
62
|
+
getActiveWatches(): Map<string, ActiveWatch>;
|
|
63
|
+
/** Build an ExecutionCheckpoint from the current state */
|
|
64
|
+
buildCheckpoint(originalPrompt: string, assistantText: string, thinkingText: string, accumulatedToolUse: ToolUseAccumulator[], hungToolId: string, claudeSessionId: string | undefined, processStartTime: number): ExecutionCheckpoint | null;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=tool-watchdog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-watchdog.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/tool-watchdog.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,mBAAmB,EAEnB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAOpB,6CAA6C;AAC7C,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAiE5E,CAAC;AAUF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzK;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,YAAY,CAAC,CAAsC;gBAE/C,OAAO,GAAE,mBAAwB;IAc7C,sEAAsE;IACtE,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IA2B5D,kDAAkD;IAClD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAWpC,4DAA4D;IAC5D,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB;IAIhD,iCAAiC;IACjC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,IAAI,GAAG,IAAI;IA8B7G,uFAAuF;YACzE,2BAA2B;IAsBzC,8DAA8D;YAChD,aAAa;IAsC3B,8EAA8E;IAC9E,OAAO,CAAC,wBAAwB;IAmBhC,mDAAmD;IACnD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQhC,gDAAgD;IAChD,QAAQ,IAAI,IAAI;IAOhB,mEAAmE;IACnE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIvD,6BAA6B;IAC7B,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAI5C,0DAA0D;IAC1D,eAAe,CACb,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,kBAAkB,EAAE,EACxC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,gBAAgB,EAAE,MAAM,GACvB,mBAAmB,GAAG,IAAI;CAsD9B"}
|