mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 14:39:42 +02:00
fix: rock-solid idle detection in respawn controller
- Add 300-char rolling window to catch working patterns split across PTY chunks - Check completion message BEFORE working patterns (priority fix) - Clear rolling window on completion message (transition point) - Increase working pattern absence threshold from 3s to 8s - Add Session.isWorking safety check before confirming idle - Add 20+ more working patterns (Compiling, Building, Processing, etc.) - Make AI idle checker prompt more conservative (err toward WORKING) - Update documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+49
-2
@@ -21,13 +21,14 @@ import { existsSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import * as pty from 'node-pty';
|
||||
import { SessionState, SessionStatus, SessionConfig, ScreenSession, RalphTrackerState, RalphTodoItem } from './types.js';
|
||||
import { SessionState, SessionStatus, SessionConfig, ScreenSession, RalphTrackerState, RalphTodoItem, ActiveBashTool } from './types.js';
|
||||
import { TaskTracker, type BackgroundTask } from './task-tracker.js';
|
||||
import { RalphTracker } from './ralph-tracker.js';
|
||||
import { BashToolParser } from './bash-tool-parser.js';
|
||||
import { ScreenManager } from './screen-manager.js';
|
||||
|
||||
export type { BackgroundTask } from './task-tracker.js';
|
||||
export type { RalphTrackerState, RalphTodoItem } from './types.js';
|
||||
export type { RalphTrackerState, RalphTodoItem, ActiveBashTool } from './types.js';
|
||||
export { withTimeout };
|
||||
|
||||
// ============================================================================
|
||||
@@ -292,6 +293,12 @@ export interface SessionEvents {
|
||||
ralphTodoUpdate: (todos: RalphTodoItem[]) => void;
|
||||
/** Ralph completion phrase detected */
|
||||
ralphCompletionDetected: (phrase: string) => void;
|
||||
/** Bash tool with file paths started */
|
||||
bashToolStart: (tool: ActiveBashTool) => void;
|
||||
/** Bash tool completed */
|
||||
bashToolEnd: (tool: ActiveBashTool) => void;
|
||||
/** Active Bash tools list updated */
|
||||
bashToolsUpdate: (tools: ActiveBashTool[]) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,6 +417,14 @@ export class Session extends EventEmitter {
|
||||
completionDetected: (phrase: string) => void;
|
||||
} | null = null;
|
||||
|
||||
// Bash tool tracking (file paths for live log viewing)
|
||||
private _bashToolParser: BashToolParser;
|
||||
private _bashToolHandlers: {
|
||||
toolStart: (tool: ActiveBashTool) => void;
|
||||
toolEnd: (tool: ActiveBashTool) => void;
|
||||
toolsUpdate: (tools: ActiveBashTool[]) => void;
|
||||
} | null = null;
|
||||
|
||||
constructor(config: Partial<SessionConfig> & {
|
||||
workingDir: string;
|
||||
mode?: SessionMode;
|
||||
@@ -453,6 +468,17 @@ export class Session extends EventEmitter {
|
||||
this._ralphTracker.on('todoUpdate', this._ralphHandlers.todoUpdate);
|
||||
this._ralphTracker.on('completionDetected', this._ralphHandlers.completionDetected);
|
||||
|
||||
// Initialize Bash tool parser and forward events (store handlers for cleanup)
|
||||
this._bashToolParser = new BashToolParser({ sessionId: this.id });
|
||||
this._bashToolHandlers = {
|
||||
toolStart: (tool) => this.emit('bashToolStart', tool),
|
||||
toolEnd: (tool) => this.emit('bashToolEnd', tool),
|
||||
toolsUpdate: (tools) => this.emit('bashToolsUpdate', tools),
|
||||
};
|
||||
this._bashToolParser.on('toolStart', this._bashToolHandlers.toolStart);
|
||||
this._bashToolParser.on('toolEnd', this._bashToolHandlers.toolEnd);
|
||||
this._bashToolParser.on('toolsUpdate', this._bashToolHandlers.toolsUpdate);
|
||||
|
||||
}
|
||||
|
||||
get status(): SessionStatus {
|
||||
@@ -540,6 +566,15 @@ export class Session extends EventEmitter {
|
||||
return this._ralphTracker.getTodoStats();
|
||||
}
|
||||
|
||||
// Bash tool tracking getters
|
||||
get bashToolParser(): BashToolParser {
|
||||
return this._bashToolParser;
|
||||
}
|
||||
|
||||
get activeTools(): ActiveBashTool[] {
|
||||
return this._bashToolParser.activeTools;
|
||||
}
|
||||
|
||||
get parentAgentId(): string | null {
|
||||
return this._parentAgentId;
|
||||
}
|
||||
@@ -852,6 +887,9 @@ export class Session extends EventEmitter {
|
||||
// Forward to Ralph tracker to detect Ralph loops and todos
|
||||
this._ralphTracker.processTerminalData(data);
|
||||
|
||||
// Forward to Bash tool parser to detect file-viewing commands
|
||||
this._bashToolParser.processTerminalData(data);
|
||||
|
||||
// Parse token count from status line (e.g., "123.4k tokens" or "5234 tokens")
|
||||
this.parseTokensFromStatusLine(data);
|
||||
|
||||
@@ -1503,6 +1541,15 @@ export class Session extends EventEmitter {
|
||||
this._ralphHandlers = null;
|
||||
}
|
||||
|
||||
// Remove BashToolParser handlers
|
||||
if (this._bashToolHandlers) {
|
||||
this._bashToolParser.off('toolStart', this._bashToolHandlers.toolStart);
|
||||
this._bashToolParser.off('toolEnd', this._bashToolHandlers.toolEnd);
|
||||
this._bashToolParser.off('toolsUpdate', this._bashToolHandlers.toolsUpdate);
|
||||
this._bashToolHandlers = null;
|
||||
}
|
||||
this._bashToolParser.destroy();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user