5つの関心を Persona, Policy, Instruction, Knowledge, Output Contract に統一。 ディレクトリ、YAMLキー、ソースコード、テンプレート、テスト、ドキュメントを全面更新。
100 lines
3.2 KiB
TypeScript
100 lines
3.2 KiB
TypeScript
/**
|
|
* Phase 2 instruction builder (report output)
|
|
*
|
|
* Builds the instruction for the report output phase.
|
|
* Assembles template variables and renders a single complete template.
|
|
*/
|
|
|
|
import type { PieceMovement, Language } from '../../models/types.js';
|
|
import type { InstructionContext } from './instruction-context.js';
|
|
import { replaceTemplatePlaceholders } from './escape.js';
|
|
import { isReportObjectConfig, renderReportContext, renderReportOutputInstruction } from './InstructionBuilder.js';
|
|
import { loadTemplate } from '../../../shared/prompts/index.js';
|
|
|
|
/**
|
|
* Context for building report phase instruction.
|
|
*/
|
|
export interface ReportInstructionContext {
|
|
/** Working directory */
|
|
cwd: string;
|
|
/** Report directory path */
|
|
reportDir: string;
|
|
/** Movement iteration (for {movement_iteration} replacement) */
|
|
movementIteration: number;
|
|
/** Language */
|
|
language?: Language;
|
|
/** Target report file name (when generating a single report) */
|
|
targetFile?: string;
|
|
}
|
|
|
|
/**
|
|
* Builds Phase 2 (report output) instructions.
|
|
*
|
|
* Renders a single complete template with all variables.
|
|
*/
|
|
export class ReportInstructionBuilder {
|
|
constructor(
|
|
private readonly step: PieceMovement,
|
|
private readonly context: ReportInstructionContext,
|
|
) {}
|
|
|
|
build(): string {
|
|
if (!this.step.report) {
|
|
throw new Error(`ReportInstructionBuilder called for movement "${this.step.name}" which has no report config`);
|
|
}
|
|
|
|
const language = this.context.language ?? 'en';
|
|
|
|
// Build report context for Piece Context section
|
|
let reportContext: string;
|
|
if (this.context.targetFile) {
|
|
reportContext = `- Report Directory: ${this.context.reportDir}/\n- Report File: ${this.context.reportDir}/${this.context.targetFile}`;
|
|
} else {
|
|
reportContext = renderReportContext(this.step.report, this.context.reportDir);
|
|
}
|
|
|
|
// Build report output instruction
|
|
let reportOutput = '';
|
|
let hasReportOutput = false;
|
|
const instrContext: InstructionContext = {
|
|
task: '',
|
|
iteration: 0,
|
|
maxIterations: 0,
|
|
movementIteration: this.context.movementIteration,
|
|
cwd: this.context.cwd,
|
|
projectCwd: this.context.cwd,
|
|
userInputs: [],
|
|
reportDir: this.context.reportDir,
|
|
language,
|
|
};
|
|
|
|
if (isReportObjectConfig(this.step.report) && this.step.report.order) {
|
|
reportOutput = replaceTemplatePlaceholders(this.step.report.order.trimEnd(), this.step, instrContext);
|
|
hasReportOutput = true;
|
|
} else if (!this.context.targetFile) {
|
|
const output = renderReportOutputInstruction(this.step, instrContext, language);
|
|
if (output) {
|
|
reportOutput = output;
|
|
hasReportOutput = true;
|
|
}
|
|
}
|
|
|
|
// Build output contract
|
|
let outputContract = '';
|
|
let hasOutputContract = false;
|
|
if (isReportObjectConfig(this.step.report) && this.step.report.format) {
|
|
outputContract = replaceTemplatePlaceholders(this.step.report.format.trimEnd(), this.step, instrContext);
|
|
hasOutputContract = true;
|
|
}
|
|
|
|
return loadTemplate('perform_phase2_message', language, {
|
|
workingDirectory: this.context.cwd,
|
|
reportContext,
|
|
hasReportOutput,
|
|
reportOutput,
|
|
hasOutputContract,
|
|
outputContract,
|
|
});
|
|
}
|
|
}
|