From 872ff5fa36ae34e355b461218b128aac871d2ae2 Mon Sep 17 00:00:00 2001 From: nrslib <38722970+nrslib@users.noreply.github.com> Date: Mon, 2 Mar 2026 14:24:57 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20decomposeTask=20/=20requestMoreParts=20?= =?UTF-8?q?/=20judgeStatus=20=E3=81=AB=E3=83=97=E3=83=AD=E3=83=90=E3=82=A4?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=82=A4=E3=83=99=E3=83=B3=E3=83=88=E3=83=AD?= =?UTF-8?q?=E3=82=AE=E3=83=B3=E3=82=B0=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit onStream を各オプション型に追加し、runAgent 呼び出しに伝播させる。 これにより team_leader の分解フェーズや Phase 3 判定のイベントが provider-events.jsonl に記録されるようになる。 変更ファイル: - agent-usecases.ts: JudgeStatusOptions / DecomposeTaskOptions に onStream 追加 - phase-runner.ts: PhaseRunnerContext に onStream 追加 - status-judgment-phase.ts: judgeStatus に ctx.onStream を渡す - OptionsBuilder.ts: buildPhaseRunnerContext の戻り値に onStream を含める - TeamLeaderRunner.ts: decomposeTask / requestMoreParts に engineOptions.onStream を渡す --- src/core/piece/agent-usecases.ts | 7 ++++++- src/core/piece/engine/OptionsBuilder.ts | 1 + src/core/piece/engine/TeamLeaderRunner.ts | 2 ++ src/core/piece/phase-runner.ts | 2 ++ src/core/piece/status-judgment-phase.ts | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/core/piece/agent-usecases.ts b/src/core/piece/agent-usecases.ts index 4a373db..8f42623 100644 --- a/src/core/piece/agent-usecases.ts +++ b/src/core/piece/agent-usecases.ts @@ -1,5 +1,5 @@ import type { AgentResponse, PartDefinition, PieceRule, RuleMatchMethod, Language } from '../models/types.js'; -import { runAgent, type RunAgentOptions } from '../../agents/runner.js'; +import { runAgent, type RunAgentOptions, type StreamCallback } from '../../agents/runner.js'; import { detectJudgeIndex, buildJudgePrompt } from '../../agents/judge-utils.js'; import { parseParts } from './engine/task-decomposer.js'; import { loadJudgmentSchema, loadEvaluationSchema, loadDecompositionSchema, loadMorePartsSchema } from './schema-loader.js'; @@ -11,6 +11,7 @@ export interface JudgeStatusOptions { movementName: string; language?: Language; interactive?: boolean; + onStream?: StreamCallback; } export interface JudgeStatusResult { @@ -29,6 +30,7 @@ export interface DecomposeTaskOptions { language?: Language; model?: string; provider?: 'claude' | 'codex' | 'opencode' | 'cursor' | 'copilot' | 'mock'; + onStream?: StreamCallback; } export interface MorePartsResponse { @@ -231,6 +233,7 @@ export async function judgeStatus( maxTurns: 3, permissionMode: 'readonly' as const, language: options.language, + onStream: options.onStream, }; // Stage 1: Structured output @@ -293,6 +296,7 @@ export async function decomposeTask( permissionMode: 'readonly', maxTurns: 4, outputSchema: loadDecompositionSchema(maxParts), + onStream: options.onStream, }); if (response.status !== 'done') { @@ -333,6 +337,7 @@ export async function requestMoreParts( permissionMode: 'readonly', maxTurns: 4, outputSchema: loadMorePartsSchema(maxAdditionalParts), + onStream: options.onStream, }); if (response.status !== 'done') { diff --git a/src/core/piece/engine/OptionsBuilder.ts b/src/core/piece/engine/OptionsBuilder.ts index 78231bf..5096e4b 100644 --- a/src/core/piece/engine/OptionsBuilder.ts +++ b/src/core/piece/engine/OptionsBuilder.ts @@ -173,6 +173,7 @@ export class OptionsBuilder { language: this.getLanguage(), interactive: this.engineOptions.interactive, lastResponse, + onStream: this.engineOptions.onStream, getSessionId: (persona: string) => state.personaSessions.get(persona), buildResumeOptions: this.buildResumeOptions.bind(this), buildNewSessionReportOptions: this.buildNewSessionReportOptions.bind(this), diff --git a/src/core/piece/engine/TeamLeaderRunner.ts b/src/core/piece/engine/TeamLeaderRunner.ts index af51807..b6b4432 100644 --- a/src/core/piece/engine/TeamLeaderRunner.ts +++ b/src/core/piece/engine/TeamLeaderRunner.ts @@ -79,6 +79,7 @@ export class TeamLeaderRunner { personaPath: leaderStep.personaPath, model: leaderModel, provider: leaderProvider, + onStream: this.deps.engineOptions.onStream, }); const leaderResponse: AgentResponse = { persona: leaderStep.persona ?? leaderStep.name, @@ -172,6 +173,7 @@ export class TeamLeaderRunner { language: this.deps.engineOptions.language, model: leaderModel, provider: leaderProvider, + onStream: this.deps.engineOptions.onStream, }, ); }, diff --git a/src/core/piece/phase-runner.ts b/src/core/piece/phase-runner.ts index 0feaada..4a210cd 100644 --- a/src/core/piece/phase-runner.ts +++ b/src/core/piece/phase-runner.ts @@ -41,6 +41,8 @@ export interface PhaseRunnerContext { buildNewSessionReportOptions: (step: PieceMovement, overrides: Pick) => RunAgentOptions; /** Update persona session after a phase run */ updatePersonaSession: (persona: string, sessionId: string | undefined) => void; + /** Stream callback for provider event logging (passed to judgeStatus) */ + onStream?: import('../../agents/types.js').StreamCallback; /** Callback for phase lifecycle logging */ onPhaseStart?: (step: PieceMovement, phase: 1 | 2 | 3, phaseName: PhaseName, instruction: string) => void; /** Callback for phase completion logging */ diff --git a/src/core/piece/status-judgment-phase.ts b/src/core/piece/status-judgment-phase.ts index 2821166..7b1ed8b 100644 --- a/src/core/piece/status-judgment-phase.ts +++ b/src/core/piece/status-judgment-phase.ts @@ -93,6 +93,7 @@ export async function runStatusJudgmentPhase( movementName: step.name, language: ctx.language, interactive: ctx.interactive, + onStream: ctx.onStream, }); const tag = `[${step.name.toUpperCase()}:${result.ruleIndex + 1}]`; ctx.onPhaseComplete?.(step, 3, 'judge', tag, 'done');