概要
commandmate wait にターミナル出力のパターンマッチによるLLM APIエラー検出機能を追加し、exit code 3 で返却する。
関連: Issue #518(CLI基盤), Issue #520(wait完了検出)
構想ドキュメント: workspace/v0.5/orchestration-concept.html セクション「子エージェントのエラー検出とリカバリ」
背景
現在の wait はエージェントのステータス(idle/ready/running/waiting)のみを監視しており、ターミナル出力の内容は検査していない。LLM APIエラー(Rate limit, ネットワークエラー等)でエージェントが停止しても、tmuxセッションは生存しているため sessionStatus=running のまま、タイムアウトまで待ち続ける。
# 現状: Rate limit でエージェントが止まっても検知できない
commandmate wait localllm-test-main --timeout 600
# → 10分間ただ待つだけ → exit 124 (タイムアウト)
検出対象パターン
| エラー種別 |
検出パターン例 |
retryable |
| APIレート制限 |
rate limit, 429, overloaded, too many requests |
true |
| ネットワークエラー |
ECONNREFUSED, ETIMEDOUT, fetch failed, network error |
true |
| 認証エラー |
unauthorized, invalid API key, 401, 403 |
false |
| サーバーエラー |
500, 502, 503, internal server error |
true |
実装方針
wait のポーリングループにパターンマッチを追加
current-output API の content または fullOutput に対して、エラーパターンを検査する。
// wait.ts のポーリングループ内(sessionStatus チェック後)
const errorMatch = detectLlmError(data.content || data.fullOutput || '');
if (errorMatch) {
const errorOutput = {
worktreeId,
errorType: errorMatch.type,
message: errorMatch.message,
retryable: errorMatch.retryable,
};
return { exitCode: WaitExitCode.LLM_ERROR, output: errorOutput };
}
exit code 3 の追加
// types/index.ts
export const WaitExitCode = {
SUCCESS: 0,
PROMPT_DETECTED: 10,
LLM_ERROR: 3, // ← 新規
TIMEOUT: 124,
} as const;
エラー検出関数
// cli/utils/llm-error-detector.ts
interface LlmErrorMatch {
type: 'rate_limit' | 'network_error' | 'auth_error' | 'server_error';
message: string;
retryable: boolean;
}
function detectLlmError(output: string): LlmErrorMatch | null {
// 出力の末尾N行のみ検査(パフォーマンス + 過去のエラーを誤検出しない)
const tail = getLastNLines(output, 20);
// パターンマッチ...
}
stdout出力(exit 3 時)
{
"worktreeId": "localllm-test-main",
"errorType": "rate_limit",
"message": "API Error: Rate limit reached",
"retryable": true
}
使用例
commandmate wait localllm-test-main --timeout 600
# exit 3 の場合:
# stdout: {"worktreeId":"...","errorType":"rate_limit","message":"...","retryable":true}
# 親エージェントのリカバリ
EXIT_CODE=$?
if [ $EXIT_CODE -eq 3 ]; then
ERROR_JSON=$(commandmate wait ... 2>/dev/null)
RETRYABLE=$(echo "$ERROR_JSON" | jq -r '.retryable')
if [ "$RETRYABLE" = "true" ]; then
sleep 60 # 待機後リトライ
commandmate send "$WT" "続けてください"
else
echo "リカバリ不可能なエラー"
fi
fi
注意事項
- エラーパターンは出力の末尾N行のみを検査する(過去のエラーメッセージを誤検出しない)
- パターンはCLI側に定義(サーバー側の変更は不要)
- 既存の
--stall-timeout との併用可能(stall-timeoutは出力変化なし、LLMエラー検出は特定パターン)
受け入れ条件
影響範囲
| ファイル |
変更内容 |
src/cli/utils/llm-error-detector.ts |
新規: エラーパターン検出関数 |
src/cli/commands/wait.ts |
ポーリングループにエラー検出追加 |
src/cli/types/index.ts |
WaitExitCode.LLM_ERROR = 3 追加 |
src/cli/types/api-responses.ts |
エラー出力型追加 |
src/cli/docs/agent-operations.ts |
ドキュメント更新(exit 3 追記) |
tests/unit/cli/commands/wait.test.ts |
テスト追加 |
tests/unit/cli/utils/llm-error-detector.test.ts |
新規テスト |
概要
commandmate waitにターミナル出力のパターンマッチによるLLM APIエラー検出機能を追加し、exit code 3 で返却する。関連: Issue #518(CLI基盤), Issue #520(wait完了検出)
構想ドキュメント:
workspace/v0.5/orchestration-concept.htmlセクション「子エージェントのエラー検出とリカバリ」背景
現在の
waitはエージェントのステータス(idle/ready/running/waiting)のみを監視しており、ターミナル出力の内容は検査していない。LLM APIエラー(Rate limit, ネットワークエラー等)でエージェントが停止しても、tmuxセッションは生存しているためsessionStatus=runningのまま、タイムアウトまで待ち続ける。検出対象パターン
rate limit,429,overloaded,too many requestsECONNREFUSED,ETIMEDOUT,fetch failed,network errorunauthorized,invalid API key,401,403500,502,503,internal server error実装方針
wait のポーリングループにパターンマッチを追加
current-outputAPI のcontentまたはfullOutputに対して、エラーパターンを検査する。exit code 3 の追加
エラー検出関数
stdout出力(exit 3 時)
{ "worktreeId": "localllm-test-main", "errorType": "rate_limit", "message": "API Error: Rate limit reached", "retryable": true }使用例
注意事項
--stall-timeoutとの併用可能(stall-timeoutは出力変化なし、LLMエラー検出は特定パターン)受け入れ条件
retryableフラグが正しく設定される影響範囲
src/cli/utils/llm-error-detector.tssrc/cli/commands/wait.tssrc/cli/types/index.tsWaitExitCode.LLM_ERROR = 3追加src/cli/types/api-responses.tssrc/cli/docs/agent-operations.tstests/unit/cli/commands/wait.test.tstests/unit/cli/utils/llm-error-detector.test.ts