OpenWriterControle/evals/framework/README.md
darrenhinde f773b290ce chore(evals): comprehensive cleanup, documentation, and test infrastructure improvements
Documentation:
- Add ARCHITECTURE.md with comprehensive system review
- Add GETTING_STARTED.md for new users
- Add DOCUMENTATION_CLEANUP.md tracking cleanup changes
- Add SCRIPTS_ORGANIZATION.md documenting script reorganization
- Remove outdated docs (TESTING_CONFIDENCE.md, TEST_REVIEW.md, SESSION_STORAGE_FIX.md)
- Update README files with current information

Script Organization:
- Move 12 scripts from framework root to organized directories:
  - scripts/debug/ (4 files): Session debugging tools
  - scripts/test/ (6 files): Test execution scripts
  - scripts/utils/ (2 files): Utility scripts
- Add comprehensive scripts/README.md with usage examples

Test Infrastructure:
- Add 5 new context loading tests for openagent
- Add result-saver.ts for test result persistence
- Add interactive results dashboard (index.html)
- Add error-handling.test.ts for framework testing
- Add result-saver.test.ts with comprehensive unit tests

Evaluator Improvements:
- Enhance context-loading-evaluator with better detection
- Update run-sdk-tests.ts with improved result handling

Agent Configuration:
- Add .opencode/agent/AGENT.md for agent definition

Test Utilities:
- Add test-agent-manual.mjs for manual testing
- Update test_tmp/README.md with usage guidelines

This commit consolidates multiple improvements:
- Better organization (scripts, docs)
- Improved testing infrastructure
- Comprehensive documentation
- Cleaner codebase structure
2025-11-26 21:34:27 +00:00

371 lines
7.9 KiB
Markdown

# Evaluation Framework
## Overview
Reusable framework for evaluating OpenCode agent behavior. Can be used to test any agent against defined standards.
## Architecture
```
framework/
├── src/
│ ├── collector/ # Session data collection
│ │ ├── session-reader.ts
│ │ ├── message-parser.ts
│ │ └── timeline-builder.ts
│ ├── evaluators/ # Evaluation logic
│ │ ├── base-evaluator.ts
│ │ ├── approval-gate.ts
│ │ ├── context-loading.ts
│ │ ├── delegation.ts
│ │ ├── tool-usage.ts
│ │ └── model-selection.ts
│ ├── runner/ # Test execution
│ │ ├── test-runner.ts
│ │ └── session-analyzer.ts
│ ├── reporters/ # Result reporting
│ │ ├── console-reporter.ts
│ │ ├── json-reporter.ts
│ │ └── markdown-reporter.ts
│ ├── types/ # TypeScript types
│ │ └── index.ts
│ ├── config.ts # Configuration
│ └── index.ts # Main exports
├── tests/ # Framework tests
├── package.json
├── tsconfig.json
└── README.md
```
## Installation
```bash
npm install
```
## Usage
### Basic Example
```typescript
import { SessionReader, ApprovalGateEvaluator, TimelineBuilder } from '@evals/framework';
// Read session
const reader = new SessionReader('/path/to/project');
const sessionInfo = reader.getSessionInfo('ses_xxxxx');
const messages = reader.getMessages('ses_xxxxx');
// Build timeline
const builder = new TimelineBuilder(reader);
const timeline = builder.buildTimeline('ses_xxxxx');
// Evaluate
const evaluator = new ApprovalGateEvaluator();
const result = evaluator.evaluate(timeline);
console.log(`Passed: ${result.passed}`);
console.log(`Score: ${result.score}/100`);
console.log(`Violations: ${result.violations.length}`);
```
### Running Test Suite
```typescript
import { TestRunner } from '@evals/framework';
const runner = new TestRunner({
projectPath: process.cwd(),
evaluatorsPath: './src/evaluators',
resultsPath: '../results'
});
// Load test cases
const testCases = runner.loadTestCases('../opencode/openagent/test-cases/approval-gates.yaml');
// Run tests
const suite = runner.runAll(testCases);
console.log(`Pass Rate: ${suite.summary.passRate}%`);
```
## Components
### Collector
**SessionReader** - Read OpenCode session files
```typescript
const reader = new SessionReader(projectPath);
const info = reader.getSessionInfo(sessionId);
const messages = reader.getMessages(sessionId);
const parts = reader.getParts(sessionId, messageId);
```
**MessageParser** - Parse message structure
```typescript
const parser = new MessageParser();
const agent = parser.getAgent(message);
const model = parser.getModel(message);
const metrics = parser.getMetrics(message);
```
**TimelineBuilder** - Build event timeline
```typescript
const builder = new TimelineBuilder(reader);
const timeline = builder.buildTimeline(sessionId);
const toolCalls = builder.filterByType(timeline, 'tool_call');
```
### Evaluators
All evaluators extend `BaseEvaluator` and implement:
```typescript
evaluate(timeline: TimelineEvent[]): EvaluationResult
```
**ApprovalGateEvaluator** - Check approval before execution
```typescript
const evaluator = new ApprovalGateEvaluator();
const result = evaluator.evaluate(timeline);
```
**ContextLoadingEvaluator** - Verify context loading
```typescript
const evaluator = new ContextLoadingEvaluator();
const result = evaluator.evaluate(timeline);
```
**DelegationEvaluator** - Validate delegation decisions
```typescript
const evaluator = new DelegationEvaluator();
const result = evaluator.evaluate(timeline);
```
**ToolUsageEvaluator** - Check tool selection
```typescript
const evaluator = new ToolUsageEvaluator();
const result = evaluator.evaluate(timeline);
```
### Runner
**TestRunner** - Execute test suites
```typescript
const runner = new TestRunner(config);
const testCases = runner.loadTestCases(path);
const suite = runner.runAll(testCases);
```
**SessionAnalyzer** - Analyze historical sessions
```typescript
const analyzer = new SessionAnalyzer(reader);
const result = analyzer.analyze(sessionId, testCase);
```
### Reporters
**ConsoleReporter** - Pretty console output
```typescript
const reporter = new ConsoleReporter();
reporter.report(testSuite);
```
**JSONReporter** - Machine-readable JSON
```typescript
const reporter = new JSONReporter();
reporter.export(testSuite, 'results.json');
```
**MarkdownReporter** - Documentation format
```typescript
const reporter = new MarkdownReporter();
reporter.generate(testSuite, 'report.md');
```
## Types
### Core Types
```typescript
interface SessionInfo {
id: string;
version: string;
title: string;
time: { created: number; updated: number };
}
interface Message {
id: string;
role: 'user' | 'assistant';
sessionID: string;
mode?: string;
modelID?: string;
providerID?: string;
tokens?: TokenUsage;
cost?: number;
time: { created: number; completed?: number };
}
interface TimelineEvent {
timestamp: number;
type: 'user_message' | 'assistant_message' | 'tool_call' | 'patch';
agent?: string;
model?: string;
data: any;
}
interface EvaluationResult {
evaluator: string;
passed: boolean;
score: number;
violations: Violation[];
evidence: Evidence[];
}
interface TestResult {
testCaseId: string;
sessionId: string;
passed: boolean;
score: number;
evaluationResults: EvaluationResult[];
metadata: any;
}
```
## Configuration
```typescript
// config.ts
export const config = {
projectPath: process.cwd(),
sessionStoragePath: '~/.local/share/opencode/',
resultsPath: '../results/',
passThreshold: 75,
evaluators: {
'approval-gate': ApprovalGateEvaluator,
'context-loading': ContextLoadingEvaluator,
'delegation': DelegationEvaluator,
'tool-usage': ToolUsageEvaluator,
}
};
```
## Development
### Setup
```bash
npm install
npm run build
```
### Testing
```bash
# Run all tests
npm test
# Run specific test
npm test -- session-reader
# Watch mode
npm run test:watch
```
### Building
```bash
# Build TypeScript
npm run build
# Watch mode
npm run build:watch
```
### Linting
```bash
npm run lint
npm run lint:fix
```
## Adding New Evaluators
1. Create file in `src/evaluators/`
2. Extend `BaseEvaluator`
3. Implement `evaluate()` method
4. Add tests
5. Register in config
6. Export from `index.ts`
**Example:**
```typescript
// src/evaluators/my-evaluator.ts
import { BaseEvaluator } from './base-evaluator';
import { EvaluationResult, TimelineEvent } from '../types';
export class MyEvaluator extends BaseEvaluator {
evaluate(timeline: TimelineEvent[]): EvaluationResult {
// Your evaluation logic
const checks = [
{ name: 'check1', passed: true, weight: 50 },
{ name: 'check2', passed: false, weight: 50 }
];
const score = this.calculateScore(checks);
const violations = this.findViolations(timeline);
return {
evaluator: 'my-evaluator',
passed: score >= 75,
score,
violations,
evidence: []
};
}
}
```
## API Reference
See [API.md](./API.md) for complete API documentation.
## Contributing
1. Fork the repository
2. Create feature branch
3. Add tests
4. Submit pull request
## License
MIT
---
## Scripts
Development and debugging scripts are organized in the `scripts/` directory:
```
scripts/
├── debug/ # Session and event debugging
├── test/ # Framework component tests
├── utils/ # Utility scripts (batch runner, etc.)
└── README.md # Script documentation
```
See [scripts/README.md](scripts/README.md) for detailed usage.
### Quick Examples
```bash
# Run tests in batches
./scripts/utils/run-tests-batch.sh openagent 3 10
# Debug a session
node scripts/debug/inspect-session.mjs
# Test framework component
npx tsx scripts/test/test-timeline.ts
```