diff --git a/src/core/piece/agent-usecases.ts b/src/core/piece/agent-usecases.ts index 2c20ee2..8dff719 100644 --- a/src/core/piece/agent-usecases.ts +++ b/src/core/piece/agent-usecases.ts @@ -10,6 +10,7 @@ export interface JudgeStatusOptions { cwd: string; movementName: string; language?: Language; + interactive?: boolean; } export interface JudgeStatusResult { @@ -98,6 +99,14 @@ export async function judgeStatus( return { ruleIndex: 0, method: 'auto_select' }; } + const interactiveEnabled = options.interactive === true; + + const isValidRuleIndex = (index: number): boolean => { + if (index < 0 || index >= rules.length) return false; + const rule = rules[index]; + return !(rule?.interactiveOnly && !interactiveEnabled); + }; + const agentOptions = { cwd: options.cwd, maxTurns: 3, @@ -115,7 +124,7 @@ export async function judgeStatus( const stepNumber = structuredResponse.structuredOutput?.step; if (typeof stepNumber === 'number' && Number.isInteger(stepNumber)) { const ruleIndex = stepNumber - 1; - if (ruleIndex >= 0 && ruleIndex < rules.length) { + if (isValidRuleIndex(ruleIndex)) { return { ruleIndex, method: 'structured_output' }; } } @@ -126,16 +135,25 @@ export async function judgeStatus( if (tagResponse.status === 'done') { const tagRuleIndex = detectRuleIndex(tagResponse.content, options.movementName); - if (tagRuleIndex >= 0 && tagRuleIndex < rules.length) { + if (isValidRuleIndex(tagRuleIndex)) { return { ruleIndex: tagRuleIndex, method: 'phase3_tag' }; } } // Stage 3: AI judge - const conditions = rules.map((rule, index) => ({ index, text: rule.condition })); - const fallbackIndex = await evaluateCondition(structuredInstruction, conditions, { cwd: options.cwd }); - if (fallbackIndex >= 0 && fallbackIndex < rules.length) { - return { ruleIndex: fallbackIndex, method: 'ai_judge' }; + const conditions = rules + .map((rule, index) => ({ rule, index })) + .filter(({ rule }) => interactiveEnabled || !rule.interactiveOnly) + .map(({ index, rule }) => ({ index, text: rule.condition })); + + if (conditions.length > 0) { + const fallbackIndex = await evaluateCondition(structuredInstruction, conditions, { cwd: options.cwd }); + if (fallbackIndex >= 0 && fallbackIndex < conditions.length) { + const originalIndex = conditions[fallbackIndex]?.index; + if (originalIndex !== undefined) { + return { ruleIndex: originalIndex, method: 'ai_judge' }; + } + } } throw new Error(`Status not found for movement "${options.movementName}"`); diff --git a/src/core/piece/status-judgment-phase.ts b/src/core/piece/status-judgment-phase.ts index 3c5d899..618de99 100644 --- a/src/core/piece/status-judgment-phase.ts +++ b/src/core/piece/status-judgment-phase.ts @@ -36,6 +36,7 @@ function buildBaseContext( if (reports.length > 0) { return { language: ctx.language, + interactive: ctx.interactive, reportContent: reports.join('\n\n---\n\n'), inputSource: 'report', }; @@ -46,6 +47,7 @@ function buildBaseContext( return { language: ctx.language, + interactive: ctx.interactive, lastResponse: ctx.lastResponse, inputSource: 'response', }; @@ -89,6 +91,7 @@ export async function runStatusJudgmentPhase( cwd: ctx.cwd, movementName: step.name, language: ctx.language, + interactive: ctx.interactive, }); const tag = `[${step.name.toUpperCase()}:${result.ruleIndex + 1}]`; ctx.onPhaseComplete?.(step, 3, 'judge', tag, 'done');