← back to kkokio88-creator__Z-CMS

Function bodies 601 total

All specs Real LLM only Function bodies
BomWasteAgent class · typescript · L9-L255 (247 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
export class BomWasteAgent extends Agent {
  private anomalyThreshold = 5; // Default 5% variance threshold
  private confidenceMultiplier = 1.0;

  constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
    super('bom-waste-agent', eventBus, stateManager, learningRegistry);
  }

  getCapabilities(): string[] {
    return ['BOM 차이 분석', '폐기물 원인 추론', '표준량 업데이트 제안', '이상 패턴 감지'];
  }

  async process(task: Task): Promise<TaskResult> {
    const startTime = Date.now();

    try {
      switch (task.type) {
        case 'analyze_bom_variance':
          return await this.analyzeBomVariance(task);
        case 'analyze_waste_trend':
          return await this.analyzeWasteTrend(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,
     
constructor method · typescript · L13-L15 (3 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
    super('bom-waste-agent', eventBus, stateManager, learningRegistry);
  }
getCapabilities method · typescript · L17-L19 (3 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  getCapabilities(): string[] {
    return ['BOM 차이 분석', '폐기물 원인 추론', '표준량 업데이트 제안', '이상 패턴 감지'];
  }
process method · typescript · L21-L44 (24 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  async process(task: Task): Promise<TaskResult> {
    const startTime = Date.now();

    try {
      switch (task.type) {
        case 'analyze_bom_variance':
          return await this.analyzeBomVariance(task);
        case 'analyze_waste_trend':
          return await this.analyzeWasteTrend(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,
      };
    }
  }
analyzeBomVariance method · typescript · L49-L122 (74 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  private async analyzeBomVariance(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const state = this.stateManager.getBomWasteState();
    const bomItems = state.bomItems;

    if (bomItems.length === 0) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'No BOM items to analyze' },
        processingTime: Date.now() - startTime,
      };
    }

    // Find items with significant variance
    const anomalies = bomItems.filter(item => Math.abs(item.diffPercent) >= this.anomalyThreshold);

    // Generate AI reasoning for each anomaly
    const analyzedItems: BomDiffItem[] = [];

    for (const item of anomalies.slice(0, 5)) {
      // Limit to top 5
      const reasoning = await geminiAdapter.analyzeAnomaly({
        itemName: item.skuName,
        expected: item.stdQty,
        actual: item.actualQty,
        diffPercent: item.diffPercent,
      });

      // Update item with reasoning
      con
analyzeWasteTrend method · typescript · L127-L180 (54 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  private async analyzeWasteTrend(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const state = this.stateManager.getBomWasteState();
    const wasteTrend = state.wasteTrend;

    if (wasteTrend.length < 3) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'Insufficient data for trend analysis' },
        processingTime: Date.now() - startTime,
      };
    }

    // Calculate trend direction
    const recentAvg = wasteTrend.slice(-7).reduce((sum, d) => sum + d.wastePercent, 0) / 7;
    const previousAvg = wasteTrend.slice(-14, -7).reduce((sum, d) => sum + d.wastePercent, 0) / 7;
    const trend =
      recentAvg > previousAvg ? 'increasing' : recentAvg < previousAvg ? 'decreasing' : 'stable';

    // Check if exceeding target
    const latestWaste = wasteTrend[wasteTrend.length - 1];
    const isExceedingTarget = latestWaste.wastePercent > latestWaste.targetPercent;

    if (isExceedingTarget 
generateDomainInsight method · typescript · L185-L217 (33 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  private async generateDomainInsight(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const state = this.stateManager.getBomWasteState();

    // Find most impactful issue
    const highImpactItems = state.bomItems
      .filter(item => item.costImpact > 0)
      .sort((a, b) => b.costImpact - a.costImpact);

    if (highImpactItems.length > 0) {
      const top = highImpactItems[0];
      this.publishInsight(
        'bom',
        '비용 영향 분석',
        `${top.skuName}의 BOM 차이로 인한 추가 비용이 가장 높습니다.`,
        {
          highlight: `예상 추가 비용: ${top.costImpact.toLocaleString()}원`,
          level: top.costImpact > 100000 ? 'critical' : 'warning',
          confidence: 0.85,
          data: { topItems: highImpactItems.slice(0, 3) },
          suggestedActions: ['BOM 표준량 재검토', '공정 최적화'],
        }
      );
    }

    return {
      taskId: task.id,
      agentId: this.id,
      success: true,
      output: { generated: true },
      processingTime: Date.now() - startT
Repobility · open methodology · https://repobility.com/research/
calculateAnomalyScore method · typescript · L222-L229 (8 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  private calculateAnomalyScore(item: BomDiffItem): number {
    const varianceScore = Math.min(Math.abs(item.diffPercent) * 5, 50);
    const costScore = Math.min(item.costImpact / 10000, 30);
    const baseScore = varianceScore + costScore;

    // Add penalty for repeated issues (would need history tracking)
    return Math.min(Math.round(baseScore + 20), 100);
  }
applyCoaching method · typescript · L234-L254 (21 LOC)
server/src/agents/bom-waste/BomWasteAgent.ts
  protected async applyCoaching(feedback: CoachingMessage['payload']['feedback']): Promise<void> {
    console.log(`BomWasteAgent applying coaching for ${feedback.metric}`);

    if (feedback.metric === 'accuracy') {
      // Increase threshold to be more selective
      this.anomalyThreshold = Math.min(this.anomalyThreshold + 1, 15);
      console.log(`Adjusted anomaly threshold to ${this.anomalyThreshold}%`);
    }

    if (feedback.metric === 'user_acceptance') {
      // Reduce confidence multiplier if insights are being dismissed
      this.confidenceMultiplier = Math.max(this.confidenceMultiplier * 0.95, 0.5);
      console.log(`Adjusted confidence multiplier to ${this.confidenceMultiplier}`);
    }

    // Record coaching application
    this.learningRegistry.recordCoaching(this.id, 'general', [
      `threshold: ${this.anomalyThreshold}`,
      `confidence: ${this.confidenceMultiplier}`,
    ]);
  }
createBomWasteTeam function · typescript · L31-L85 (55 LOC)
server/src/agents/bom-waste-team/index.ts
export function createBomWasteTeam(
  eventBus: EventBus,
  stateManager: StateManager,
  learningRegistry: LearningRegistry
): BomWasteTeam {
  const optimist = new OptimistPersona(
    'bom-waste-optimist',
    'bom-waste-team',
    'bom',
    eventBus,
    stateManager,
    learningRegistry
  );

  const pessimist = new PessimistPersona(
    'bom-waste-pessimist',
    'bom-waste-team',
    'bom',
    eventBus,
    stateManager,
    learningRegistry
  );

  const mediator = new MediatorPersona(
    'bom-waste-mediator',
    'bom-waste-team',
    'bom',
    eventBus,
    stateManager,
    learningRegistry
  );

  return {
    optimist,
    pessimist,
    mediator,
    start: () => {
      optimist.start();
      pessimist.start();
      mediator.start();
      console.log('[BomWasteTeam] 팀 시작됨');
    },
    stop: () => {
      optimist.stop();
      pessimist.stop();
      mediator.stop();
      console.log('[BomWasteTeam] 팀 중지됨');
    },
    injectDependencies: (debateManager: Debate
createBusinessTeam function · typescript · L31-L85 (55 LOC)
server/src/agents/business-team/index.ts
export function createBusinessTeam(
  eventBus: EventBus,
  stateManager: StateManager,
  learningRegistry: LearningRegistry
): BusinessTeam {
  const optimist = new OptimistPersona(
    'business-optimist',
    'business-strategy-team',
    'general', // business 도메인은 서버에서 general로 매핑
    eventBus,
    stateManager,
    learningRegistry
  );

  const pessimist = new PessimistPersona(
    'business-pessimist',
    'business-strategy-team',
    'general',
    eventBus,
    stateManager,
    learningRegistry
  );

  const mediator = new MediatorPersona(
    'business-mediator',
    'business-strategy-team',
    'general',
    eventBus,
    stateManager,
    learningRegistry
  );

  return {
    optimist,
    pessimist,
    mediator,
    start: () => {
      optimist.start();
      pessimist.start();
      mediator.start();
      console.log('[BusinessTeam] 팀 시작됨');
    },
    stop: () => {
      optimist.stop();
      pessimist.stop();
      mediator.stop();
      console.log('[BusinessT
CoordinatorAgent class · typescript · L16-L368 (353 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
export class CoordinatorAgent extends Agent {
  private subordinates: Agent[];
  private pendingResults: Map<string, TaskResult[]> = new Map();
  private coachingInterval: NodeJS.Timeout | null = null;
  private insightBuffer: Map<string, AgentInsight> = new Map();

  constructor(
    eventBus: EventBus,
    stateManager: StateManager,
    learningRegistry: LearningRegistry,
    subordinates: Agent[]
  ) {
    super('coordinator', eventBus, stateManager, learningRegistry);
    this.subordinates = subordinates;
  }

  getCapabilities(): string[] {
    return [
      '태스크 오케스트레이션',
      '에이전트 코칭',
      '크로스도메인 인사이트 통합',
      '우선순위 관리',
      '성과 모니터링',
    ];
  }

  /**
   * Start coordinator with coaching loop
   */
  start(): void {
    super.start();

    // Subscribe to insight shares from subordinates
    this.eventBus.subscribeType('INSIGHT_SHARE', this.handleInsightShare.bind(this));
    this.eventBus.subscribeType('TASK_RESULT', this.handleTaskResult.bind(this));

    // Start
constructor method · typescript · L22-L30 (9 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  constructor(
    eventBus: EventBus,
    stateManager: StateManager,
    learningRegistry: LearningRegistry,
    subordinates: Agent[]
  ) {
    super('coordinator', eventBus, stateManager, learningRegistry);
    this.subordinates = subordinates;
  }
getCapabilities method · typescript · L32-L40 (9 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  getCapabilities(): string[] {
    return [
      '태스크 오케스트레이션',
      '에이전트 코칭',
      '크로스도메인 인사이트 통합',
      '우선순위 관리',
      '성과 모니터링',
    ];
  }
start method · typescript · L45-L58 (14 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  start(): void {
    super.start();

    // Subscribe to insight shares from subordinates
    this.eventBus.subscribeType('INSIGHT_SHARE', this.handleInsightShare.bind(this));
    this.eventBus.subscribeType('TASK_RESULT', this.handleTaskResult.bind(this));

    // Start periodic coaching check
    this.coachingInterval = setInterval(() => {
      this.evaluateAndCoach();
    }, 60000); // Check every minute

    console.log('Coordinator started with coaching loop');
  }
Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
stop method · typescript · L63-L68 (6 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  stop(): void {
    if (this.coachingInterval) {
      clearInterval(this.coachingInterval);
    }
    super.stop();
  }
process method · typescript · L70-L100 (31 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  async process(task: Task): Promise<TaskResult> {
    const startTime = Date.now();

    try {
      switch (task.type) {
        case 'orchestrate_analysis':
          await this.orchestrateAnalysis(task);
          return {
            taskId: task.id,
            agentId: this.id,
            success: true,
            output: { orchestrated: true },
            processingTime: Date.now() - startTime,
          };
        case 'synthesize_insights':
          return await this.synthesizeInsights(task);
        case 'evaluate_agents':
          return await this.evaluateAgents(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,
      };
    }
  }
orchestrateAnalysis method · typescript · L105-L184 (80 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  async orchestrateAnalysis(input?: {
    priority?: 'low' | 'medium' | 'high' | 'critical';
  }): Promise<void> {
    const correlationId = uuidv4();
    const sender = this.eventBus.createSender(this.id);

    // Create tasks for each domain agent
    const tasks: { agentId: AgentId; task: Task }[] = [
      {
        agentId: 'bom-waste-agent',
        task: {
          id: uuidv4(),
          type: 'analyze_bom_variance',
          domain: 'bom',
          input: {},
          priority: input?.priority || 'medium',
        },
      },
      {
        agentId: 'bom-waste-agent',
        task: {
          id: uuidv4(),
          type: 'analyze_waste_trend',
          domain: 'waste',
          input: {},
          priority: input?.priority || 'medium',
        },
      },
      {
        agentId: 'inventory-agent',
        task: {
          id: uuidv4(),
          type: 'analyze_safety_stock',
          domain: 'inventory',
          input: {},
          priority: input?.priority || 
handleTaskResult method · typescript · L189-L205 (17 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  protected async handleTaskResult(message: AgentMessage): Promise<void> {
    if (message.source === this.id) return; // Ignore own results

    const result = message.payload as TaskResult;
    const correlationId = message.correlationId;

    if (correlationId && this.pendingResults.has(correlationId)) {
      const results = this.pendingResults.get(correlationId)!;
      results.push(result);

      // Check if all results are in (we expect 6 tasks)
      if (results.length >= 6) {
        await this.synthesizeFromResults(correlationId, results);
        this.pendingResults.delete(correlationId);
      }
    }
  }
handleInsightShare method · typescript · L210-L221 (12 LOC)
server/src/agents/coordinator/CoordinatorAgent.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);

    // Keep buffer limited
    if (this.insightBuffer.size > 50) {
      const oldestKey = this.insightBuffer.keys().next().value;
      if (oldestKey) this.insightBuffer.delete(oldestKey);
    }
  }
synthesizeFromResults method · typescript · L226-L275 (50 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  private async synthesizeFromResults(correlationId: string, results: TaskResult[]): Promise<void> {
    const successfulResults = results.filter(r => r.success);

    // Get recent insights from buffer
    const recentInsights = Array.from(this.insightBuffer.values()).filter(
      i => Date.now() - i.timestamp.getTime() < 60000
    ); // Last minute

    if (recentInsights.length === 0 && successfulResults.length === 0) {
      return;
    }

    // Categorize insights
    const bomInsights = recentInsights.filter(i => i.domain === 'bom' || i.domain === 'waste');
    const inventoryInsights = recentInsights.filter(i => i.domain === 'inventory');
    const profitInsights = recentInsights.filter(i => i.domain === 'profitability');

    // Generate coordinator summary
    const summary = await geminiAdapter.generateCoordinatorSummary({
      bomWaste: bomInsights.map(i => i.description).join('; ') || undefined,
      inventory: inventoryInsights.map(i => i.description).join('; ') || und
synthesizeInsights method · typescript · L280-L314 (35 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  private async synthesizeInsights(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const insights = this.stateManager.getInsights(undefined, 20);

    // Group by domain
    const byDomain = new Map<string, AgentInsight[]>();
    for (const insight of insights) {
      const current = byDomain.get(insight.domain) || [];
      current.push(insight);
      byDomain.set(insight.domain, current);
    }

    // Generate summary
    const domainSummaries: Record<string, string> = {};
    for (const [domain, domainInsights] of byDomain) {
      domainSummaries[domain] = domainInsights
        .map(i => i.description)
        .slice(0, 3)
        .join('; ');
    }

    const summary = await geminiAdapter.generateCoordinatorSummary({
      bomWaste: domainSummaries['bom'] || domainSummaries['waste'],
      inventory: domainSummaries['inventory'],
      profitability: domainSummaries['profitability'],
    });

    return {
      taskId: task.id,
      agentId: this.id,
evaluateAgents method · typescript · L319-L330 (12 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  private async evaluateAgents(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    await this.evaluateAndCoach();

    return {
      taskId: task.id,
      agentId: this.id,
      success: true,
      output: { evaluated: true },
      processingTime: Date.now() - startTime,
    };
  }
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
evaluateAndCoach method · typescript · L335-L352 (18 LOC)
server/src/agents/coordinator/CoordinatorAgent.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(
            `Sent coaching to ${perf.agentId}: ${feedback.metric} (score: ${feedback.score})`
          );
        }
      }
    }
  }
applyCoaching method · typescript · L357-L360 (4 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  protected async applyCoaching(): Promise<void> {
    // Coordinator doesn't receive coaching from others
    console.log('Coordinator: coaching not applicable');
  }
getSubordinateStatuses method · typescript · L365-L367 (3 LOC)
server/src/agents/coordinator/CoordinatorAgent.ts
  getSubordinateStatuses() {
    return this.subordinates.map(agent => agent.getStatus());
  }
constructor method · typescript · L42-L44 (3 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
    super('cost-management-agent', eventBus, stateManager, learningRegistry);
  }
getCapabilities method · typescript · L46-L55 (10 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  getCapabilities(): string[] {
    return [
      '원가 구조 분석',
      '노무비 효율성 분석',
      '발주/구매 패턴 분석',
      '원가 절감 기회 도출',
      '비용 추세 모니터링',
      '인건비 최적화 제안',
    ];
  }
process method · typescript · L57-L84 (28 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  async process(task: Task): Promise<TaskResult> {
    const startTime = Date.now();

    try {
      switch (task.type) {
        case 'analyze_cost_structure':
          return await this.analyzeCostStructure(task);
        case 'analyze_labor_efficiency':
          return await this.analyzeLaborEfficiency(task);
        case 'analyze_purchase_patterns':
          return await this.analyzePurchasePatterns(task);
        case 'detect_cost_anomalies':
          return await this.detectCostAnomalies(task);
        case 'generate_cost_insight':
          return await this.generateCostInsight(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,
      };
    }
  }
analyzeCostStructure method · typescript · L89-L169 (81 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  private async analyzeCostStructure(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const costData = task.payload?.costData as CostData | undefined;

    if (!costData) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'No cost data available' },
        processingTime: Date.now() - startTime,
      };
    }

    const totalCost =
      costData.rawMaterialCost +
      costData.subMaterialCost +
      costData.laborCost +
      costData.expenseAmount;
    const profitRatio = costData.salesAmount > 0 ? costData.salesAmount / totalCost : 0;

    // Calculate cost ratios
    const ratios = {
      rawMaterial: costData.salesAmount > 0 ? costData.salesAmount / costData.rawMaterialCost : 0,
      subMaterial: costData.salesAmount > 0 ? costData.salesAmount / costData.subMaterialCost : 0,
      labor: costData.salesAmount > 0 ? costData.salesAmount / costData.laborCost : 0,
      expense: costData.s
analyzeLaborEfficiency method · typescript · L174-L246 (73 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  private async analyzeLaborEfficiency(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const attendanceData = task.payload?.attendanceData as AttendanceData[] | undefined;
    const laborCost = (task.payload?.laborCost as number) || 0;
    const productionVolume = (task.payload?.productionVolume as number) || 0;

    if (!attendanceData || attendanceData.length === 0) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'No attendance data available' },
        processingTime: Date.now() - startTime,
      };
    }

    // Calculate overtime statistics
    const totalOvertimeHours = attendanceData.reduce((sum, a) => sum + (a.overtimeHours || 0), 0);
    const uniqueEmployees = new Set(attendanceData.map(a => a.employeeId)).size;
    const avgOvertimePerEmployee = uniqueEmployees > 0 ? totalOvertimeHours / uniqueEmployees : 0;

    // Analyze by shift
    const shiftStats = new Map<string, { count:
Same scanner, your repo: https://repobility.com — Repobility
analyzePurchasePatterns method · typescript · L251-L327 (77 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  private async analyzePurchasePatterns(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const purchaseOrders = task.payload?.purchaseOrders as PurchaseOrderData[] | undefined;

    if (!purchaseOrders || purchaseOrders.length === 0) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'No purchase order data available' },
        processingTime: Date.now() - startTime,
      };
    }

    // Calculate statistics
    const totalAmount = purchaseOrders.reduce((sum, po) => sum + po.totalAmount, 0);
    const urgentOrders = purchaseOrders.filter(po => po.isUrgent).length;

    // Aggregate by supplier
    const supplierStats = new Map<string, number>();
    for (const po of purchaseOrders) {
      const current = supplierStats.get(po.supplierName) || 0;
      supplierStats.set(po.supplierName, current + po.totalAmount);
    }

    // Get top suppliers
    const topSuppliers = Array.from(supplierStats.
detectCostAnomalies method · typescript · L332-L414 (83 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  private async detectCostAnomalies(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const costHistory = task.payload?.costHistory as CostData[] | undefined;

    if (!costHistory || costHistory.length < 2) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'Insufficient cost history for anomaly detection' },
        processingTime: Date.now() - startTime,
      };
    }

    const anomalies: { category: string; variance: number; severity: string }[] = [];

    // Compare latest period with average
    const latest = costHistory[costHistory.length - 1];
    const previousAvg = costHistory.slice(0, -1).reduce(
      (acc, c) => ({
        rawMaterialCost: acc.rawMaterialCost + c.rawMaterialCost,
        subMaterialCost: acc.subMaterialCost + c.subMaterialCost,
        laborCost: acc.laborCost + c.laborCost,
        expenseAmount: acc.expenseAmount + c.expenseAmount,
      }),
      { rawMaterialCo
generateCostInsight method · typescript · L419-L480 (62 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  private async generateCostInsight(task: Task): Promise<TaskResult> {
    const startTime = Date.now();
    const costData = task.payload?.costData as CostData | undefined;

    if (!costData) {
      return {
        taskId: task.id,
        agentId: this.id,
        success: true,
        output: { message: 'No cost data for insight generation' },
        processingTime: Date.now() - startTime,
      };
    }

    const totalCost =
      costData.rawMaterialCost +
      costData.subMaterialCost +
      costData.laborCost +
      costData.expenseAmount;
    const profitRatio = costData.salesAmount > 0 ? costData.salesAmount / totalCost : 0;

    // Calculate cost breakdown percentages
    const breakdown = {
      rawMaterial: (costData.rawMaterialCost / totalCost) * 100,
      subMaterial: (costData.subMaterialCost / totalCost) * 100,
      labor: (costData.laborCost / totalCost) * 100,
      expense: (costData.expenseAmount / totalCost) * 100,
    };

    // Find the largest cost d
applyCoaching method · typescript · L485-L504 (20 LOC)
server/src/agents/cost-management/CostManagementAgent.ts
  protected async applyCoaching(feedback: CoachingMessage['payload']['feedback']): Promise<void> {
    console.log(`CostManagementAgent applying coaching for ${feedback.metric}`);

    if (feedback.metric === 'accuracy') {
      // Adjust thresholds based on feedback
      this.costThreshold = Math.max(this.costThreshold - 0.05, 1.0);
      console.log(`Adjusted cost threshold to ${this.costThreshold}`);
    }

    if (feedback.metric === 'user_acceptance') {
      this.overtimeAlertThreshold = Math.min(this.overtimeAlertThreshold + 5, 40);
      console.log(`Adjusted overtime alert threshold to ${this.overtimeAlertThreshold}%`);
    }

    this.learningRegistry.recordCoaching(this.id, 'general', [
      `costThreshold: ${this.costThreshold}`,
      `laborCostRatio: ${this.laborCostRatio}`,
      `overtimeAlertThreshold: ${this.overtimeAlertThreshold}`,
    ]);
  }
createCostTeam function · typescript · L31-L85 (55 LOC)
server/src/agents/cost-team/index.ts
export function createCostTeam(
  eventBus: EventBus,
  stateManager: StateManager,
  learningRegistry: LearningRegistry
): CostTeam {
  const optimist = new OptimistPersona(
    'cost-optimist',
    'cost-management-team',
    'general',
    eventBus,
    stateManager,
    learningRegistry
  );

  const pessimist = new PessimistPersona(
    'cost-pessimist',
    'cost-management-team',
    'general',
    eventBus,
    stateManager,
    learningRegistry
  );

  const mediator = new MediatorPersona(
    'cost-mediator',
    'cost-management-team',
    'general',
    eventBus,
    stateManager,
    learningRegistry
  );

  return {
    optimist,
    pessimist,
    mediator,
    start: () => {
      optimist.start();
      pessimist.start();
      mediator.start();
      console.log('[CostTeam] 팀 시작됨');
    },
    stop: () => {
      optimist.stop();
      pessimist.stop();
      mediator.stop();
      console.log('[CostTeam] 팀 중지됨');
    },
    injectDependencies: (debateManager: DebateM
ComplianceAuditor class · typescript · L41-L390 (350 LOC)
server/src/agents/governance/ComplianceAuditor.ts
export class ComplianceAuditor extends Agent {
  private debateManager?: DebateManager;
  private geminiAdapter?: GeminiAdapter;

  // 컴플라이언스 규칙들
  private rules: ComplianceRule[] = [
    {
      id: 'DP001',
      name: '개인정보 노출 금지',
      description: '토론 내용에 개인 식별 정보가 포함되어서는 안 됩니다.',
      category: 'data_privacy',
      severity: 'critical',
      check: debate => {
        const content = JSON.stringify(debate);
        // 이메일, 전화번호, 주민번호 패턴 검사
        const piiPatterns = [
          /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/,
          /\b01[0-9]-?\d{3,4}-?\d{4}\b/,
          /\b\d{6}-?[1-4]\d{6}\b/,
        ];
        return !piiPatterns.some(pattern => pattern.test(content));
      },
    },
    {
      id: 'BR001',
      name: '재무 데이터 정확성',
      description: '재무 관련 수치는 검증 가능한 출처가 있어야 합니다.',
      category: 'business_rule',
      severity: 'high',
      check: debate => {
        // 금액 관련 수치가 있을 때 근거도 있는지 확인
        const hasFinancialData = /[₩\$]\d+|억|만원/.test(JSON.
constructor method · typescript · L148-L150 (3 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
    super('compliance-auditor', eventBus, stateManager, learningRegistry);
  }
injectDependencies method · typescript · L155-L158 (4 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  injectDependencies(debateManager: DebateManager, geminiAdapter: GeminiAdapter): void {
    this.debateManager = debateManager;
    this.geminiAdapter = geminiAdapter;
  }
Repobility · open methodology · https://repobility.com/research/
handleMessage method · typescript · L163-L171 (9 LOC)
server/src/agents/governance/ComplianceAuditor.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 · L176-L215 (40 LOC)
server/src/agents/governance/ComplianceAuditor.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.performComplianceReview(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: 'compliance',
      });

      this.processedTasks++;
      this.successfulTasks++;
      this.totalProcessingTime += Date.now() - startTime;

      // 컴플라이언스 위반 발견 시 인사이트 발행
      if (!review.approved) {
        this.publishComplianceInsight(payload.debate, review);
      }
    } catch (error) {
      console.error('[Co
performComplianceReview method · typescript · L220-L270 (51 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  async performComplianceReview(
    debate: DebateRecord
  ): Promise<Omit<GovernanceReview, 'id' | 'debateId'>> {
    const issues: GovernanceIssue[] = [];
    let score = 100;

    // 각 규칙 검사
    for (const rule of this.rules) {
      try {
        const passed = rule.check(debate);

        if (!passed) {
          const severityPenalty = {
            low: 5,
            medium: 10,
            high: 20,
            critical: 40,
          };

          issues.push({
            type: 'compliance',
            severity: rule.severity,
            description: `[${rule.id}] ${rule.name}: ${rule.description}`,
          });

          score -= severityPenalty[rule.severity];
        }
      } catch (error) {
        console.error(`[ComplianceAuditor] 규칙 ${rule.id} 검사 오류:`, error);
      }
    }

    // 점수 범위 조정
    score = Math.max(0, Math.min(100, score));

    // 승인 기준: 점수 60 이상 & critical 이슈 없음
    const approved = score >= 60 && !issues.some(i => i.severity === 'critical');

   
generateRecommendations method · typescript · L275-L305 (31 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  private generateRecommendations(issues: GovernanceIssue[]): string[] {
    const recommendations: string[] = [];
    const categories = new Set(
      issues.map(i => {
        const match = i.description.match(/\[(.*?)\]/);
        return match ? match[1].substring(0, 2) : '';
      })
    );

    if (issues.some(i => i.description.includes('DP'))) {
      recommendations.push('개인정보 보호를 위해 민감 데이터를 익명화하거나 제거하세요.');
    }

    if (issues.some(i => i.description.includes('BR'))) {
      recommendations.push('비즈니스 규정 준수를 위해 결론과 근거를 보강하세요.');
    }

    if (issues.some(i => i.description.includes('RM'))) {
      recommendations.push('리스크 관리 체계를 강화하고 완화 방안을 명시하세요.');
    }

    if (issues.some(i => i.description.includes('RG'))) {
      recommendations.push('토론 내용이 지정된 도메인과 관련성을 갖도록 조정하세요.');
    }

    if (issues.some(i => i.severity === 'critical')) {
      recommendations.push('심각한 컴플라이언스 위반이 발견되어 즉각적인 조치가 필요합니다.');
    }

    return recommendations;
  }
publishComplianceInsight method · typescript · L310-L338 (29 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  private publishComplianceInsight(
    debate: DebateRecord,
    review: Omit<GovernanceReview, 'id' | 'debateId'>
  ): void {
    const criticalIssues = review.issues?.filter(i => i.severity === 'critical') || [];
    const level: InsightLevel =
      criticalIssues.length > 0 ? 'critical' : review.score < 60 ? 'warning' : 'info';

    this.publishInsight(
      debate.domain,
      `[컴플라이언스] ${debate.topic}`,
      `컴플라이언스 검토 완료: ${review.approved ? '승인' : '위반 발견'} (점수: ${review.score}/100)`,
      {
        level,
        confidence: review.score / 100,
        data: {
          debateId: debate.id,
          issues: review.issues,
          recommendations: review.recommendations,
          violatedRules: review.issues?.map(i => {
            const match = i.description.match(/\[(.*?)\]/);
            return match ? match[1] : '';
          }),
        },
        actionable: !review.approved,
        suggestedActions: review.recommendations,
      }
    );
  }
addRule method · typescript · L343-L346 (4 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  addRule(rule: ComplianceRule): void {
    this.rules.push(rule);
    console.log(`[ComplianceAuditor] 규칙 추가됨: ${rule.id} - ${rule.name}`);
  }
getRules method · typescript · L351-L353 (3 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  getRules(): ComplianceRule[] {
    return [...this.rules];
  }
process method · typescript · L358-L366 (9 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  async process(task: Task): Promise<TaskResult> {
    return {
      taskId: task.id,
      agentId: this.id,
      success: true,
      output: { message: 'Compliance review processed' },
      processingTime: 0,
    };
  }
Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
getCapabilities method · typescript · L371-L380 (10 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  getCapabilities(): string[] {
    return [
      'compliance_auditing',
      'data_privacy_review',
      'business_rule_validation',
      'risk_assessment_review',
      'regulatory_compliance',
      'governance_approval',
    ];
  }
applyCoaching method · typescript · L385-L389 (5 LOC)
server/src/agents/governance/ComplianceAuditor.ts
  protected async applyCoaching(feedback: CoachingMessage['payload']['feedback']): Promise<void> {
    console.log(`[ComplianceAuditor] 코칭 적용: ${feedback.suggestion}`);

    // 향후 규칙 가중치 조정 등에 활용 가능
  }
constructor method · typescript · L41-L43 (3 LOC)
server/src/agents/governance/QASpecialist.ts
  constructor(eventBus: EventBus, stateManager: StateManager, learningRegistry: LearningRegistry) {
    super('qa-specialist', eventBus, stateManager, learningRegistry);
  }
‹ prevpage 4 / 13next ›