Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
import * as fs from 'node:fs/promises';
|
|
import * as path from 'node:path';
|
|
|
|
import type { EvaluationLifecycle, ExampleResult } from '../harness/harness-types';
|
|
import type { EvalLogger } from '../harness/logger';
|
|
import { summarizeIntrospectionResults } from '../summarizers/introspection-summarizer';
|
|
|
|
export interface IntrospectionAnalysisOptions {
|
|
judgeLlm: BaseChatModel;
|
|
outputDir?: string;
|
|
logger: EvalLogger;
|
|
}
|
|
|
|
export function createIntrospectionAnalysisLifecycle(
|
|
options: IntrospectionAnalysisOptions,
|
|
): Partial<EvaluationLifecycle> {
|
|
const { logger } = options;
|
|
const collectedResults: ExampleResult[] = [];
|
|
|
|
return {
|
|
onExampleComplete(_index, result) {
|
|
collectedResults.push(result);
|
|
|
|
const events = result.introspectionEvents ?? [];
|
|
if (events.length > 0) {
|
|
logger.info(` ${events.length} introspection event(s):`);
|
|
for (const event of events) {
|
|
logger.info(` [${event.category}] ${event.issue}`);
|
|
}
|
|
} else {
|
|
logger.info(' No introspection events');
|
|
}
|
|
},
|
|
|
|
async onEnd() {
|
|
if (collectedResults.length === 0) return;
|
|
|
|
const { judgeLlm, outputDir, logger } = options;
|
|
|
|
logger.info('\n📊 Running introspection analysis...\n');
|
|
|
|
const summary = await summarizeIntrospectionResults(collectedResults, judgeLlm);
|
|
|
|
logger.info('=== Introspection Analysis ===\n');
|
|
logger.info(`Total events: ${summary.totalEvents}`);
|
|
logger.info(`Category breakdown: ${JSON.stringify(summary.categoryBreakdown, null, 2)}`);
|
|
logger.info('\n--- LLM Analysis ---\n');
|
|
logger.info(summary.llmAnalysis);
|
|
|
|
if (outputDir) {
|
|
const summaryContent = `# Introspection Summary
|
|
|
|
## Overview
|
|
- **Total Events:** ${summary.totalEvents}
|
|
- **Category Breakdown:** ${JSON.stringify(summary.categoryBreakdown, null, 2)}
|
|
|
|
## LLM Analysis
|
|
|
|
${summary.llmAnalysis}
|
|
`;
|
|
const summaryPath = path.join(outputDir, 'introspection-summary.md');
|
|
await fs.writeFile(summaryPath, summaryContent);
|
|
logger.info(`\nSummary saved to: ${summaryPath}`);
|
|
}
|
|
},
|
|
};
|
|
}
|