Function bodies 601 total
injectDependencies method · typescript · L48-L51 (4 LOC)server/src/agents/governance/QASpecialist.ts
injectDependencies(debateManager: DebateManager, geminiAdapter: GeminiAdapter): void {
this.debateManager = debateManager;
this.geminiAdapter = geminiAdapter;
}handleMessage method · typescript · L56-L64 (9 LOC)server/src/agents/governance/QASpecialist.ts
protected async handleMessage(message: AgentMessage): Promise<void> {
switch (message.type) {
case 'GOVERNANCE_REVIEW_REQUEST':
await this.handleReviewRequest(message);
break;
default:
await super.handleMessage(message);
}
}handleReviewRequest method · typescript · L69-L108 (40 LOC)server/src/agents/governance/QASpecialist.ts
private async handleReviewRequest(message: AgentMessage): Promise<void> {
const payload = message.payload as {
debateId: string;
debate: DebateRecord;
};
this.status = 'processing';
const startTime = Date.now();
try {
const review = await this.performQAReview(payload.debate);
// 토론 매니저에 검토 결과 추가
if (this.debateManager) {
await this.debateManager.addGovernanceReview(payload.debateId, review);
}
// 결과 전송
const sender = this.eventBus.createSender(this.id);
sender.reply(message, 'GOVERNANCE_REVIEW_RESULT', {
debateId: payload.debateId,
review,
reviewType: 'qa',
});
this.processedTasks++;
this.successfulTasks++;
this.totalProcessingTime += Date.now() - startTime;
// 심각한 이슈 발견 시 인사이트 발행
if (!review.approved || review.issues?.some(i => i.severity === 'critical')) {
this.publishQAInsight(payload.debate, review);
}
} catch (errorperformQAReview method · typescript · L113-L160 (48 LOC)server/src/agents/governance/QASpecialist.ts
async performQAReview(debate: DebateRecord): Promise<Omit<GovernanceReview, 'id' | 'debateId'>> {
const issues: GovernanceIssue[] = [];
let score = 100;
// 1. 기본 구조 검증
const structureIssues = this.validateStructure(debate);
issues.push(...structureIssues);
score -= structureIssues.length * 10;
// 2. 논리적 일관성 검증
const logicIssues = this.validateLogic(debate);
issues.push(...logicIssues);
score -= logicIssues.length * 15;
// 3. 신뢰도 검증
const confidenceIssues = this.validateConfidence(debate);
issues.push(...confidenceIssues);
score -= confidenceIssues.length * 5;
// 4. 근거 검증
const evidenceIssues = this.validateEvidence(debate);
issues.push(...evidenceIssues);
score -= evidenceIssues.length * 10;
// 5. 실행 가능성 검증
const actionabilityIssues = this.validateActionability(debate);
issues.push(...actionabilityIssues);
score -= actionabilityIssues.length * 8;
// 점수 범위 조정
score = Math.max(0, Math.validateStructure method · typescript · L165-L196 (32 LOC)server/src/agents/governance/QASpecialist.ts
private validateStructure(debate: DebateRecord): GovernanceIssue[] {
const issues: GovernanceIssue[] = [];
if (!debate.thesis) {
issues.push({
type: 'quality',
severity: 'critical',
description: '정(Thesis) 라운드가 누락되었습니다.',
affectedRound: 'thesis',
});
}
if (!debate.antithesis) {
issues.push({
type: 'quality',
severity: 'critical',
description: '반(Antithesis) 라운드가 누락되었습니다.',
affectedRound: 'antithesis',
});
}
if (!debate.synthesis) {
issues.push({
type: 'quality',
severity: 'critical',
description: '합(Synthesis) 라운드가 누락되었습니다.',
affectedRound: 'synthesis',
});
}
return issues;
}validateLogic method · typescript · L201-L239 (39 LOC)server/src/agents/governance/QASpecialist.ts
private validateLogic(debate: DebateRecord): GovernanceIssue[] {
const issues: GovernanceIssue[] = [];
if (debate.thesis && debate.antithesis) {
// 반론이 정론을 실제로 반박하는지 확인
if (debate.antithesis.content.position === debate.thesis.content.position) {
issues.push({
type: 'logic',
severity: 'high',
description: '반론이 정론과 동일합니다. 실질적인 반박이 이루어지지 않았습니다.',
affectedRound: 'antithesis',
});
}
}
if (debate.synthesis) {
// 종합이 양측을 모두 고려했는지 확인
const synthesisText = debate.synthesis.content.reasoning.toLowerCase();
const mentionsOptimist =
synthesisText.includes('낙관') ||
synthesisText.includes('기회') ||
synthesisText.includes('긍정');
const mentionsPessimist =
synthesisText.includes('비관') ||
synthesisText.includes('리스크') ||
synthesisText.includes('위험');
if (!mentionsOptimist && !mentionsPessimist) {
issues.push({
type: validateConfidence method · typescript · L244-L268 (25 LOC)server/src/agents/governance/QASpecialist.ts
private validateConfidence(debate: DebateRecord): GovernanceIssue[] {
const issues: GovernanceIssue[] = [];
const rounds: {
name: string;
round?: DebateRound;
affectedRound: 'thesis' | 'antithesis' | 'synthesis';
}[] = [
{ name: '정(Thesis)', round: debate.thesis, affectedRound: 'thesis' },
{ name: '반(Antithesis)', round: debate.antithesis, affectedRound: 'antithesis' },
{ name: '합(Synthesis)', round: debate.synthesis, affectedRound: 'synthesis' },
];
for (const { name, round, affectedRound } of rounds) {
if (round && round.content.confidence < this.minConfidenceThreshold) {
issues.push({
type: 'quality',
severity: 'medium',
description: `${name} 라운드의 신뢰도(${round.content.confidence}%)가 기준치(${this.minConfidenceThreshold}%) 미만입니다.`,
affectedRound,
});
}
}
return issues;
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
validateEvidence method · typescript · L273-L297 (25 LOC)server/src/agents/governance/QASpecialist.ts
private validateEvidence(debate: DebateRecord): GovernanceIssue[] {
const issues: GovernanceIssue[] = [];
const rounds: {
name: string;
round?: DebateRound;
affectedRound: 'thesis' | 'antithesis' | 'synthesis';
}[] = [
{ name: '정(Thesis)', round: debate.thesis, affectedRound: 'thesis' },
{ name: '반(Antithesis)', round: debate.antithesis, affectedRound: 'antithesis' },
{ name: '합(Synthesis)', round: debate.synthesis, affectedRound: 'synthesis' },
];
for (const { name, round, affectedRound } of rounds) {
if (round && round.content.evidence.length < this.minEvidenceCount) {
issues.push({
type: 'data',
severity: 'low',
description: `${name} 라운드의 근거(${round.content.evidence.length}개)가 권장 수준(${this.minEvidenceCount}개) 미만입니다.`,
affectedRound,
});
}
}
return issues;
}validateActionability method · typescript · L302-L333 (32 LOC)server/src/agents/governance/QASpecialist.ts
private validateActionability(debate: DebateRecord): GovernanceIssue[] {
const issues: GovernanceIssue[] = [];
if (debate.synthesis) {
const actions = debate.synthesis.content.suggestedActions || [];
if (actions.length === 0) {
issues.push({
type: 'quality',
severity: 'medium',
description: '종합 결과에 구체적인 실행 항목이 없습니다.',
affectedRound: 'synthesis',
});
}
// 실행 항목이 너무 모호한지 확인
const vagueActions = actions.filter(
a => a.length < 10 || a.includes('등') || a.includes('기타') || a.includes('필요시')
);
if (vagueActions.length > actions.length / 2) {
issues.push({
type: 'quality',
severity: 'low',
description: '실행 항목 중 일부가 구체적이지 않습니다.',
affectedRound: 'synthesis',
});
}
}
return issues;
}generateRecommendations method · typescript · L338-L362 (25 LOC)server/src/agents/governance/QASpecialist.ts
private generateRecommendations(issues: GovernanceIssue[]): string[] {
const recommendations: string[] = [];
const issueTypes = new Set(issues.map(i => i.type));
if (issueTypes.has('quality')) {
recommendations.push('토론 각 단계의 완성도를 높이기 위해 추가 분석을 권고합니다.');
}
if (issueTypes.has('logic')) {
recommendations.push(
'논리적 일관성 향상을 위해 상대 관점을 명시적으로 반박/수용해야 합니다.'
);
}
if (issueTypes.has('data')) {
recommendations.push('근거 자료를 보강하여 주장의 신뢰성을 높이기 바랍니다.');
}
if (issues.some(i => i.severity === 'critical')) {
recommendations.push('심각한 품질 이슈가 발견되어 토론 재진행을 권고합니다.');
}
return recommendations;
}publishQAInsight method · typescript · L367-L393 (27 LOC)server/src/agents/governance/QASpecialist.ts
private publishQAInsight(
debate: DebateRecord,
review: Omit<GovernanceReview, 'id' | 'debateId'>
): void {
const level: InsightLevel = review.approved
? 'info'
: review.score >= 50
? 'warning'
: 'critical';
this.publishInsight(
debate.domain,
`[QA 검토] ${debate.topic}`,
`QA 검토 완료: ${review.approved ? '승인' : '보완 필요'} (점수: ${review.score}/100)`,
{
level,
confidence: review.score / 100,
data: {
debateId: debate.id,
issues: review.issues,
recommendations: review.recommendations,
},
actionable: !review.approved,
suggestedActions: review.recommendations,
}
);
}process method · typescript · L398-L406 (9 LOC)server/src/agents/governance/QASpecialist.ts
async process(task: Task): Promise<TaskResult> {
return {
taskId: task.id,
agentId: this.id,
success: true,
output: { message: 'QA review processed' },
processingTime: 0,
};
}getCapabilities method · typescript · L411-L419 (9 LOC)server/src/agents/governance/QASpecialist.ts
getCapabilities(): string[] {
return [
'quality_assurance',
'logic_validation',
'evidence_verification',
'actionability_review',
'governance_approval',
];
}applyCoaching method · typescript · L424-L432 (9 LOC)server/src/agents/governance/QASpecialist.ts
protected async applyCoaching(feedback: CoachingMessage['payload']['feedback']): Promise<void> {
console.log(`[QASpecialist] 코칭 적용: ${feedback.suggestion}`);
if (feedback.metric === 'accuracy' && feedback.score < feedback.benchmark) {
// 검증 기준 강화
this.minConfidenceThreshold = Math.min(70, this.minConfidenceThreshold + 5);
this.minEvidenceCount = Math.min(5, this.minEvidenceCount + 1);
}
}InventoryAgent class · typescript · L12-L297 (286 LOC)server/src/agents/inventory/InventoryAgent.ts
export class InventoryAgent extends Agent {
private safetyStockDays = 7; // Default safety stock coverage
private anomalyThreshold = 10; // 10% variance threshold for stocktake
private predictionConfidence = 0.85;
constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
super('inventory-agent', eventBus, stateManager, learningRegistry);
}
getCapabilities(): string[] {
return [
'재고 수준 모니터링',
'안전재고 계산',
'재고실사 이상 감지',
'수요 예측',
'발주 제안 생성',
];
}
async process(task: Task): Promise<TaskResult> {
const startTime = Date.now();
try {
switch (task.type) {
case 'analyze_safety_stock':
return await this.analyzeSafetyStock(task);
case 'detect_stocktake_anomalies':
return await this.detectStocktakeAnomalies(task);
case 'generate_order_suggestions':
return await this.generateOrderSuggestions(task);
case 'generate_insight':
Want this analysis on your repo? https://repobility.com/scan/
constructor method · typescript · L17-L19 (3 LOC)server/src/agents/inventory/InventoryAgent.ts
constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
super('inventory-agent', eventBus, stateManager, learningRegistry);
}getCapabilities method · typescript · L21-L29 (9 LOC)server/src/agents/inventory/InventoryAgent.ts
getCapabilities(): string[] {
return [
'재고 수준 모니터링',
'안전재고 계산',
'재고실사 이상 감지',
'수요 예측',
'발주 제안 생성',
];
}process method · typescript · L31-L56 (26 LOC)server/src/agents/inventory/InventoryAgent.ts
async process(task: Task): Promise<TaskResult> {
const startTime = Date.now();
try {
switch (task.type) {
case 'analyze_safety_stock':
return await this.analyzeSafetyStock(task);
case 'detect_stocktake_anomalies':
return await this.detectStocktakeAnomalies(task);
case 'generate_order_suggestions':
return await this.generateOrderSuggestions(task);
case 'generate_insight':
return await this.generateDomainInsight(task);
default:
throw new Error(`Unknown task type: ${task.type}`);
}
} catch (error) {
return {
taskId: task.id,
agentId: this.id,
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
processingTime: Date.now() - startTime,
};
}
}analyzeSafetyStock method · typescript · L61-L110 (50 LOC)server/src/agents/inventory/InventoryAgent.ts
private async analyzeSafetyStock(task: Task): Promise<TaskResult> {
const startTime = Date.now();
const state = this.stateManager.getInventoryState();
const items = state.inventoryItems;
const criticalItems = items.filter(item => item.status === 'critical');
const warningItems = items.filter(item => item.status === 'warning');
if (criticalItems.length > 0) {
this.publishInsight(
'inventory',
`긴급 재고 부족: ${criticalItems.length}개 품목`,
`${criticalItems
.map(i => i.materialName)
.slice(0, 3)
.join(', ')} 등의 재고가 안전재고 이하입니다.`,
{
highlight: `${criticalItems[0].daysRemaining}일 내 재고 소진 예상`,
level: 'critical',
confidence: 0.95,
data: criticalItems,
suggestedActions: ['긴급 발주 진행', '대체 자재 검토', '생산 일정 조정'],
}
);
} else if (warningItems.length > 0) {
this.publishInsight(
'inventory',
`재고 주의 품목: ${warningItems.length}개`detectStocktakeAnomalies method · typescript · L115-L192 (78 LOC)server/src/agents/inventory/InventoryAgent.ts
private async detectStocktakeAnomalies(task: Task): Promise<TaskResult> {
const startTime = Date.now();
const state = this.stateManager.getInventoryState();
const anomalies = state.anomalies;
if (anomalies.length === 0) {
return {
taskId: task.id,
agentId: this.id,
success: true,
output: { message: 'No anomalies to process' },
processingTime: Date.now() - startTime,
};
}
// Generate AI predictions for anomalies
const processedAnomalies: StocktakeAnomalyItem[] = [];
for (const anomaly of anomalies.slice(0, 5)) {
const inventory = state.inventoryItems.find(i => i.materialCode === anomaly.materialCode);
if (inventory) {
const prediction = await geminiAdapter.predictInventory({
materialName: anomaly.materialName,
currentStock: anomaly.systemQty,
avgDailyUsage: inventory.avgDailyUsage,
recentTrend:
inventory.trend === 'up'
generateOrderSuggestions method · typescript · L197-L235 (39 LOC)server/src/agents/inventory/InventoryAgent.ts
private async generateOrderSuggestions(task: Task): Promise<TaskResult> {
const startTime = Date.now();
const state = this.stateManager.getInventoryState();
const suggestions = state.orderSuggestions;
const urgentOrders = suggestions.filter(s => s.urgency === 'high');
if (urgentOrders.length > 0) {
const totalCost = urgentOrders.reduce((sum, s) => sum + s.estimatedCost, 0);
this.publishInsight(
'inventory',
`긴급 발주 필요: ${urgentOrders.length}건`,
`${urgentOrders
.map(o => o.materialName)
.slice(0, 3)
.join(', ')} 등의 발주가 필요합니다.`,
{
highlight: `예상 발주 금액: ${totalCost.toLocaleString()}원`,
level: 'warning',
confidence: 0.9,
data: urgentOrders,
actionable: true,
suggestedActions: ['발주서 생성', '공급업체 연락'],
}
);
}
return {
taskId: task.id,
agentId: this.id,
success: true,
output: {
totalSugenerateDomainInsight method · typescript · L240-L272 (33 LOC)server/src/agents/inventory/InventoryAgent.ts
private async generateDomainInsight(task: Task): Promise<TaskResult> {
const startTime = Date.now();
const state = this.stateManager.getInventoryState();
// Calculate overall inventory health
const items = state.inventoryItems;
const criticalRate = items.filter(i => i.status === 'critical').length / (items.length || 1);
const avgDaysRemaining =
items.reduce((sum, i) => sum + i.daysRemaining, 0) / (items.length || 1);
if (criticalRate > 0.1) {
this.publishInsight(
'inventory',
'재고 건전성 주의',
`전체 품목 중 ${Math.round(criticalRate * 100)}%가 위험 수준입니다.`,
{
highlight: `평균 잔여일: ${Math.round(avgDaysRemaining)}일`,
level: 'warning',
confidence: 0.85,
data: { criticalRate, avgDaysRemaining },
suggestedActions: ['전체 발주 계획 재검토'],
}
);
}
return {
taskId: task.id,
agentId: this.id,
success: true,
output: { generated: true },
procapplyCoaching method · typescript · L277-L296 (20 LOC)server/src/agents/inventory/InventoryAgent.ts
protected async applyCoaching(feedback: CoachingMessage['payload']['feedback']): Promise<void> {
console.log(`InventoryAgent applying coaching for ${feedback.metric}`);
if (feedback.metric === 'accuracy') {
// Adjust prediction confidence
this.predictionConfidence = Math.max(this.predictionConfidence * 0.95, 0.6);
console.log(`Adjusted prediction confidence to ${this.predictionConfidence}`);
}
if (feedback.metric === 'user_acceptance') {
// Adjust anomaly threshold
this.anomalyThreshold = Math.min(this.anomalyThreshold + 2, 25);
console.log(`Adjusted anomaly threshold to ${this.anomalyThreshold}%`);
}
this.learningRegistry.recordCoaching(this.id, 'general', [
`predictionConfidence: ${this.predictionConfidence}`,
`anomalyThreshold: ${this.anomalyThreshold}`,
]);
}Repobility — the code-quality scanner for AI-generated software · https://repobility.com
createInventoryTeam function · typescript · L31-L85 (55 LOC)server/src/agents/inventory-team/index.ts
export function createInventoryTeam(
eventBus: EventBus,
stateManager: StateManager,
learningRegistry: LearningRegistry
): InventoryTeam {
const optimist = new OptimistPersona(
'inventory-optimist',
'inventory-team',
'inventory',
eventBus,
stateManager,
learningRegistry
);
const pessimist = new PessimistPersona(
'inventory-pessimist',
'inventory-team',
'inventory',
eventBus,
stateManager,
learningRegistry
);
const mediator = new MediatorPersona(
'inventory-mediator',
'inventory-team',
'inventory',
eventBus,
stateManager,
learningRegistry
);
return {
optimist,
pessimist,
mediator,
start: () => {
optimist.start();
pessimist.start();
mediator.start();
console.log('[InventoryTeam] 팀 시작됨');
},
stop: () => {
optimist.stop();
pessimist.stop();
mediator.stop();
console.log('[InventoryTeam] 팀 중지됨');
},
injectDependencies: constructor method · typescript · L69-L71 (3 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
super('chief-orchestrator', eventBus, stateManager, learningRegistry);
}registerDomainTeams method · typescript · L76-L79 (4 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
registerDomainTeams(teams: DomainTeams): void {
this.domainTeams = { ...this.domainTeams, ...teams };
console.log('[ChiefOrchestrator] 도메인 팀 등록됨:', Object.keys(teams).join(', '));
}registerGovernanceAgents method · typescript · L84-L87 (4 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
registerGovernanceAgents(agents: GovernanceAgents): void {
this.governanceAgents = { ...this.governanceAgents, ...agents };
console.log('[ChiefOrchestrator] 거버넌스 에이전트 등록됨');
}registerDebateManager method · typescript · L92-L95 (4 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
registerDebateManager(debateManager: DebateManager): void {
this.debateManager = debateManager;
console.log('[ChiefOrchestrator] 토론 매니저 등록됨');
}registerLegacyAgents method · typescript · L100-L103 (4 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
registerLegacyAgents(agents: Agent[]): void {
this.legacyAgents = agents;
console.log('[ChiefOrchestrator] 레거시 에이전트 등록됨:', agents.length);
}getCapabilities method · typescript · L108-L117 (10 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
getCapabilities(): string[] {
return [
'도메인 토론 오케스트레이션',
'크로스도메인 인사이트 종합',
'거버넌스 에스컬레이션',
'에이전트 코칭',
'우선순위 관리',
'변증법적 토론 조율',
];
}start method · typescript · L122-L137 (16 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
start(): void {
super.start();
// 토론 관련 메시지 구독
this.eventBus.subscribeType('DEBATE_SYNTHESIS', this.handleDebateSynthesis.bind(this));
this.eventBus.subscribeType('GOVERNANCE_REVIEW_RESULT', this.handleGovernanceResult.bind(this));
this.eventBus.subscribeType('INSIGHT_SHARE', this.handleInsightShare.bind(this));
this.eventBus.subscribeType('TASK_RESULT', this.handleTaskResult.bind(this));
// 주기적 코칭 평가
this.coachingInterval = setInterval(() => {
this.evaluateAndCoach();
}, 60000);
console.log('[ChiefOrchestrator] 시작됨');
}Repobility — same analyzer, your code, free for public repos · /scan/
stop method · typescript · L142-L148 (7 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
stop(): void {
if (this.coachingInterval) {
clearInterval(this.coachingInterval);
}
super.stop();
console.log('[ChiefOrchestrator] 중지됨');
}process method · typescript · L153-L193 (41 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
async process(task: Task): Promise<TaskResult> {
const startTime = Date.now();
try {
switch (task.type) {
case 'orchestrate_debate':
await this.orchestrateDebate(
task.input as {
team: DomainTeam;
topic: string;
contextData: unknown;
priority?: MessagePriority;
}
);
return this.successResult(task, startTime, { initiated: true });
case 'orchestrate_all_teams':
await this.orchestrateAllTeams(
task.input as {
priority?: MessagePriority;
}
);
return this.successResult(task, startTime, { initiated: true });
case 'synthesize_insights':
const summary = await this.synthesizeAllInsights();
return this.successResult(task, startTime, { summary });
default:
throw new Error(`알 수 없는 태스크 타입: ${task.type}`);
}
} catch (error) {
resuccessResult method · typescript · L195-L203 (9 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private successResult(task: Task, startTime: number, output: unknown): TaskResult {
return {
taskId: task.id,
agentId: this.id,
success: true,
output,
processingTime: Date.now() - startTime,
};
}orchestrateDebate method · typescript · L208-L257 (50 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
async orchestrateDebate(input: {
team: DomainTeam;
topic: string;
contextData: unknown;
priority?: MessagePriority;
}): Promise<string> {
if (!this.debateManager) {
throw new Error('DebateManager가 등록되지 않았습니다.');
}
const { team, topic, contextData, priority = 'medium' } = input;
// 토론 시작
const debateId = await this.debateManager.initiateDebate({
team,
topic,
contextData,
priority,
immediate: true,
});
if (debateId === 'queued') {
console.log(`[ChiefOrchestrator] 토론 대기열에 추가됨: ${topic}`);
return 'queued';
}
// 진행 중인 토론 추적
this.pendingDebates.set(debateId, {
contextData,
priority,
});
// 팀의 Optimist에게 토론 시작 메시지 전송
const optimistId = this.getTeamOptimistId(team);
const sender = this.eventBus.createSender(this.id);
sender.send(
optimistId,
'DEBATE_START',
{
debateId,
topic,
contextData,
},
priorgetTeamOptimistId method · typescript · L262-L271 (10 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private getTeamOptimistId(team: DomainTeam): AgentId {
const mapping: Record<DomainTeam, AgentId> = {
'bom-waste-team': 'bom-waste-optimist',
'inventory-team': 'inventory-optimist',
'profitability-team': 'profitability-optimist',
'cost-management-team': 'cost-optimist',
'business-strategy-team': 'business-optimist',
};
return mapping[team];
}orchestrateAllTeams method · typescript · L276-L312 (37 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
async orchestrateAllTeams(input?: { priority?: MessagePriority }): Promise<void> {
const priority = input?.priority || 'medium';
const state = this.stateManager;
const teams: { team: DomainTeam; topic: string; contextData: unknown }[] = [
{
team: 'bom-waste-team',
topic: 'BOM 차이 및 폐기물 분석',
contextData: state.getBomWasteState(),
},
{
team: 'inventory-team',
topic: '재고 수준 및 안전재고 분석',
contextData: state.getInventoryState(),
},
{
team: 'profitability-team',
topic: '채널별 수익성 분석',
contextData: state.getProfitabilityState(),
},
{
team: 'cost-management-team',
topic: '원가 구조 분석',
contextData: {}, // 원가 데이터는 별도 조회 필요
},
];
for (const { team, topic, contextData } of teams) {
try {
await this.orchestrateDebate({ team, topic, contextData, priority });
} catch (error) {
console.error(`[ChiefOrchestrator] ${thandleDebateSynthesis method · typescript · L317-L349 (33 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
protected async handleDebateSynthesis(message: AgentMessage): Promise<void> {
const payload = message.payload as {
debateId: string;
thesis: DebateRound;
antithesis: DebateRound;
synthesis: DebateRound;
contextData: unknown;
};
const pendingDebate = this.pendingDebates.get(payload.debateId);
if (!pendingDebate) {
console.warn(`[ChiefOrchestrator] 알 수 없는 토론 ID: ${payload.debateId}`);
return;
}
// 토론 정보 업데이트
pendingDebate.thesis = payload.thesis;
pendingDebate.antithesis = payload.antithesis;
pendingDebate.synthesis = payload.synthesis;
// 거버넌스 검토 요청 (높은 우선순위나 낮은 신뢰도의 경우)
const needsGovernance =
pendingDebate.priority === 'critical' ||
pendingDebate.priority === 'high' ||
payload.synthesis.content.confidence < 70;
if (needsGovernance && this.debateManager) {
await this.requestGovernanceReview(payload.debateId);
} else {
// 바로 토론 완료 처리
await this.completerequestGovernanceReview method · typescript · L354-L389 (36 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private async requestGovernanceReview(debateId: string): Promise<void> {
if (!this.debateManager) return;
const debate = this.debateManager.getActiveDebate(debateId);
if (!debate) return;
const sender = this.eventBus.createSender(this.id);
// QA Specialist 검토 요청
if (this.governanceAgents.qaSpecialist) {
sender.send(
'qa-specialist',
'GOVERNANCE_REVIEW_REQUEST',
{
debateId,
debate,
},
'high'
);
}
// Compliance Auditor 검토 요청
if (this.governanceAgents.complianceAuditor) {
sender.send(
'compliance-auditor',
'GOVERNANCE_REVIEW_REQUEST',
{
debateId,
debate,
},
'high'
);
}
console.log(`[ChiefOrchestrator] 거버넌스 검토 요청: ${debateId}`);
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
handleGovernanceResult method · typescript · L394-L413 (20 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
protected async handleGovernanceResult(message: AgentMessage): Promise<void> {
const payload = message.payload as {
debateId: string;
review: unknown;
reviewType: 'qa' | 'compliance';
};
const debate = this.debateManager?.getActiveDebate(payload.debateId);
if (!debate) return;
// 모든 거버넌스 검토가 완료되었는지 확인
const reviews = debate.governanceReviews || [];
const hasQA = reviews.some(r => r.reviewerId === 'qa-specialist');
const hasCompliance = reviews.some(r => r.reviewerId === 'compliance-auditor');
// 두 검토가 모두 완료되면 토론 완료
if (hasQA && hasCompliance) {
await this.completeDebate(payload.debateId);
}
}completeDebate method · typescript · L418-L437 (20 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private async completeDebate(debateId: string): Promise<void> {
const pendingDebate = this.pendingDebates.get(debateId);
if (!pendingDebate || !pendingDebate.synthesis) return;
if (!this.debateManager) return;
// 최종 결정 생성
const finalDecision = this.createFinalDecision(pendingDebate);
// 토론 완료
const completedDebate = await this.debateManager.completeDebate(debateId, finalDecision);
// 인사이트 발행
this.publishDebateInsight(completedDebate);
// 추적에서 제거
this.pendingDebates.delete(debateId);
console.log(`[ChiefOrchestrator] 토론 완료: ${debateId}`);
}createFinalDecision method · typescript · L442-L455 (14 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private createFinalDecision(pendingDebate: {
synthesis?: DebateRound;
priority: MessagePriority;
}): FinalDecision {
const synthesis = pendingDebate.synthesis!;
return {
recommendation: synthesis.content.position,
reasoning: synthesis.content.reasoning,
confidence: synthesis.content.confidence,
actions: synthesis.content.suggestedActions || [],
priority: pendingDebate.priority,
};
}publishDebateInsight method · typescript · L460-L493 (34 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private publishDebateInsight(debate: DebateRecord): void {
if (!debate.finalDecision) return;
const level =
debate.finalDecision.confidence >= 80
? 'info'
: debate.finalDecision.confidence >= 60
? 'warning'
: 'critical';
this.publishInsight(
debate.domain,
`[토론 완료] ${debate.topic}`,
debate.finalDecision.recommendation,
{
highlight: `신뢰도 ${debate.finalDecision.confidence}%`,
level,
confidence: debate.finalDecision.confidence / 100,
data: {
debateId: debate.id,
team: debate.team,
thesisPosition: debate.thesis?.content.position,
antithesisPosition: debate.antithesis?.content.position,
governanceReviews: debate.governanceReviews?.map(r => ({
reviewer: r.reviewerId,
approved: r.approved,
score: r.score,
})),
},
actionable: true,
suggestedActions: debate.finalDehandleInsightShare method · typescript · L498-L509 (12 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
protected async handleInsightShare(message: AgentMessage): Promise<void> {
if (message.source === this.id) return;
const insight = message.payload as AgentInsight;
this.insightBuffer.set(insight.id, insight);
// 버퍼 크기 제한
if (this.insightBuffer.size > 50) {
const oldestKey = this.insightBuffer.keys().next().value;
if (oldestKey) this.insightBuffer.delete(oldestKey);
}
}handleTaskResult method · typescript · L514-L519 (6 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
protected async handleTaskResult(message: AgentMessage): Promise<void> {
// 레거시 에이전트의 결과 처리
if (this.legacyAgents.some(a => a.getStatus().id === message.source)) {
console.log(`[ChiefOrchestrator] 레거시 에이전트 결과 수신: ${message.source}`);
}
}synthesizeAllInsights method · typescript · L524-L568 (45 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
async synthesizeAllInsights(): Promise<string> {
const recentInsights = Array.from(this.insightBuffer.values()).filter(
i => Date.now() - i.timestamp.getTime() < 300000
); // 최근 5분
const byDomain: Record<string, AgentInsight[]> = {};
for (const insight of recentInsights) {
if (!byDomain[insight.domain]) {
byDomain[insight.domain] = [];
}
byDomain[insight.domain].push(insight);
}
// Gemini로 종합 생성
const summary = await geminiAdapter.generateCoordinatorSummary({
bomWaste:
byDomain['bom']?.map(i => i.description).join('; ') ||
byDomain['waste']?.map(i => i.description).join('; '),
inventory: byDomain['inventory']?.map(i => i.description).join('; '),
profitability: byDomain['profitability']?.map(i => i.description).join('; '),
});
// 종합 인사이트 발행
const criticalCount = recentInsights.filter(i => i.level === 'critical').length;
const warningCount = recentInsights.filter(i => i.leveevaluateAndCoach method · typescript · L573-L588 (16 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
private async evaluateAndCoach(): Promise<void> {
const performances = this.learningRegistry.getAllPerformances();
for (const perf of performances) {
if (this.learningRegistry.needsCoaching(perf.agentId)) {
const feedback = this.learningRegistry.generateCoachingFeedback(perf.agentId);
if (feedback) {
const sender = this.eventBus.createSender(this.id);
sender.send(perf.agentId, 'COACHING_FEEDBACK', { feedback }, 'medium');
console.log(`[ChiefOrchestrator] 코칭 전송: ${perf.agentId}`);
}
}
}
}Want this analysis on your repo? https://repobility.com/scan/
applyCoaching method · typescript · L593-L595 (3 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
protected async applyCoaching(): Promise<void> {
console.log('[ChiefOrchestrator] 코칭 미적용 (최고 조율자)');
}getDebateStatus method · typescript · L600-L604 (5 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
getDebateStatus(): {
active: number;
pending: number;
completed: number;
} {getAllTeamStatuses method · typescript · L618-L640 (23 LOC)server/src/agents/orchestrator/ChiefOrchestrator.ts
getAllTeamStatuses(): Record<string, unknown>[] {
const statuses: Record<string, unknown>[] = [];
const teams = [
{ name: 'bom-waste-team', team: this.domainTeams.bomWaste },
{ name: 'inventory-team', team: this.domainTeams.inventory },
{ name: 'profitability-team', team: this.domainTeams.profitability },
{ name: 'cost-team', team: this.domainTeams.cost },
];
for (const { name, team } of teams) {
if (team) {
statuses.push({
team: name,
optimist: team.optimist.getStatus(),
pessimist: team.pessimist.getStatus(),
mediator: team.mediator.getStatus(),
});
}
}
return statuses;
}