chore: verify and stabilize main branch (#42)
* chore: update package-lock.json after npm install * chore: remove unused ajv-cli, keep vitest at stable 1.6.1 - Removed ajv-cli (unused dev dependency, had high severity vulnerability) - Kept vitest at 1.6.1 (stable, upgrading to v4 requires extensive refactoring) - Reduced vulnerabilities from 6 to 4 (all moderate, dev-only) - All remaining vulnerabilities are in esbuild/vite (dev server only, no production impact) - Build and tests verified working * feat(evals): add execution-balance validation to 21 OpenAgent tests and enhance agent system Major improvements to evaluation framework and agent capabilities: ## Execution Balance Evaluator Integration - Added execution-balance rule to 21 OpenAgent tests (2.7% → 31.5% coverage) - Validates "read before execute" pattern across critical rules, workflows, and edge cases - Tests now check: read operations before execution tools, healthy read/exec ratio (≥1.0) - Coverage includes: approval-gate, context-loading, stop-on-failure, report-first tests ## Agent System Enhancements - Enhanced OpenCoder agent with critical rules enforcement (approval gates, context loading) - Added structured delegation rules and workflow phases - Improved error handling with REPORT→PROPOSE→REQUEST→FIX pattern ## New Agent Creation System - Added research-backed agent creation templates and guides - Includes 8 test templates covering planning, context, incremental execution, tools - Automated agent scaffolding with /create-agent command - Complete documentation in .opencode/command/openagents/new-agents/ ## OpenCoder Test Suite - Added 8 comprehensive test cases for OpenCoder agent - Tests cover: planning, context-loading, delegation, error-handling, implementation - Includes DEBUG_GUIDE.md and QUICK_TEST_GUIDE.md for developers ## Documentation & Tooling - Added DEVELOPMENT.md guide for contributors - Enhanced CONTRIBUTING.md with quick reference and common commands - Improved event-logger with DEBUG_VERBOSE mode for detailed output - Added debug scripts: show-test-conversation.sh, run-test-verbose.sh - Removed deprecated EXTERNAL_PR_GUIDE.md ## Version Bump - Bumped version to 0.0.3 (patch) Files changed: 60+ files (21 test updates, 16 new agent templates, 8 new tests, docs, tooling) * feat(ci): add PR title validation for semantic versioning Add automated PR title validation to ensure conventional commit format. This enables proper automatic version bumping when PRs are merged. Features: - Validates PR titles against conventional commit patterns - Shows expected version bump (major/minor/patch) - Posts helpful comment with examples if validation fails - Supports all conventional commit types (feat, fix, docs, etc.) - Supports breaking changes (feat!, fix!) - Supports pre-release tags ([alpha], [beta], [rc]) When PR titles follow the format, version bumping works correctly: - feat: → minor bump (0.3.0 → 0.4.0) - fix: → patch bump (0.3.0 → 0.3.1) - feat!: → major bump (0.3.0 → 1.0.0) * fix(ci): improve PR checks workflow with sequential execution Reorganize PR checks to run in logical sequence and skip unnecessary checks: Changes: - Run PR title validation first (fast, always required) - Detect changed files to determine which checks to run - Only run build checks if evals/ files changed - Add comprehensive summary job showing all check results - Prevent cache errors when evals files not changed Benefits: - Faster PR checks (skip unnecessary builds) - Clear sequential execution (title → changes → build) - Better error messages and summaries - Reduced CI/CD costs * fix(ci): resolve PR #42 issues and refactor prompt architecture ## Fixed PR #42 Issues 1. **Prompt Validation** - Refactored to new architecture where agent files are canonical defaults 2. **Package-lock.json** - Fixed workflow to use root package-lock (npm workspaces) 3. **Git Merge Base** - Added fetch-depth: 0 to PR checks workflow ## New Prompt Architecture **Before:** - Agent files had to match .opencode/prompts/<agent>/default.md - Caused validation failures when updating prompts - Redundant duplication **After:** - Agent files (.opencode/agent/*.md) = Canonical defaults (source of truth) - Prompt variants (.opencode/prompts/<agent>/<model>.md) = Model-specific optimizations - No more default.md files needed ## Changes ### Workflows - pr-checks.yml: Added fetch-depth: 0 for full git history - validate-test-suites.yml: Fixed package-lock path for npm workspaces - validate-registry.yml: Updated validation messaging ### Scripts - validate-pr.sh: Validates prompt library structure (rejects default.md files) - use-prompt.sh: Handles 'default' as agent file, variants as model-specific - test-prompt.sh: Tests default variant correctly, saves results to prompts/results/ ### Documentation - .opencode/prompts/README.md: Updated architecture explanation - docs/contributing/CONTRIBUTING.md: Updated prompt workflow - scripts/development/demo.sh: Updated structure display ## Results - 12 files changed, 231 insertions(+), 811 deletions(-) - Net reduction: 580 lines (cleaner codebase) - All validations passing - Results directory structure preserved - Backwards compatible with existing test results
This commit is contained in:
parent
e81f71bdac
commit
784ffadf92
72 changed files with 7038 additions and 1925 deletions
174
.github/EXTERNAL_PR_GUIDE.md
vendored
174
.github/EXTERNAL_PR_GUIDE.md
vendored
|
|
@ -1,174 +0,0 @@
|
||||||
# External PR Guide
|
|
||||||
|
|
||||||
This guide explains how GitHub Actions workflows behave for external contributors (fork PRs).
|
|
||||||
|
|
||||||
## For External Contributors (Fork PRs)
|
|
||||||
|
|
||||||
When you submit a PR from a fork, workflows run but **cannot auto-commit fixes** due to GitHub security restrictions.
|
|
||||||
|
|
||||||
### What Runs Automatically
|
|
||||||
|
|
||||||
✅ **Fast Build Check (< 2 minutes)**
|
|
||||||
- TypeScript compilation check
|
|
||||||
- YAML test suite validation
|
|
||||||
- Quick feedback on code quality
|
|
||||||
|
|
||||||
✅ **Registry Validation**
|
|
||||||
- Checks if `registry.json` matches actual files
|
|
||||||
- Validates all paths are correct
|
|
||||||
- Checks prompts use defaults
|
|
||||||
- **Cannot auto-commit** (you'll need to fix locally)
|
|
||||||
|
|
||||||
❌ **What Doesn't Run on PRs**
|
|
||||||
- Full AI agent tests (too expensive, run manually by maintainers)
|
|
||||||
- Auto-version bumping (happens after merge)
|
|
||||||
|
|
||||||
### What You Need to Do
|
|
||||||
|
|
||||||
If the validation workflow reports issues, you'll need to fix them locally:
|
|
||||||
|
|
||||||
#### 1. Build Failures
|
|
||||||
|
|
||||||
If TypeScript compilation fails:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build locally to see errors
|
|
||||||
cd evals/framework
|
|
||||||
npm install
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# Fix the errors, then commit
|
|
||||||
git add .
|
|
||||||
git commit -m "fix: resolve build errors"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Registry Issues
|
|
||||||
|
|
||||||
If new components are detected (you'll get a comment on your PR):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run auto-detect locally
|
|
||||||
./scripts/registry/auto-detect-components.sh --auto-add
|
|
||||||
|
|
||||||
# Commit the updated registry
|
|
||||||
git add registry.json
|
|
||||||
git commit -m "chore: update registry with new components"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. Prompt Issues
|
|
||||||
|
|
||||||
If prompts don't match defaults:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Restore default prompts
|
|
||||||
./scripts/prompts/use-prompt.sh <agent-name> default
|
|
||||||
|
|
||||||
# Commit the changes
|
|
||||||
git add .opencode/agent/
|
|
||||||
git commit -m "chore: restore default prompts"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. Path Issues
|
|
||||||
|
|
||||||
If registry paths are invalid:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Validate and see suggestions
|
|
||||||
./scripts/validate-registry.sh --fix
|
|
||||||
|
|
||||||
# Manually fix paths in registry.json
|
|
||||||
# Then commit
|
|
||||||
git add registry.json
|
|
||||||
git commit -m "fix: correct registry paths"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
### What Happens Next
|
|
||||||
|
|
||||||
1. **Fix Issues Locally**: If validation fails, fix issues and push
|
|
||||||
2. **Fast Feedback**: Build checks complete in < 2 minutes
|
|
||||||
3. **Maintainer Review**: A maintainer will review your code
|
|
||||||
4. **Merge**: Once everything passes, your PR will be merged!
|
|
||||||
5. **Auto-Release**: After merge, version is auto-bumped and release created (you don't need to do anything!)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## For Maintainers
|
|
||||||
|
|
||||||
### Handling External PRs
|
|
||||||
|
|
||||||
External PRs run normally but **cannot auto-commit** due to GitHub security (can't push to fork branches).
|
|
||||||
|
|
||||||
### Simple Overrides
|
|
||||||
|
|
||||||
If you need to override checks:
|
|
||||||
|
|
||||||
**Skip Validation:**
|
|
||||||
1. Go to **Actions** → **Validate Registry on PR**
|
|
||||||
2. Click **"Run workflow"**
|
|
||||||
3. Enable **"Skip validation checks"**
|
|
||||||
4. Run on the PR branch
|
|
||||||
|
|
||||||
**Skip Version Bump:**
|
|
||||||
1. Go to **Actions** → **Post-Merge Automation**
|
|
||||||
2. Click **"Run workflow"**
|
|
||||||
3. Enable **"Skip version bump"**
|
|
||||||
4. Run manually
|
|
||||||
|
|
||||||
### Workflow Behavior
|
|
||||||
|
|
||||||
| PR Type | Build Check | Registry Validation | Auto-Commit | AI Tests |
|
|
||||||
|---------|------------|-------------------|-------------|----------|
|
|
||||||
| **Internal PR** (branch) | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No* |
|
|
||||||
| **External PR** (fork) | ✅ Yes | ✅ Yes | ❌ No** | ❌ No* |
|
|
||||||
|
|
||||||
*AI tests don't run on PRs (too expensive) - maintainers run manually if needed
|
|
||||||
**Cannot push to fork branches - contributor must fix locally
|
|
||||||
|
|
||||||
### Manual Testing External PRs
|
|
||||||
|
|
||||||
If you want to test an external PR locally:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Fetch the PR
|
|
||||||
gh pr checkout <PR_NUMBER>
|
|
||||||
|
|
||||||
# Run build check
|
|
||||||
cd evals/framework
|
|
||||||
npm install
|
|
||||||
npm run build
|
|
||||||
npm run validate:suites:all
|
|
||||||
|
|
||||||
# Run validation
|
|
||||||
./scripts/registry/validate-registry.sh -v
|
|
||||||
./scripts/prompts/validate-pr.sh
|
|
||||||
|
|
||||||
# Auto-fix registry if needed
|
|
||||||
./scripts/registry/auto-detect-components.sh --auto-add
|
|
||||||
|
|
||||||
# Run AI tests (optional - only if needed)
|
|
||||||
npm run test:ci
|
|
||||||
|
|
||||||
# If everything passes, approve and merge
|
|
||||||
gh pr review <PR_NUMBER> --approve
|
|
||||||
gh pr merge <PR_NUMBER>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** AI tests are optional for PRs. The build check is usually sufficient.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workflow Files
|
|
||||||
|
|
||||||
- **`.github/workflows/pr-checks.yml`**: Fast build validation (< 2 min)
|
|
||||||
- **`.github/workflows/validate-registry.yml`**: Registry validation with override
|
|
||||||
- **`.github/workflows/post-merge.yml`**: Auto-versioning after merge (main only)
|
|
||||||
|
|
||||||
## Questions?
|
|
||||||
|
|
||||||
- **Contributors**: See [CONTRIBUTING.md](../docs/contributing/CONTRIBUTING.md)
|
|
||||||
- **Maintainers**: See [WORKFLOW_GUIDE.md](../WORKFLOW_GUIDE.md)
|
|
||||||
- **Issues**: Open a [GitHub Issue](https://github.com/darrenhinde/OpenAgents/issues)
|
|
||||||
207
.github/workflows/README.md
vendored
207
.github/workflows/README.md
vendored
|
|
@ -1,207 +0,0 @@
|
||||||
# Workflow Guide
|
|
||||||
|
|
||||||
This directory contains GitHub Actions workflows for automated testing, validation, and releases.
|
|
||||||
|
|
||||||
## Workflow Overview
|
|
||||||
|
|
||||||
### For Contributors (PR Workflows)
|
|
||||||
|
|
||||||
#### `pr-checks.yml` - Fast Build Validation
|
|
||||||
**Triggers:** Pull requests to main/dev with evals changes
|
|
||||||
**Duration:** < 2 minutes
|
|
||||||
**What it does:**
|
|
||||||
- ✅ TypeScript compilation check
|
|
||||||
- ✅ YAML test suite validation
|
|
||||||
- ✅ Fast feedback on code quality
|
|
||||||
|
|
||||||
**Fork-friendly:** ✅ Yes - read-only checks
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### `validate-registry.yml` - Registry Validation
|
|
||||||
**Triggers:** Pull requests to main/dev
|
|
||||||
**Duration:** < 1 minute
|
|
||||||
**What it does:**
|
|
||||||
- ✅ Validates registry.json paths
|
|
||||||
- ✅ Auto-detects new components
|
|
||||||
- ✅ Validates prompts use defaults
|
|
||||||
- ✅ **Internal PRs:** Auto-commits registry updates
|
|
||||||
- ✅ **Fork PRs:** Posts comment with instructions
|
|
||||||
|
|
||||||
**Fork-friendly:** ✅ Yes - detects forks and provides guidance
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### For Maintainers (Post-Merge Workflows)
|
|
||||||
|
|
||||||
#### `post-merge.yml` - Auto-Versioning & Releases
|
|
||||||
**Triggers:** Push to main branch
|
|
||||||
**Duration:** < 1 minute
|
|
||||||
**What it does:**
|
|
||||||
- ✅ Auto-bumps version based on conventional commits
|
|
||||||
- ✅ Updates CHANGELOG.md
|
|
||||||
- ✅ Creates git tag
|
|
||||||
- ✅ Publishes GitHub release
|
|
||||||
|
|
||||||
**Conventional Commit Examples:**
|
|
||||||
```bash
|
|
||||||
feat: add new feature # → Minor bump (0.1.0 → 0.2.0)
|
|
||||||
fix: bug fix # → Patch bump (0.1.0 → 0.1.1)
|
|
||||||
feat!: breaking change # → Major bump (0.1.0 → 1.0.0)
|
|
||||||
[alpha] experimental # → Alpha bump (0.1.0-alpha.1)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Manual override:** Can skip version bump via workflow_dispatch
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### `update-registry.yml` - Registry Auto-Update
|
|
||||||
**Triggers:** Push to main with .opencode changes
|
|
||||||
**Duration:** < 1 minute
|
|
||||||
**What it does:**
|
|
||||||
- ✅ Auto-detects new components
|
|
||||||
- ✅ Updates registry.json
|
|
||||||
- ✅ Commits changes to main
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### `sync-docs.yml` - Documentation Sync
|
|
||||||
**Triggers:** Push to main with registry/component changes
|
|
||||||
**Duration:** Variable (depends on OpenCode)
|
|
||||||
**What it does:**
|
|
||||||
- ✅ Creates sync branch
|
|
||||||
- ✅ Opens issue for OpenCode to update docs
|
|
||||||
- ✅ Syncs component counts with registry
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Integration Workflows
|
|
||||||
|
|
||||||
#### `opencode.yml` - OpenCode Integration
|
|
||||||
**Triggers:** Issue comments with `/opencode` or `/oc`
|
|
||||||
**What it does:**
|
|
||||||
- ✅ Enables OpenCode AI assistance on issues
|
|
||||||
- ✅ Restricted to maintainers only
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workflow Philosophy
|
|
||||||
|
|
||||||
### Design Principles
|
|
||||||
|
|
||||||
1. **Fast Feedback** - PRs get results in < 2 minutes
|
|
||||||
2. **Fork-Friendly** - No push attempts to fork branches
|
|
||||||
3. **Cost-Effective** - No expensive AI tests on every PR
|
|
||||||
4. **Maintainer Control** - Manual overrides available
|
|
||||||
5. **Clear Communication** - Helpful error messages and guidance
|
|
||||||
|
|
||||||
### What Changed (Dec 2025)
|
|
||||||
|
|
||||||
**Before:**
|
|
||||||
- ❌ Expensive AI tests on every PR (15 min, costs money)
|
|
||||||
- ❌ Fork PRs failed with confusing errors
|
|
||||||
- ❌ Slow feedback loop
|
|
||||||
|
|
||||||
**After:**
|
|
||||||
- ✅ Fast build checks (< 2 min, free)
|
|
||||||
- ✅ Fork-friendly workflows
|
|
||||||
- ✅ Manual AI testing when needed
|
|
||||||
- ✅ Auto-versioning preserved (moved to post-merge)
|
|
||||||
|
|
||||||
See [_archive/README.md](_archive/README.md) for details on removed workflows.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## For Contributors
|
|
||||||
|
|
||||||
### What Runs on Your PR
|
|
||||||
|
|
||||||
1. **Build Check** (`pr-checks.yml`)
|
|
||||||
- TypeScript compilation
|
|
||||||
- YAML validation
|
|
||||||
- Fast (< 2 min)
|
|
||||||
|
|
||||||
2. **Registry Validation** (`validate-registry.yml`)
|
|
||||||
- Path validation
|
|
||||||
- Component detection
|
|
||||||
- Prompt validation
|
|
||||||
|
|
||||||
### If Checks Fail
|
|
||||||
|
|
||||||
See [EXTERNAL_PR_GUIDE.md](../EXTERNAL_PR_GUIDE.md) for detailed instructions.
|
|
||||||
|
|
||||||
**Quick fixes:**
|
|
||||||
```bash
|
|
||||||
# Build errors
|
|
||||||
cd evals/framework && npm run build
|
|
||||||
|
|
||||||
# Registry updates
|
|
||||||
./scripts/registry/auto-detect-components.sh --auto-add
|
|
||||||
|
|
||||||
# Prompt issues
|
|
||||||
./scripts/prompts/use-prompt.sh <agent> default
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## For Maintainers
|
|
||||||
|
|
||||||
### Manual Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test PR locally
|
|
||||||
gh pr checkout <PR_NUMBER>
|
|
||||||
cd evals/framework
|
|
||||||
npm install
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# Run AI tests (optional)
|
|
||||||
npm run test:ci
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual Overrides
|
|
||||||
|
|
||||||
**Skip validation:**
|
|
||||||
```bash
|
|
||||||
gh workflow run validate-registry.yml -f skip_validation=true
|
|
||||||
```
|
|
||||||
|
|
||||||
**Skip version bump:**
|
|
||||||
```bash
|
|
||||||
gh workflow run post-merge.yml -f skip_version_bump=true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Version Management
|
|
||||||
|
|
||||||
Version bumping is automatic based on commit messages. See [VERSION_BUMP_GUIDE.md](VERSION_BUMP_GUIDE.md).
|
|
||||||
|
|
||||||
**Manual version bump:**
|
|
||||||
```bash
|
|
||||||
npm run version:bump:patch # 0.1.0 → 0.1.1
|
|
||||||
npm run version:bump:minor # 0.1.0 → 0.2.0
|
|
||||||
npm run version:bump:major # 0.1.0 → 1.0.0
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workflow Status
|
|
||||||
|
|
||||||
| Workflow | Status | Purpose | Fork-Friendly |
|
|
||||||
|----------|--------|---------|---------------|
|
|
||||||
| pr-checks.yml | ✅ Active | Fast build validation | ✅ Yes |
|
|
||||||
| validate-registry.yml | ✅ Active | Registry validation | ✅ Yes |
|
|
||||||
| post-merge.yml | ✅ Active | Auto-versioning | N/A (main only) |
|
|
||||||
| update-registry.yml | ✅ Active | Registry auto-update | N/A (main only) |
|
|
||||||
| sync-docs.yml | ✅ Active | Doc sync | N/A (main only) |
|
|
||||||
| opencode.yml | ✅ Active | OpenCode integration | N/A (issues only) |
|
|
||||||
| test-agents.yml | 🗄️ Archived | Expensive AI tests | ❌ No |
|
|
||||||
| validate-test-suites.yml | 🗄️ Archived | Redundant validation | ✅ Yes |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Questions?
|
|
||||||
|
|
||||||
- **Contributors:** See [EXTERNAL_PR_GUIDE.md](../EXTERNAL_PR_GUIDE.md)
|
|
||||||
- **Maintainers:** See [PROJECT_CLI_GUIDE.md](../PROJECT_CLI_GUIDE.md)
|
|
||||||
- **Version Bumping:** See [VERSION_BUMP_GUIDE.md](VERSION_BUMP_GUIDE.md)
|
|
||||||
- **Archived Workflows:** See [_archive/README.md](_archive/README.md)
|
|
||||||
270
.github/workflows/pr-checks.yml
vendored
270
.github/workflows/pr-checks.yml
vendored
|
|
@ -3,15 +3,218 @@ name: PR Checks
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main, dev]
|
branches: [main, dev]
|
||||||
paths:
|
types: [opened, edited, synchronize, reopened]
|
||||||
- 'evals/**'
|
|
||||||
- '.github/workflows/pr-checks.yml'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
pr-title-check:
|
||||||
|
name: Validate PR Title
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
title-valid: ${{ steps.validate.outputs.valid }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check PR title format
|
||||||
|
id: validate
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const prTitle = context.payload.pull_request.title;
|
||||||
|
|
||||||
|
// Conventional commit patterns
|
||||||
|
const patterns = {
|
||||||
|
feat: /^feat(\(.+\))?!?:\s.+/,
|
||||||
|
fix: /^fix(\(.+\))?!?:\s.+/,
|
||||||
|
docs: /^docs(\(.+\))?:\s.+/,
|
||||||
|
style: /^style(\(.+\))?:\s.+/,
|
||||||
|
refactor: /^refactor(\(.+\))?:\s.+/,
|
||||||
|
perf: /^perf(\(.+\))?:\s.+/,
|
||||||
|
test: /^test(\(.+\))?:\s.+/,
|
||||||
|
chore: /^chore(\(.+\))?:\s.+/,
|
||||||
|
ci: /^ci(\(.+\))?:\s.+/,
|
||||||
|
build: /^build(\(.+\))?:\s.+/,
|
||||||
|
revert: /^revert(\(.+\))?:\s.+/,
|
||||||
|
alpha: /^\[alpha\]\s.+/,
|
||||||
|
beta: /^\[beta\]\s.+/,
|
||||||
|
rc: /^\[rc\]\s.+/
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if title matches any pattern
|
||||||
|
const matchedType = Object.entries(patterns).find(([type, pattern]) =>
|
||||||
|
pattern.test(prTitle)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!matchedType) {
|
||||||
|
const validExamples = [
|
||||||
|
'✅ feat(evals): add new evaluator',
|
||||||
|
'✅ fix(agents): correct delegation logic',
|
||||||
|
'✅ docs(readme): update installation guide',
|
||||||
|
'✅ test(evals): add execution-balance tests',
|
||||||
|
'✅ chore(deps): update dependencies',
|
||||||
|
'✅ feat!: breaking API change',
|
||||||
|
'✅ [alpha] experimental feature'
|
||||||
|
];
|
||||||
|
|
||||||
|
const message = `
|
||||||
|
## ❌ Invalid PR Title Format
|
||||||
|
|
||||||
|
**Current title:** \`${prTitle}\`
|
||||||
|
|
||||||
|
### Required Format
|
||||||
|
PR titles must follow [Conventional Commits](https://www.conventionalcommits.org/) format:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
<type>(<scope>): <description>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Valid Types
|
||||||
|
- **feat** - New feature (triggers minor version bump: 0.3.0 → 0.4.0)
|
||||||
|
- **fix** - Bug fix (triggers patch version bump: 0.3.0 → 0.3.1)
|
||||||
|
- **docs** - Documentation changes (triggers patch bump)
|
||||||
|
- **test** - Test additions/changes (triggers patch bump)
|
||||||
|
- **refactor** - Code refactoring (triggers patch bump)
|
||||||
|
- **chore** - Maintenance tasks (triggers patch bump)
|
||||||
|
- **ci** - CI/CD changes (triggers patch bump)
|
||||||
|
- **perf** - Performance improvements (triggers patch bump)
|
||||||
|
- **style** - Code style changes (triggers patch bump)
|
||||||
|
- **build** - Build system changes (triggers patch bump)
|
||||||
|
- **revert** - Revert previous commit (triggers patch bump)
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
- **feat!:** or **fix!:** - Breaking change (triggers major version bump: 0.3.0 → 1.0.0)
|
||||||
|
- **BREAKING CHANGE:** in description
|
||||||
|
|
||||||
|
### Pre-release Tags
|
||||||
|
- **[alpha]** - Alpha release (0.3.0 → 0.3.1-alpha.1)
|
||||||
|
- **[beta]** - Beta release (0.3.0 → 0.3.1-beta.1)
|
||||||
|
- **[rc]** - Release candidate (0.3.0 → 0.3.1-rc.1)
|
||||||
|
|
||||||
|
### Valid Examples
|
||||||
|
${validExamples.map(ex => `- ${ex}`).join('\n')}
|
||||||
|
|
||||||
|
### Why This Matters
|
||||||
|
- ✅ Enables automatic semantic versioning
|
||||||
|
- ✅ Generates meaningful changelogs
|
||||||
|
- ✅ Makes commit history searchable
|
||||||
|
- ✅ Clarifies the impact of changes
|
||||||
|
|
||||||
|
### How to Fix
|
||||||
|
Edit your PR title to match the format above.
|
||||||
|
`;
|
||||||
|
|
||||||
|
core.setFailed(message);
|
||||||
|
|
||||||
|
// Also post as a comment
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: context.payload.pull_request.number,
|
||||||
|
body: message
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const [type] = matchedType;
|
||||||
|
let versionBump = 'patch (0.3.0 → 0.3.1)';
|
||||||
|
|
||||||
|
if (type === 'feat' && prTitle.includes('!')) {
|
||||||
|
versionBump = 'major (0.3.0 → 1.0.0) - BREAKING CHANGE';
|
||||||
|
} else if (type === 'feat') {
|
||||||
|
versionBump = 'minor (0.3.0 → 0.4.0)';
|
||||||
|
} else if (type === 'fix' && prTitle.includes('!')) {
|
||||||
|
versionBump = 'major (0.3.0 → 1.0.0) - BREAKING CHANGE';
|
||||||
|
} else if (type === 'alpha') {
|
||||||
|
versionBump = 'alpha (0.3.0 → 0.3.1-alpha.1)';
|
||||||
|
} else if (type === 'beta') {
|
||||||
|
versionBump = 'beta (0.3.0 → 0.3.1-beta.1)';
|
||||||
|
} else if (type === 'rc') {
|
||||||
|
versionBump = 'rc (0.3.0 → 0.3.1-rc.1)';
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = `
|
||||||
|
## ✅ PR Title Valid
|
||||||
|
|
||||||
|
**Title:** \`${prTitle}\`
|
||||||
|
**Type:** \`${type}\`
|
||||||
|
**Version bump:** ${versionBump}
|
||||||
|
|
||||||
|
When this PR is merged using **"Squash and Merge"**, the version will be automatically bumped.
|
||||||
|
`;
|
||||||
|
|
||||||
|
core.info(message);
|
||||||
|
|
||||||
|
// Set output for summary
|
||||||
|
core.summary
|
||||||
|
.addHeading('✅ PR Title Validation Passed', 2)
|
||||||
|
.addRaw(`**Title:** \`${prTitle}\``)
|
||||||
|
.addBreak()
|
||||||
|
.addRaw(`**Type:** \`${type}\``)
|
||||||
|
.addBreak()
|
||||||
|
.addRaw(`**Version bump:** ${versionBump}`)
|
||||||
|
.write();
|
||||||
|
|
||||||
|
// Set output for dependent jobs
|
||||||
|
core.setOutput('valid', 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
check-changes:
|
||||||
|
name: Detect Changed Files
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: pr-title-check
|
||||||
|
if: needs.pr-title-check.outputs.title-valid == 'true'
|
||||||
|
outputs:
|
||||||
|
has-evals: ${{ steps.filter.outputs.evals }}
|
||||||
|
has-docs: ${{ steps.filter.outputs.docs }}
|
||||||
|
has-workflows: ${{ steps.filter.outputs.workflows }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Check changed files
|
||||||
|
id: filter
|
||||||
|
run: |
|
||||||
|
# Get list of changed files
|
||||||
|
git fetch origin ${{ github.base_ref }}
|
||||||
|
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
|
||||||
|
|
||||||
|
echo "Changed files:"
|
||||||
|
echo "$CHANGED_FILES"
|
||||||
|
|
||||||
|
# Check for evals changes
|
||||||
|
if echo "$CHANGED_FILES" | grep -q "^evals/"; then
|
||||||
|
echo "has-evals=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✅ Evals changes detected"
|
||||||
|
else
|
||||||
|
echo "has-evals=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "ℹ️ No evals changes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for docs changes
|
||||||
|
if echo "$CHANGED_FILES" | grep -q "^docs/"; then
|
||||||
|
echo "has-docs=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✅ Docs changes detected"
|
||||||
|
else
|
||||||
|
echo "has-docs=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "ℹ️ No docs changes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for workflow changes
|
||||||
|
if echo "$CHANGED_FILES" | grep -q "^.github/workflows/"; then
|
||||||
|
echo "has-workflows=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✅ Workflow changes detected"
|
||||||
|
else
|
||||||
|
echo "has-workflows=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "ℹ️ No workflow changes"
|
||||||
|
fi
|
||||||
|
|
||||||
build-check:
|
build-check:
|
||||||
name: Build & Validate
|
name: Build & Validate
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
|
needs: [pr-title-check, check-changes]
|
||||||
|
if: |
|
||||||
|
needs.pr-title-check.outputs.title-valid == 'true' &&
|
||||||
|
needs.check-changes.outputs.has-evals == 'true'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
|
|
@ -57,3 +260,64 @@ jobs:
|
||||||
echo "**Common fixes:**" >> $GITHUB_STEP_SUMMARY
|
echo "**Common fixes:**" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- TypeScript errors: Fix type issues in \`evals/framework/src/\`" >> $GITHUB_STEP_SUMMARY
|
echo "- TypeScript errors: Fix type issues in \`evals/framework/src/\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- YAML validation: Check test files in \`evals/agents/*/tests/\`" >> $GITHUB_STEP_SUMMARY
|
echo "- YAML validation: Check test files in \`evals/agents/*/tests/\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
summary:
|
||||||
|
name: PR Checks Summary
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [pr-title-check, check-changes, build-check]
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Generate summary
|
||||||
|
run: |
|
||||||
|
echo "## 📊 PR Checks Summary" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# PR Title Check
|
||||||
|
if [ "${{ needs.pr-title-check.result }}" == "success" ]; then
|
||||||
|
echo "✅ **PR Title:** Valid conventional commit format" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "❌ **PR Title:** Invalid format - please fix" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Changed Files Detection
|
||||||
|
if [ "${{ needs.check-changes.result }}" == "success" ]; then
|
||||||
|
echo "✅ **Changed Files:** Detected successfully" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ "${{ needs.check-changes.outputs.has-evals }}" == "true" ]; then
|
||||||
|
echo " - 📦 Evals changes detected" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.check-changes.outputs.has-docs }}" == "true" ]; then
|
||||||
|
echo " - 📚 Docs changes detected" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.check-changes.outputs.has-workflows }}" == "true" ]; then
|
||||||
|
echo " - ⚙️ Workflow changes detected" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⏭️ **Changed Files:** Skipped (title validation failed)" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build Check
|
||||||
|
if [ "${{ needs.build-check.result }}" == "success" ]; then
|
||||||
|
echo "✅ **Build & Validate:** Passed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
elif [ "${{ needs.build-check.result }}" == "skipped" ]; then
|
||||||
|
echo "⏭️ **Build & Validate:** Skipped (no evals changes)" >> $GITHUB_STEP_SUMMARY
|
||||||
|
elif [ "${{ needs.build-check.result }}" == "failure" ]; then
|
||||||
|
echo "❌ **Build & Validate:** Failed - check logs" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# Overall status
|
||||||
|
if [ "${{ needs.pr-title-check.result }}" == "success" ] && \
|
||||||
|
([ "${{ needs.build-check.result }}" == "success" ] || [ "${{ needs.build-check.result }}" == "skipped" ]); then
|
||||||
|
echo "### ✅ All Required Checks Passed!" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "This PR is ready for review." >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "### ❌ Some Checks Failed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "Please fix the failing checks before merging." >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
|
||||||
24
.github/workflows/validate-registry.yml
vendored
24
.github/workflows/validate-registry.yml
vendored
|
|
@ -88,31 +88,33 @@ jobs:
|
||||||
|
|
||||||
./scripts/registry/auto-detect-components.sh --auto-add | tee -a $GITHUB_STEP_SUMMARY
|
./scripts/registry/auto-detect-components.sh --auto-add | tee -a $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
- name: Validate prompts use defaults
|
- name: Validate prompt library structure
|
||||||
id: validate_prompts
|
id: validate_prompts
|
||||||
run: |
|
run: |
|
||||||
echo "## 🔍 Prompt Validation" >> $GITHUB_STEP_SUMMARY
|
echo "## 🔍 Prompt Library Validation" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
if ./scripts/prompts/validate-pr.sh > /tmp/prompt-validation.txt 2>&1; then
|
if ./scripts/prompts/validate-pr.sh > /tmp/prompt-validation.txt 2>&1; then
|
||||||
echo "prompt_validation=passed" >> $GITHUB_OUTPUT
|
echo "prompt_validation=passed" >> $GITHUB_OUTPUT
|
||||||
echo "✅ All agents use default prompts!" >> $GITHUB_STEP_SUMMARY
|
echo "✅ Prompt library structure is valid!" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
cat /tmp/prompt-validation.txt >> $GITHUB_STEP_SUMMARY
|
cat /tmp/prompt-validation.txt >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "prompt_validation=failed" >> $GITHUB_OUTPUT
|
echo "prompt_validation=failed" >> $GITHUB_OUTPUT
|
||||||
echo "❌ Prompt validation failed!" >> $GITHUB_STEP_SUMMARY
|
echo "❌ Prompt library validation failed!" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
cat /tmp/prompt-validation.txt >> $GITHUB_STEP_SUMMARY
|
cat /tmp/prompt-validation.txt >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**How to fix:**" >> $GITHUB_STEP_SUMMARY
|
echo "**Architecture:**" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "1. Restore defaults: \`./scripts/prompts/use-prompt.sh <agent> default\`" >> $GITHUB_STEP_SUMMARY
|
echo "- Agent files (.opencode/agent/*.md) = Canonical defaults" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "2. If adding a variant, add it to \`.opencode/prompts/<agent>/\` instead" >> $GITHUB_STEP_SUMMARY
|
echo "- Prompt variants (.opencode/prompts/<agent>/<model>.md) = Model-specific" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "3. See [CONTRIBUTING.md](docs/contributing/CONTRIBUTING.md) for details" >> $GITHUB_STEP_SUMMARY
|
echo "- default.md files should NOT exist" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "See [CONTRIBUTING.md](docs/contributing/CONTRIBUTING.md) for details" >> $GITHUB_STEP_SUMMARY
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -223,7 +225,7 @@ jobs:
|
||||||
if [ "$PROMPT_VALID" = "passed" ] && [ "$REGISTRY_VALID" = "passed" ]; then
|
if [ "$PROMPT_VALID" = "passed" ] && [ "$REGISTRY_VALID" = "passed" ]; then
|
||||||
echo "### ✅ All Validations Passed" >> $GITHUB_STEP_SUMMARY
|
echo "### ✅ All Validations Passed" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- ✅ Prompts use defaults" >> $GITHUB_STEP_SUMMARY
|
echo "- ✅ Prompt library structure is valid" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- ✅ Registry paths are valid" >> $GITHUB_STEP_SUMMARY
|
echo "- ✅ Registry paths are valid" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "This PR is ready for review!" >> $GITHUB_STEP_SUMMARY
|
echo "This PR is ready for review!" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
@ -232,9 +234,9 @@ jobs:
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
if [ "$PROMPT_VALID" != "passed" ]; then
|
if [ "$PROMPT_VALID" != "passed" ]; then
|
||||||
echo "- ❌ Prompt validation failed" >> $GITHUB_STEP_SUMMARY
|
echo "- ❌ Prompt library validation failed" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "- ✅ Prompt validation passed" >> $GITHUB_STEP_SUMMARY
|
echo "- ✅ Prompt library validation passed" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$REGISTRY_VALID" != "passed" ]; then
|
if [ "$REGISTRY_VALID" != "passed" ]; then
|
||||||
|
|
|
||||||
3
.github/workflows/validate-test-suites.yml
vendored
3
.github/workflows/validate-test-suites.yml
vendored
|
|
@ -29,11 +29,10 @@ jobs:
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: '20'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: 'evals/framework/package-lock.json'
|
cache-dependency-path: 'package-lock.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
cd evals/framework
|
|
||||||
npm ci
|
npm ci
|
||||||
|
|
||||||
- name: Validate all test suites
|
- name: Validate all test suites
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,40 @@ status: "stable"
|
||||||
# Development Agent
|
# Development Agent
|
||||||
Always start with phrase "DIGGING IN..."
|
Always start with phrase "DIGGING IN..."
|
||||||
|
|
||||||
|
<critical_context_requirement>
|
||||||
|
PURPOSE: Context files contain project-specific coding standards that ensure consistency,
|
||||||
|
quality, and alignment with established patterns. Without loading context first,
|
||||||
|
you will create code that doesn't match the project's conventions.
|
||||||
|
|
||||||
|
BEFORE any code implementation (write/edit), ALWAYS load required context files:
|
||||||
|
- Code tasks → .opencode/context/core/standards/code.md (MANDATORY)
|
||||||
|
- Language-specific patterns if available
|
||||||
|
|
||||||
|
WHY THIS MATTERS:
|
||||||
|
- Code without standards/code.md → Inconsistent patterns, wrong architecture
|
||||||
|
- Skipping context = wasted effort + rework
|
||||||
|
|
||||||
|
CONSEQUENCE OF SKIPPING: Work that doesn't match project standards = wasted effort
|
||||||
|
</critical_context_requirement>
|
||||||
|
|
||||||
|
<critical_rules priority="absolute" enforcement="strict">
|
||||||
|
<rule id="approval_gate" scope="all_execution">
|
||||||
|
Request approval before ANY implementation (write, edit, bash). Read/list/glob/grep for discovery don't require approval.
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule id="stop_on_failure" scope="validation">
|
||||||
|
STOP on test fail/build errors - NEVER auto-fix without approval
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule id="report_first" scope="error_handling">
|
||||||
|
On fail: REPORT error → PROPOSE fix → REQUEST APPROVAL → Then fix (never auto-fix)
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule id="incremental_execution" scope="implementation">
|
||||||
|
Implement ONE step at a time, validate each step before proceeding
|
||||||
|
</rule>
|
||||||
|
</critical_rules>
|
||||||
|
|
||||||
## Available Subagents (invoke via task tool)
|
## Available Subagents (invoke via task tool)
|
||||||
|
|
||||||
- `subagents/core/task-manager` - Feature breakdown (4+ files, >60 min)
|
- `subagents/core/task-manager` - Feature breakdown (4+ files, >60 min)
|
||||||
|
|
@ -84,57 +118,109 @@ Code Standards
|
||||||
- Prefer declarative over imperative patterns
|
- Prefer declarative over imperative patterns
|
||||||
- Use proper type systems when available
|
- Use proper type systems when available
|
||||||
|
|
||||||
Subtask Strategy
|
<delegation_rules>
|
||||||
|
<delegate_when>
|
||||||
|
<condition id="scale" trigger="4_plus_files" action="delegate_to_task_manager">
|
||||||
|
When feature spans 4+ files OR estimated >60 minutes
|
||||||
|
</condition>
|
||||||
|
<condition id="simple_task" trigger="focused_implementation" action="delegate_to_coder_agent">
|
||||||
|
For simple, focused implementations to save time
|
||||||
|
</condition>
|
||||||
|
</delegate_when>
|
||||||
|
|
||||||
- When a feature spans multiple modules or is estimated > 60 minutes, delegate planning to `subagents/core/task-manager` to generate atomic subtasks under `tasks/subtasks/{feature}/` using the `{sequence}-{task-description}.md` pattern and a feature `README.md` index.
|
<execute_directly_when>
|
||||||
- After subtask creation, implement strictly one subtask at a time; update the feature index status between tasks.
|
<condition trigger="single_file_simple_change">1-3 files, straightforward implementation</condition>
|
||||||
|
</execute_directly_when>
|
||||||
|
</delegation_rules>
|
||||||
|
|
||||||
Mandatory Workflow
|
<workflow>
|
||||||
Phase 1: Planning (REQUIRED)
|
<stage id="1" name="Analyze" required="true">
|
||||||
|
Assess task complexity, scope, and delegation criteria
|
||||||
|
</stage>
|
||||||
|
|
||||||
Once planning is done, we should make tasks for the plan once plan is approved.
|
<stage id="2" name="Plan" required="true" enforce="@approval_gate">
|
||||||
So pass it to the `subagents/core/task-manager` to make tasks for the plan.
|
Create step-by-step implementation plan
|
||||||
|
Present plan to user
|
||||||
|
Request approval BEFORE any implementation
|
||||||
|
|
||||||
ALWAYS propose a concise step-by-step implementation plan FIRST
|
<format>
|
||||||
Ask for user approval before any implementation
|
## Implementation Plan
|
||||||
Do NOT proceed without explicit approval
|
|
||||||
|
|
||||||
Phase 2: Implementation (After Approval Only)
|
|
||||||
|
|
||||||
Implement incrementally - complete one step at a time, never implement the entire plan at once
|
|
||||||
After each increment:
|
|
||||||
- Use appropriate runtime for the language (node/bun for TypeScript/JavaScript, python for Python, go run for Go, cargo run for Rust)
|
|
||||||
- Run type checks if applicable (tsc for TypeScript, mypy for Python, go build for Go, cargo check for Rust)
|
|
||||||
- Run linting if configured (eslint, pylint, golangci-lint, clippy)
|
|
||||||
- Run build checks
|
|
||||||
- Execute relevant tests
|
|
||||||
|
|
||||||
For simple tasks, use the `subagents/code/coder-agent` to implement the code to save time.
|
|
||||||
|
|
||||||
Use Test-Driven Development when tests/ directory is available
|
|
||||||
Request approval before executing any risky bash commands
|
|
||||||
|
|
||||||
Phase 3: Completion
|
|
||||||
When implementation is complete and user approves final result:
|
|
||||||
|
|
||||||
Emit handoff recommendations for `subagents/code/tester` and `subagents/core/documentation` agents
|
|
||||||
|
|
||||||
Response Format
|
|
||||||
For planning phase:
|
|
||||||
Copy## Implementation Plan
|
|
||||||
[Step-by-step breakdown]
|
[Step-by-step breakdown]
|
||||||
|
|
||||||
|
**Estimated:** [time/complexity]
|
||||||
|
**Files affected:** [count]
|
||||||
**Approval needed before proceeding. Please review and confirm.**
|
**Approval needed before proceeding. Please review and confirm.**
|
||||||
For implementation phase:
|
</format>
|
||||||
Copy## Implementing Step [X]: [Description]
|
</stage>
|
||||||
|
|
||||||
|
<stage id="3" name="LoadContext" required="true" enforce="@critical_context_requirement">
|
||||||
|
BEFORE implementation, load required context:
|
||||||
|
- Code tasks → Read .opencode/context/core/standards/code.md NOW
|
||||||
|
- Apply standards to implementation
|
||||||
|
|
||||||
|
<checkpoint>Context file loaded OR confirmed not needed (bash-only tasks)</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="4" name="Execute" when="approved" enforce="@incremental_execution">
|
||||||
|
Implement ONE step at a time (never all at once)
|
||||||
|
|
||||||
|
After each increment:
|
||||||
|
- Use appropriate runtime (node/bun for TS/JS, python, go run, cargo run)
|
||||||
|
- Run type checks if applicable (tsc, mypy, go build, cargo check)
|
||||||
|
- Run linting if configured (eslint, pylint, golangci-lint, clippy)
|
||||||
|
- Run build checks
|
||||||
|
- Execute relevant tests
|
||||||
|
|
||||||
|
For simple tasks, optionally delegate to `subagents/code/coder-agent`
|
||||||
|
Use Test-Driven Development when tests/ directory is available
|
||||||
|
|
||||||
|
<format>
|
||||||
|
## Implementing Step [X]: [Description]
|
||||||
[Code implementation]
|
[Code implementation]
|
||||||
[Build/test results]
|
[Validation results: type check ✓, lint ✓, tests ✓]
|
||||||
|
|
||||||
**Ready for next step or feedback**
|
**Ready for next step or feedback**
|
||||||
Remember: Plan first, get approval, then implement one step at a time. Never implement everything at once.
|
</format>
|
||||||
Handoff:
|
</stage>
|
||||||
Once completed the plan and user is happy with final result then:
|
|
||||||
- Emit follow-ups for `subagents/code/tester` to run tests and find any issues.
|
<stage id="5" name="Validate" enforce="@stop_on_failure">
|
||||||
- Update the Task you just completed and mark the completed sections in the task as done with a checkmark.
|
Check quality → Verify complete → Test if applicable
|
||||||
|
|
||||||
|
<on_failure enforce="@report_first">
|
||||||
|
STOP → Report error → Propose fix → Request approval → Fix → Re-validate
|
||||||
|
NEVER auto-fix without approval
|
||||||
|
</on_failure>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="6" name="Handoff" when="complete">
|
||||||
|
When implementation complete and user approves:
|
||||||
|
|
||||||
|
Emit handoff recommendations:
|
||||||
|
- `subagents/code/tester` - For comprehensive test coverage
|
||||||
|
- `subagents/core/documentation` - For documentation generation
|
||||||
|
|
||||||
|
Update task status and mark completed sections with checkmarks
|
||||||
|
</stage>
|
||||||
|
</workflow>
|
||||||
|
|
||||||
|
<execution_philosophy>
|
||||||
|
Development specialist with strict quality gates and context awareness.
|
||||||
|
|
||||||
|
**Approach**: Plan → Approve → Load Context → Execute Incrementally → Validate → Handoff
|
||||||
|
**Mindset**: Quality over speed, consistency over convenience
|
||||||
|
**Safety**: Context loading, approval gates, stop on failure, incremental execution
|
||||||
|
</execution_philosophy>
|
||||||
|
|
||||||
|
<constraints enforcement="absolute">
|
||||||
|
These constraints override all other considerations:
|
||||||
|
|
||||||
|
1. NEVER execute write/edit without loading required context first
|
||||||
|
2. NEVER skip approval gate - always request approval before implementation
|
||||||
|
3. NEVER auto-fix errors - always report first and request approval
|
||||||
|
4. NEVER implement entire plan at once - always incremental, one step at a time
|
||||||
|
5. ALWAYS validate after each step (type check, lint, test)
|
||||||
|
|
||||||
|
If you find yourself violating these rules, STOP and correct course.
|
||||||
|
</constraints>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
381
.opencode/command/openagents/new-agents/README.md
Normal file
381
.opencode/command/openagents/new-agents/README.md
Normal file
|
|
@ -0,0 +1,381 @@
|
||||||
|
# New Agent Creation System
|
||||||
|
|
||||||
|
**Research-backed agent creation following Anthropic 2025 best practices**
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This command system helps you create production-ready OpenCode agents with:
|
||||||
|
- ✅ **Minimal prompts** (~500 tokens at "right altitude")
|
||||||
|
- ✅ **Single agent + tools** (not multi-agent for coding)
|
||||||
|
- ✅ **Just-in-time context** (loaded on demand, not pre-loaded)
|
||||||
|
- ✅ **Clear tool definitions** (purpose, when to use, when not to use)
|
||||||
|
- ✅ **Comprehensive testing** (8 essential test types)
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Create a New Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Interactive agent creation
|
||||||
|
/create-agent my-agent-name
|
||||||
|
|
||||||
|
# Or specify in prompt
|
||||||
|
"Create a new agent called 'python-dev' for Python development"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generate Test Suite
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate 8 comprehensive tests for existing agent
|
||||||
|
/create-tests my-agent-name
|
||||||
|
```
|
||||||
|
|
||||||
|
## Research-Backed Principles
|
||||||
|
|
||||||
|
### 1. Single Agent + Tools > Multi-Agent for Coding
|
||||||
|
|
||||||
|
**Finding**: "Most coding tasks involve fewer truly parallelizable tasks than research" (Anthropic 2025)
|
||||||
|
|
||||||
|
**Why this matters**:
|
||||||
|
- Code changes are deeply dependent on each other
|
||||||
|
- Sub-agents can't coordinate edits to the same file
|
||||||
|
- Agents waste time duplicating work
|
||||||
|
- Multi-agent excels at research (90.2% improvement) because searches are independent
|
||||||
|
- Code is sequential
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Use ONE lead agent with tool-based sub-functions
|
||||||
|
- NOT autonomous sub-agents for coding
|
||||||
|
- Multi-agent only for truly independent tasks:
|
||||||
|
- Static analysis (no coordination needed)
|
||||||
|
- Test execution
|
||||||
|
- Code search/retrieval
|
||||||
|
- NOT for: refactoring, architecture decisions, multi-file changes
|
||||||
|
|
||||||
|
### 2. Right Altitude: Minimal Prompts
|
||||||
|
|
||||||
|
**Finding**: "Find the smallest possible set of high-signal tokens that maximize likelihood of desired outcome"
|
||||||
|
|
||||||
|
**The Balance**:
|
||||||
|
| Too Vague | Right Altitude ✅ | Too Rigid |
|
||||||
|
|-----------|------------------|-----------|
|
||||||
|
| "Write good code" | Clear heuristics + examples | 50-line prompt with edge cases |
|
||||||
|
| Fails to guide behavior | Flexible but specific | Brittle, hard to maintain |
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- System prompt: Minimal (~500 tokens)
|
||||||
|
- Clear heuristics, not exhaustive rules
|
||||||
|
- Examples > edge case lists
|
||||||
|
- Show ONE canonical example, not 20 scenarios
|
||||||
|
|
||||||
|
### 3. Just-in-Time Context Loading
|
||||||
|
|
||||||
|
**Finding**: "Agents discover context layer by layer. File metadata guides behavior. Prevents drowning in irrelevant information"
|
||||||
|
|
||||||
|
**Context Management Layers**:
|
||||||
|
1. **System prompt**: Minimal (~500 tokens). Clear heuristics, not exhaustive rules.
|
||||||
|
2. **Just-in-time retrieval**: Tools that agents call to load context on demand (file paths, not full content)
|
||||||
|
3. **Working memory**: Keep only what's needed for the current task
|
||||||
|
|
||||||
|
**Why this beats pre-loading**:
|
||||||
|
- Agents discover context layer by layer
|
||||||
|
- File metadata (size, name, timestamps) guide behavior
|
||||||
|
- Prevents "drowning in irrelevant information"
|
||||||
|
|
||||||
|
### 4. CLAUDE.md Pattern
|
||||||
|
|
||||||
|
**Finding**: Anthropic's Claude Code uses this in production
|
||||||
|
|
||||||
|
**Create a project context file** automatically loaded into every session:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Project Context
|
||||||
|
|
||||||
|
## Bash Commands
|
||||||
|
- npm run test: Run unit tests
|
||||||
|
- npm run lint: Check code style
|
||||||
|
- npm run typecheck: Check TypeScript
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
- Use ES modules (import/export)
|
||||||
|
- Destructure imports when possible
|
||||||
|
- Use async/await, not callbacks
|
||||||
|
|
||||||
|
## Common Files & Patterns
|
||||||
|
- API handlers in src/handlers/
|
||||||
|
- Business logic in src/logic/
|
||||||
|
- Tests mirror source structure
|
||||||
|
|
||||||
|
## Workflow Rules
|
||||||
|
- Always run typecheck before committing
|
||||||
|
- Don't modify test files when writing implementation
|
||||||
|
- Use git history to understand WHY, not WHAT
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits**:
|
||||||
|
- Eliminates repetitive context-loading
|
||||||
|
- Shared across team (check into git)
|
||||||
|
- Tuned like any prompt (run through prompt improvers)
|
||||||
|
|
||||||
|
### 5. Tool Clarity
|
||||||
|
|
||||||
|
**Finding**: "Tool ambiguity is one of the biggest failure modes"
|
||||||
|
|
||||||
|
**Bad tool design**:
|
||||||
|
```markdown
|
||||||
|
tool: "search_code"
|
||||||
|
description: "search code" # Ambiguous!
|
||||||
|
```
|
||||||
|
|
||||||
|
**Good tool design**:
|
||||||
|
```markdown
|
||||||
|
tool: "read_file"
|
||||||
|
purpose: "Load a specific file for analysis or modification"
|
||||||
|
when_to_use: "You need to examine or edit a file"
|
||||||
|
when_not_to_use: "You already have the file content in context"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key principle**: If a human engineer can't definitively say which tool to use, neither can the agent.
|
||||||
|
|
||||||
|
### 6. Extended Thinking for Decomposition
|
||||||
|
|
||||||
|
**Finding**: "Improved instruction-following and reasoning efficiency for complex decomposition"
|
||||||
|
|
||||||
|
**Before jumping to code, trigger extended thinking**:
|
||||||
|
```
|
||||||
|
"Think about how to approach this problem. What files need to change?
|
||||||
|
What are the dependencies? What should we test?"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phrases mapped to thinking budget**:
|
||||||
|
- "think" = basic
|
||||||
|
- "think hard" = 2x budget
|
||||||
|
- "think harder" = 3x budget
|
||||||
|
- "ultrathink" = maximum
|
||||||
|
|
||||||
|
### 7. Parallel Tool Calling
|
||||||
|
|
||||||
|
**Finding**: "Parallel tool calling cut research time by up to 90% for complex queries"
|
||||||
|
|
||||||
|
**Design workflows where agent can call multiple tools simultaneously**:
|
||||||
|
|
||||||
|
**Can do in parallel**:
|
||||||
|
- Run linter
|
||||||
|
- Execute tests
|
||||||
|
- Check type errors
|
||||||
|
|
||||||
|
**NOT in parallel** (sequential):
|
||||||
|
- Apply fix, then test
|
||||||
|
|
||||||
|
### 8. Outcome-Focused Evaluation
|
||||||
|
|
||||||
|
**Finding**: "Token usage explains 80% of performance variance. Number of tool calls ~10%. Model choice ~10%"
|
||||||
|
|
||||||
|
**What to measure**:
|
||||||
|
- ✅ Does it solve the task?
|
||||||
|
- ✅ Token usage reasonable?
|
||||||
|
- ✅ Tool calls appropriate?
|
||||||
|
- ❌ NOT: "Did it follow exact steps I imagined?"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Optimize for using enough tokens to solve the problem
|
||||||
|
- Don't minimize tool calls (some redundancy is fine)
|
||||||
|
- Evaluate on real failure cases, not synthetic tests
|
||||||
|
|
||||||
|
## Agent Structure
|
||||||
|
|
||||||
|
### Minimal System Prompt Template (~500 tokens)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
description: "{one-line purpose}"
|
||||||
|
mode: primary
|
||||||
|
temperature: 0.1-0.7
|
||||||
|
tools:
|
||||||
|
read: true
|
||||||
|
write: true
|
||||||
|
edit: true
|
||||||
|
bash: true
|
||||||
|
glob: true
|
||||||
|
grep: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# {Agent Name}
|
||||||
|
|
||||||
|
<role>
|
||||||
|
{Clear, concise role - what this agent does}
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<approach>
|
||||||
|
1. {First step - usually read/understand}
|
||||||
|
2. {Second step - usually think/plan}
|
||||||
|
3. {Third step - usually implement/execute}
|
||||||
|
4. {Fourth step - usually verify/test}
|
||||||
|
5. {Fifth step - usually complete/handoff}
|
||||||
|
</approach>
|
||||||
|
|
||||||
|
<heuristics>
|
||||||
|
- {Key heuristic 1 - how to approach problems}
|
||||||
|
- {Key heuristic 2 - when to use tools}
|
||||||
|
- {Key heuristic 3 - how to verify work}
|
||||||
|
- {Key heuristic 4 - when to stop/report}
|
||||||
|
</heuristics>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
Always include:
|
||||||
|
- What you did
|
||||||
|
- Why you did it that way
|
||||||
|
- {Domain-specific output requirement}
|
||||||
|
</output>
|
||||||
|
|
||||||
|
<examples>
|
||||||
|
<example name="{Canonical Use Case}">
|
||||||
|
**User**: "{typical request}"
|
||||||
|
|
||||||
|
**Agent**:
|
||||||
|
1. {Step 1 with tool usage}
|
||||||
|
2. {Step 2 with reasoning}
|
||||||
|
3. {Step 3 with output}
|
||||||
|
|
||||||
|
**Result**: {Expected outcome}
|
||||||
|
</example>
|
||||||
|
</examples>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Suite (8 Essential Tests)
|
||||||
|
|
||||||
|
Every agent gets 8 comprehensive tests:
|
||||||
|
|
||||||
|
1. **Planning & Approval** - Verify plan-first approach
|
||||||
|
2. **Context Loading** - Ensure just-in-time context retrieval
|
||||||
|
3. **Incremental Implementation** - Verify step-by-step execution
|
||||||
|
4. **Tool Usage** - Check correct tool selection and usage
|
||||||
|
5. **Error Handling** - Verify stop-on-failure behavior
|
||||||
|
6. **Extended Thinking** - Check decomposition before coding
|
||||||
|
7. **Compaction** - Verify summarization for long sessions
|
||||||
|
8. **Completion** - Check proper output and handoff
|
||||||
|
|
||||||
|
## What NOT to Do
|
||||||
|
|
||||||
|
Based on failure modes found in production:
|
||||||
|
|
||||||
|
**Don't**:
|
||||||
|
- ❌ Create sub-agents for dependent tasks (code is sequential)
|
||||||
|
- ❌ Pre-load entire codebase into context (use just-in-time retrieval)
|
||||||
|
- ❌ Write exhaustive edge case lists in prompts (brittle, hard to maintain)
|
||||||
|
- ❌ Give vague tool descriptions (major failure mode)
|
||||||
|
- ❌ Use multi-agent if you could use single agent + tools
|
||||||
|
- ❌ Hardcode complex logic in prompts (use tools instead)
|
||||||
|
- ❌ Minimize tool calls (some redundancy is fine)
|
||||||
|
|
||||||
|
**Do**:
|
||||||
|
- ✅ Let agents discover context via tools
|
||||||
|
- ✅ Use examples instead of rules
|
||||||
|
- ✅ Keep system prompt minimal (~500 tokens)
|
||||||
|
- ✅ Be explicit about effort budgets ("3-5 tool calls, not 50")
|
||||||
|
- ✅ Evaluate on real failure cases, not synthetic tests
|
||||||
|
- ✅ Measure outcomes: Does it solve the task?
|
||||||
|
|
||||||
|
## Files Created
|
||||||
|
|
||||||
|
When you create a new agent, the system generates:
|
||||||
|
|
||||||
|
```
|
||||||
|
.opencode/agent/{agent-name}.md
|
||||||
|
└─ Minimal system prompt (~500 tokens)
|
||||||
|
|
||||||
|
.opencode/context/project/{agent-name}-context.md
|
||||||
|
└─ Project context (CLAUDE.md pattern)
|
||||||
|
|
||||||
|
evals/agents/{agent-name}/
|
||||||
|
├─ config/
|
||||||
|
│ └─ config.yaml
|
||||||
|
└─ tests/
|
||||||
|
├─ planning/
|
||||||
|
│ └─ planning-approval-001.yaml
|
||||||
|
├─ context-loading/
|
||||||
|
│ └─ context-before-code-001.yaml
|
||||||
|
├─ implementation/
|
||||||
|
│ ├─ incremental-001.yaml
|
||||||
|
│ ├─ tool-usage-001.yaml
|
||||||
|
│ └─ extended-thinking-001.yaml
|
||||||
|
├─ error-handling/
|
||||||
|
│ └─ stop-on-failure-001.yaml
|
||||||
|
├─ long-horizon/
|
||||||
|
│ └─ compaction-001.yaml
|
||||||
|
└─ completion/
|
||||||
|
└─ handoff-001.yaml
|
||||||
|
|
||||||
|
registry.json (updated)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Example 1: Create Python Development Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
User: "Create a new agent for Python development with testing and linting"
|
||||||
|
|
||||||
|
System creates:
|
||||||
|
- Agent: python-dev
|
||||||
|
- System prompt: ~500 tokens
|
||||||
|
- Tools: read, write, edit, bash, glob, grep
|
||||||
|
- Context file: Python-specific commands and patterns
|
||||||
|
- 8 comprehensive tests
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Create API Testing Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
User: "Create an agent for API endpoint testing"
|
||||||
|
|
||||||
|
System creates:
|
||||||
|
- Agent: api-tester
|
||||||
|
- System prompt: ~500 tokens
|
||||||
|
- Tools: read, bash, glob, grep (no write/edit)
|
||||||
|
- Context file: API testing patterns and commands
|
||||||
|
- 8 comprehensive tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests for an agent
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent=my-agent-name
|
||||||
|
|
||||||
|
# Run specific category
|
||||||
|
npm test -- --agent=my-agent-name --category=planning
|
||||||
|
|
||||||
|
# Run single test
|
||||||
|
npm test -- --agent=my-agent-name --test=planning-approval-001
|
||||||
|
```
|
||||||
|
|
||||||
|
## Iteration and Improvement
|
||||||
|
|
||||||
|
1. **Test with real use cases** (not just synthetic tests)
|
||||||
|
2. **Measure outcomes**: Does it solve the task?
|
||||||
|
3. **Iterate based on actual failures** (not imagined edge cases)
|
||||||
|
4. **Update status** to "stable" when proven in production
|
||||||
|
|
||||||
|
## Research References
|
||||||
|
|
||||||
|
- **Anthropic Multi-Agent Research** (Sept-Dec 2025)
|
||||||
|
- Single agent + tools > multi-agent for coding
|
||||||
|
- Token usage explains 80% of performance variance
|
||||||
|
|
||||||
|
- **Context Engineering Best Practices** (Sept 2025)
|
||||||
|
- "Find the smallest possible set of high-signal tokens"
|
||||||
|
- Just-in-time retrieval beats pre-loading
|
||||||
|
|
||||||
|
- **Claude Code Production Patterns**
|
||||||
|
- CLAUDE.md pattern for project context
|
||||||
|
- Extended thinking for complex decomposition
|
||||||
|
- Compaction for long-horizon tasks
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For questions or issues:
|
||||||
|
1. Check existing agents: `.opencode/agent/opencoder.md`, `.opencode/agent/openagent.md`
|
||||||
|
2. Review test examples: `evals/agents/openagent/tests/`
|
||||||
|
3. See research docs: `docs/agents/research-backed-prompt-design.md`
|
||||||
479
.opencode/command/openagents/new-agents/create-agent.md
Normal file
479
.opencode/command/openagents/new-agents/create-agent.md
Normal file
|
|
@ -0,0 +1,479 @@
|
||||||
|
---
|
||||||
|
description: "Create new OpenCode agents following research-backed best practices (Anthropic 2025)"
|
||||||
|
---
|
||||||
|
|
||||||
|
# New Agent Creator
|
||||||
|
|
||||||
|
<agent_name> $ARGUMENTS </agent_name>
|
||||||
|
|
||||||
|
<role>
|
||||||
|
Agent creation specialist applying Anthropic's research-backed patterns for production-ready agents
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<task>
|
||||||
|
Create a new agent with minimal, high-signal prompts following "right altitude" principles - clear heuristics, not exhaustive rules
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<approach>
|
||||||
|
1. Gather agent requirements
|
||||||
|
2. Create minimal system prompt (~500 tokens)
|
||||||
|
3. Generate tool definitions with clear purpose
|
||||||
|
4. Create project context file (CLAUDE.md pattern)
|
||||||
|
5. Build comprehensive test suite (8 essential tests)
|
||||||
|
6. Register and validate
|
||||||
|
</approach>
|
||||||
|
|
||||||
|
<heuristics>
|
||||||
|
- **Single agent + tools > multi-agent** for coding tasks (Anthropic research: code is sequential, not parallelizable)
|
||||||
|
- **Minimal prompts at "right altitude"** - clear heuristics with examples, not edge case lists
|
||||||
|
- **Just-in-time context** - tools load context on demand, not pre-loaded
|
||||||
|
- **Examples > rules** - show one canonical example, not 20 scenarios
|
||||||
|
- **Measure outcomes** - does it solve the task? Not "did it follow exact steps?"
|
||||||
|
</heuristics>
|
||||||
|
|
||||||
|
<workflow>
|
||||||
|
<step_1 name="GatherRequirements">
|
||||||
|
Ask user for:
|
||||||
|
- Agent name (e.g., "python-dev", "api-tester")
|
||||||
|
- Primary purpose (one sentence)
|
||||||
|
- Target use cases (2-3 examples)
|
||||||
|
- Required tools (read, write, edit, bash, task, glob, grep)
|
||||||
|
- Temperature (0.1-0.3 for precise, 0.5-0.7 for creative)
|
||||||
|
- Will it delegate? (Use sparingly - only for truly independent tasks)
|
||||||
|
</step_1>
|
||||||
|
|
||||||
|
<step_2 name="CreateMinimalPrompt">
|
||||||
|
Create `.opencode/agent/{agent-name}.md` with ~500 token system prompt:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
description: "{one-line purpose}"
|
||||||
|
mode: primary
|
||||||
|
temperature: 0.1-0.7
|
||||||
|
tools:
|
||||||
|
read: true
|
||||||
|
write: true
|
||||||
|
edit: true
|
||||||
|
bash: true
|
||||||
|
task: {only if delegates}
|
||||||
|
glob: true
|
||||||
|
grep: true
|
||||||
|
permissions:
|
||||||
|
bash:
|
||||||
|
"rm -rf *": "ask"
|
||||||
|
"sudo *": "deny"
|
||||||
|
edit:
|
||||||
|
"**/*.env*": "deny"
|
||||||
|
"**/*.key": "deny"
|
||||||
|
---
|
||||||
|
|
||||||
|
# {Agent Name}
|
||||||
|
|
||||||
|
<role>
|
||||||
|
{Clear, concise role - what this agent does}
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<approach>
|
||||||
|
1. {First step - usually read/understand}
|
||||||
|
2. {Second step - usually think/plan}
|
||||||
|
3. {Third step - usually implement/execute}
|
||||||
|
4. {Fourth step - usually verify/test}
|
||||||
|
5. {Fifth step - usually complete/handoff}
|
||||||
|
</approach>
|
||||||
|
|
||||||
|
<heuristics>
|
||||||
|
- {Key heuristic 1 - how to approach problems}
|
||||||
|
- {Key heuristic 2 - when to use tools}
|
||||||
|
- {Key heuristic 3 - how to verify work}
|
||||||
|
- {Key heuristic 4 - when to stop/report}
|
||||||
|
</heuristics>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
Always include:
|
||||||
|
- What you did
|
||||||
|
- Why you did it that way
|
||||||
|
- {Domain-specific output requirement}
|
||||||
|
</output>
|
||||||
|
|
||||||
|
<examples>
|
||||||
|
<example name="{Canonical Use Case}">
|
||||||
|
**User**: "{typical request}"
|
||||||
|
|
||||||
|
**Agent**:
|
||||||
|
1. {Step 1 with tool usage}
|
||||||
|
2. {Step 2 with reasoning}
|
||||||
|
3. {Step 3 with output}
|
||||||
|
|
||||||
|
**Result**: {Expected outcome}
|
||||||
|
</example>
|
||||||
|
</examples>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key principles**:
|
||||||
|
- Keep system prompt minimal (~500 tokens)
|
||||||
|
- Use clear heuristics, not exhaustive rules
|
||||||
|
- Show ONE canonical example, not 20 scenarios
|
||||||
|
- Focus on "right altitude" - not too vague, not too rigid
|
||||||
|
</step_2>
|
||||||
|
|
||||||
|
<step_3 name="CreateToolDefinitions">
|
||||||
|
For each tool the agent uses, add clear definitions:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<tools>
|
||||||
|
<tool name="read_file">
|
||||||
|
<purpose>Load specific file for analysis or modification</purpose>
|
||||||
|
<when_to_use>You need to examine or edit a file</when_to_use>
|
||||||
|
<when_not_to_use>You already have the file content in context</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<tool name="run_tests">
|
||||||
|
<purpose>Execute test suite and report failures</purpose>
|
||||||
|
<when_to_use>After making code changes, before committing</when_to_use>
|
||||||
|
<when_not_to_use>No code changes made yet</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
</tools>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Research finding**: Tool ambiguity is a major failure mode. Be explicit about:
|
||||||
|
- Purpose of each tool
|
||||||
|
- When to use vs. when NOT to use
|
||||||
|
- Expected output format
|
||||||
|
</step_3>
|
||||||
|
|
||||||
|
<step_4 name="CreateProjectContext">
|
||||||
|
Create `.opencode/context/project/{agent-name}-context.md` (CLAUDE.md pattern):
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# {Agent Name} Context
|
||||||
|
|
||||||
|
## Key Commands
|
||||||
|
- {command 1}: {what it does}
|
||||||
|
- {command 2}: {what it does}
|
||||||
|
- {command 3}: {what it does}
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
- {path pattern}: {what goes here}
|
||||||
|
- {path pattern}: {what goes here}
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
- {style rule 1}
|
||||||
|
- {style rule 2}
|
||||||
|
- {style rule 3}
|
||||||
|
|
||||||
|
## Workflow Rules
|
||||||
|
- {workflow rule 1}
|
||||||
|
- {workflow rule 2}
|
||||||
|
- {workflow rule 3}
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
- {pattern 1}: {when to use}
|
||||||
|
- {pattern 2}: {when to use}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Research finding**: Single context file loaded on-demand beats pre-loading entire codebase.
|
||||||
|
This file:
|
||||||
|
- Eliminates repetitive context-loading
|
||||||
|
- Can be checked into git (shared across team)
|
||||||
|
- Tuned like any prompt (run through prompt improvers)
|
||||||
|
</step_4>
|
||||||
|
|
||||||
|
<step_5 name="CreateTestSuite">
|
||||||
|
Generate 8 comprehensive tests in `evals/agents/{agent-name}/tests/`:
|
||||||
|
|
||||||
|
**Test 1: Planning & Approval** (`planning/planning-approval-001.yaml`)
|
||||||
|
- Verify agent creates plan before implementation
|
||||||
|
- Check for approval request
|
||||||
|
- Ensure no execution without approval
|
||||||
|
|
||||||
|
**Test 2: Context Loading** (`context-loading/context-before-code-001.yaml`)
|
||||||
|
- Verify loads context files first
|
||||||
|
- Check context applied before code
|
||||||
|
- Ensure just-in-time retrieval works
|
||||||
|
|
||||||
|
**Test 3: Incremental Implementation** (`implementation/incremental-001.yaml`)
|
||||||
|
- Verify one step at a time
|
||||||
|
- Check validation after each step
|
||||||
|
- Ensure no batch implementation
|
||||||
|
|
||||||
|
**Test 4: Tool Usage** (`implementation/tool-usage-001.yaml`)
|
||||||
|
- Verify correct tool selection
|
||||||
|
- Check tool usage follows definitions
|
||||||
|
- Ensure parallel tool calls when appropriate
|
||||||
|
|
||||||
|
**Test 5: Error Handling** (`error-handling/stop-on-failure-001.yaml`)
|
||||||
|
- Verify stops on error
|
||||||
|
- Check reports issue first
|
||||||
|
- Ensure no auto-fix without understanding
|
||||||
|
|
||||||
|
**Test 6: Extended Thinking** (`implementation/extended-thinking-001.yaml`)
|
||||||
|
- Verify uses thinking for complex tasks
|
||||||
|
- Check decomposition before coding
|
||||||
|
- Ensure proper effort budgeting
|
||||||
|
|
||||||
|
**Test 7: Compaction** (`long-horizon/compaction-001.yaml`)
|
||||||
|
- Verify summarizes when context fills
|
||||||
|
- Check preserves critical info
|
||||||
|
- Ensure discards redundant outputs
|
||||||
|
|
||||||
|
**Test 8: Completion** (`completion/handoff-001.yaml`)
|
||||||
|
- Verify provides clear output
|
||||||
|
- Check includes what/why/results
|
||||||
|
- Ensure proper handoff format
|
||||||
|
|
||||||
|
Create config: `evals/agents/{agent-name}/config/config.yaml`
|
||||||
|
```yaml
|
||||||
|
agent: {agent-name}
|
||||||
|
description: {description}
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
timeout: 60000
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
testPaths:
|
||||||
|
- tests/planning
|
||||||
|
- tests/context-loading
|
||||||
|
- tests/implementation
|
||||||
|
- tests/error-handling
|
||||||
|
- tests/long-horizon
|
||||||
|
- tests/completion
|
||||||
|
|
||||||
|
expectations:
|
||||||
|
requiresTextApproval: true
|
||||||
|
usesToolPermissions: true
|
||||||
|
loadsContextOnDemand: true
|
||||||
|
```
|
||||||
|
</step_5>
|
||||||
|
|
||||||
|
<step_6 name="RegisterAndValidate">
|
||||||
|
1. Register in `registry.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "{agent-name}",
|
||||||
|
"type": "agent",
|
||||||
|
"path": ".opencode/agent/{agent-name}.md",
|
||||||
|
"description": "{description}",
|
||||||
|
"category": "primary",
|
||||||
|
"status": "experimental",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"maintainer": "{maintainer}",
|
||||||
|
"tested_with": "anthropic/claude-sonnet-4-5",
|
||||||
|
"last_tested": "{date}",
|
||||||
|
"tags": ["{tag1}", "{tag2}"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Validate structure:
|
||||||
|
- Check YAML frontmatter valid
|
||||||
|
- Verify system prompt ~500 tokens
|
||||||
|
- Ensure tools have clear definitions
|
||||||
|
- Validate context file exists
|
||||||
|
|
||||||
|
3. Run tests:
|
||||||
|
```bash
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent={agent-name}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Measure what matters:
|
||||||
|
- Does it solve the task? ✓
|
||||||
|
- Token usage reasonable? ✓
|
||||||
|
- Tool calls appropriate? ✓
|
||||||
|
- NOT: "Did it follow exact steps I imagined?"
|
||||||
|
</step_6>
|
||||||
|
|
||||||
|
<step_7 name="DeliverAgent">
|
||||||
|
Present complete package:
|
||||||
|
|
||||||
|
## ✅ Agent Created: {agent-name}
|
||||||
|
|
||||||
|
### Files Created
|
||||||
|
- `.opencode/agent/{agent-name}.md` - Minimal system prompt (~500 tokens)
|
||||||
|
- `.opencode/context/project/{agent-name}-context.md` - Project context (CLAUDE.md pattern)
|
||||||
|
- `evals/agents/{agent-name}/config/config.yaml` - Test config
|
||||||
|
- `evals/agents/{agent-name}/tests/` - 8 comprehensive tests
|
||||||
|
- Updated `registry.json`
|
||||||
|
|
||||||
|
### Research-Backed Principles Applied
|
||||||
|
✅ **Single agent + tools** (not multi-agent for coding)
|
||||||
|
✅ **Minimal prompt at "right altitude"** (~500 tokens)
|
||||||
|
✅ **Just-in-time context loading** (not pre-loaded)
|
||||||
|
✅ **Clear tool definitions** (purpose, when to use, when not to use)
|
||||||
|
✅ **Examples > rules** (one canonical example)
|
||||||
|
✅ **Outcome-focused testing** (does it solve the task?)
|
||||||
|
|
||||||
|
### Test Coverage
|
||||||
|
- ✅ Planning & Approval
|
||||||
|
- ✅ Context Loading
|
||||||
|
- ✅ Incremental Implementation
|
||||||
|
- ✅ Tool Usage
|
||||||
|
- ✅ Error Handling
|
||||||
|
- ✅ Extended Thinking
|
||||||
|
- ✅ Compaction
|
||||||
|
- ✅ Completion
|
||||||
|
|
||||||
|
**Total**: 8/8 tests
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
1. Test with real use cases
|
||||||
|
2. Measure: Does it solve the task?
|
||||||
|
3. Iterate based on actual failures (not synthetic tests)
|
||||||
|
4. Update status to "stable" when proven
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
```bash
|
||||||
|
# Use this agent
|
||||||
|
opencode --agent={agent-name}
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cd evals/framework && npm test -- --agent={agent-name}
|
||||||
|
```
|
||||||
|
</step_7>
|
||||||
|
</workflow>
|
||||||
|
|
||||||
|
<research_principles>
|
||||||
|
<single_agent_plus_tools>
|
||||||
|
**Finding**: "Most coding tasks involve fewer truly parallelizable tasks than research" (Anthropic 2025)
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Use ONE lead agent with tool-based sub-functions
|
||||||
|
- NOT autonomous sub-agents for coding
|
||||||
|
- Multi-agent only for truly independent tasks (static analysis, test execution, code search)
|
||||||
|
- Code changes are deeply dependent - sub-agents can't coordinate edits to same file
|
||||||
|
</single_agent_plus_tools>
|
||||||
|
|
||||||
|
<right_altitude>
|
||||||
|
**Finding**: "Find the smallest possible set of high-signal tokens that maximize likelihood of desired outcome"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- System prompt: Minimal (~500 tokens)
|
||||||
|
- Clear heuristics, not exhaustive rules
|
||||||
|
- Examples > edge case lists
|
||||||
|
- Show ONE canonical example, not 20 scenarios
|
||||||
|
|
||||||
|
**Balance**:
|
||||||
|
- Too vague: "Write good code" ❌
|
||||||
|
- Right altitude: Clear heuristics + examples ✅
|
||||||
|
- Too rigid: 50-line prompt with edge cases ❌
|
||||||
|
</right_altitude>
|
||||||
|
|
||||||
|
<just_in_time_context>
|
||||||
|
**Finding**: "Agents discover context layer by layer. File metadata guides behavior. Prevents drowning in irrelevant information"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Tools load context on demand (not pre-loaded)
|
||||||
|
- File metadata (size, name, timestamps) guide behavior
|
||||||
|
- Working memory: Keep only what's needed for current task
|
||||||
|
- CLAUDE.md pattern: Single context file loaded on-demand
|
||||||
|
</just_in_time_context>
|
||||||
|
|
||||||
|
<tool_clarity>
|
||||||
|
**Finding**: "Tool ambiguity is one of the biggest failure modes"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Explicit purpose for each tool
|
||||||
|
- When to use vs. when NOT to use
|
||||||
|
- Expected output format
|
||||||
|
- If human can't definitively say which tool to use, neither can agent
|
||||||
|
</tool_clarity>
|
||||||
|
|
||||||
|
<extended_thinking>
|
||||||
|
**Finding**: "Improved instruction-following and reasoning efficiency for complex decomposition"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Before jumping to code, trigger extended thinking
|
||||||
|
- "Think about how to approach this problem. What files need to change? What are the dependencies?"
|
||||||
|
- Phrases mapped to thinking budget:
|
||||||
|
- "think" = basic
|
||||||
|
- "think hard" = 2x budget
|
||||||
|
- "think harder" = 3x budget
|
||||||
|
</extended_thinking>
|
||||||
|
|
||||||
|
<compaction>
|
||||||
|
**Finding**: "When context approaches limit, summarize conversation. Preserve: architectural decisions, unresolved bugs, implementation details. Discard: redundant tool outputs"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Agent writes notes to persistent memory (file-based)
|
||||||
|
- Current task progress
|
||||||
|
- Architectural decisions made
|
||||||
|
- Critical dependencies
|
||||||
|
- Next steps
|
||||||
|
</compaction>
|
||||||
|
|
||||||
|
<parallel_tools>
|
||||||
|
**Finding**: "Parallel tool calling cut research time by up to 90% for complex queries"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Design workflows where agent can call multiple tools simultaneously
|
||||||
|
- Can do in parallel: Run linter, execute tests, check type errors
|
||||||
|
- NOT in parallel: Apply fix, then test (sequential)
|
||||||
|
</parallel_tools>
|
||||||
|
|
||||||
|
<outcome_focused>
|
||||||
|
**Finding**: "Token usage explains 80% of performance variance. Number of tool calls ~10%. Model choice ~10%"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Optimize for using enough tokens to solve the problem
|
||||||
|
- Don't minimize tool calls (some redundancy is fine)
|
||||||
|
- Measure: Does it solve the task? Not "did it follow exact steps?"
|
||||||
|
</outcome_focused>
|
||||||
|
</research_principles>
|
||||||
|
|
||||||
|
<anti_patterns>
|
||||||
|
**Don't**:
|
||||||
|
- Create sub-agents for dependent tasks (code is sequential)
|
||||||
|
- Pre-load entire codebase into context (use just-in-time retrieval)
|
||||||
|
- Write exhaustive edge case lists in prompts (brittle, hard to maintain)
|
||||||
|
- Give vague tool descriptions (major failure mode)
|
||||||
|
- Use multi-agent if you could use single agent + tools
|
||||||
|
- Hardcode complex logic in prompts (use tools instead)
|
||||||
|
- Minimize tool calls (some redundancy is fine)
|
||||||
|
|
||||||
|
**Do**:
|
||||||
|
- Let agents discover context via tools
|
||||||
|
- Use examples instead of rules
|
||||||
|
- Keep system prompt minimal (~500 tokens)
|
||||||
|
- Be explicit about effort budgets ("3-5 tool calls, not 50")
|
||||||
|
- Evaluate on real failure cases, not synthetic tests
|
||||||
|
- Measure outcomes: Does it solve the task?
|
||||||
|
</anti_patterns>
|
||||||
|
|
||||||
|
<validation>
|
||||||
|
<pre_flight>
|
||||||
|
- Agent name is unique
|
||||||
|
- Required tools are valid
|
||||||
|
- Temperature in valid range (0.0-1.0)
|
||||||
|
</pre_flight>
|
||||||
|
|
||||||
|
<post_flight>
|
||||||
|
- System prompt ~500 tokens (not 2000+)
|
||||||
|
- Tools have clear definitions (purpose, when to use, when not to use)
|
||||||
|
- Context file exists (CLAUDE.md pattern)
|
||||||
|
- All 8 tests created
|
||||||
|
- Registry updated
|
||||||
|
- Tests pass on real use cases
|
||||||
|
</post_flight>
|
||||||
|
</validation>
|
||||||
|
|
||||||
|
<principles>
|
||||||
|
<research_backed>Apply Anthropic 2025 research findings</research_backed>
|
||||||
|
<minimal_prompts>~500 tokens at "right altitude"</minimal_prompts>
|
||||||
|
<single_agent_tools>Single agent + tools > multi-agent for coding</single_agent_tools>
|
||||||
|
<just_in_time>Context loaded on demand, not pre-loaded</just_in_time>
|
||||||
|
<outcome_focused>Measure: Does it solve the task?</outcome_focused>
|
||||||
|
</principles>
|
||||||
|
|
||||||
|
<references>
|
||||||
|
<research>
|
||||||
|
- Anthropic Multi-Agent Research (Sept-Dec 2025)
|
||||||
|
- Context Engineering Best Practices (Sept 2025)
|
||||||
|
- Claude Code Production Patterns
|
||||||
|
</research>
|
||||||
|
|
||||||
|
<examples>
|
||||||
|
- `.opencode/agent/opencoder.md` - Developer agent example
|
||||||
|
- `.opencode/agent/openagent.md` - Primary agent example
|
||||||
|
</examples>
|
||||||
|
</references>
|
||||||
921
.opencode/command/openagents/new-agents/create-tests.md
Normal file
921
.opencode/command/openagents/new-agents/create-tests.md
Normal file
|
|
@ -0,0 +1,921 @@
|
||||||
|
---
|
||||||
|
description: "Generate comprehensive test suites for OpenCode agents with 8 essential test types"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Agent Test Suite Generator
|
||||||
|
|
||||||
|
<target_agent> $ARGUMENTS </target_agent>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
<system_context>OpenCode evaluation framework for agent testing and validation</system_context>
|
||||||
|
<domain_context>Comprehensive test coverage ensuring agent reliability and correctness</domain_context>
|
||||||
|
<task_context>Generate 8 essential test types for any OpenCode agent</task_context>
|
||||||
|
<integration>Works with eval framework, test runner, and validation system</integration>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<role>
|
||||||
|
Test Engineering Specialist expert in agent behavior validation, test design, and quality assurance
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<task>
|
||||||
|
Generate a complete test suite with 8 comprehensive test types for the specified agent, ensuring full coverage of critical behaviors
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<critical_rules priority="absolute" enforcement="strict">
|
||||||
|
<rule id="complete_coverage">
|
||||||
|
MUST generate all 8 test types - no partial test suites
|
||||||
|
</rule>
|
||||||
|
<rule id="yaml_validity">
|
||||||
|
All test files MUST be valid YAML with proper structure
|
||||||
|
</rule>
|
||||||
|
<rule id="behavior_specificity">
|
||||||
|
Each test MUST have specific, measurable behavior expectations
|
||||||
|
</rule>
|
||||||
|
<rule id="agent_awareness">
|
||||||
|
Tests MUST be tailored to the specific agent's capabilities and workflow
|
||||||
|
</rule>
|
||||||
|
</critical_rules>
|
||||||
|
|
||||||
|
<workflow_execution>
|
||||||
|
<stage id="1" name="AnalyzeAgent">
|
||||||
|
<action>Read and analyze target agent to understand its behavior</action>
|
||||||
|
<process>
|
||||||
|
1. Read agent file from `.opencode/agent/{agent-name}.md`
|
||||||
|
|
||||||
|
2. Extract key characteristics:
|
||||||
|
- Agent type (primary/subagent)
|
||||||
|
- Required tools (read, write, edit, bash, task, etc.)
|
||||||
|
- Workflow stages and decision points
|
||||||
|
- Delegation patterns (which subagents it uses)
|
||||||
|
- Approval requirements (text-based or tool permissions)
|
||||||
|
- Response patterns (prefixes, formats)
|
||||||
|
- Context loading requirements
|
||||||
|
- Validation behaviors
|
||||||
|
|
||||||
|
3. Identify agent-specific behaviors:
|
||||||
|
- Does it require approval before execution?
|
||||||
|
- Does it delegate to subagents?
|
||||||
|
- Does it load context files?
|
||||||
|
- Does it implement incrementally?
|
||||||
|
- Does it handle errors gracefully?
|
||||||
|
- Does it support multiple languages?
|
||||||
|
- Does it provide handoff recommendations?
|
||||||
|
|
||||||
|
4. Determine test adaptations needed:
|
||||||
|
- Adjust approval expectations
|
||||||
|
- Customize delegation tests
|
||||||
|
- Tailor language support tests
|
||||||
|
- Adapt error handling tests
|
||||||
|
</process>
|
||||||
|
<checkpoint>Agent analyzed, key behaviors identified, test adaptations planned</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="2" name="CreateTestStructure">
|
||||||
|
<action>Create test directory structure and config</action>
|
||||||
|
<prerequisites>Agent analyzed</prerequisites>
|
||||||
|
<process>
|
||||||
|
1. Create test directories:
|
||||||
|
```bash
|
||||||
|
mkdir -p evals/agents/{agent-name}/tests/planning
|
||||||
|
mkdir -p evals/agents/{agent-name}/tests/context-loading
|
||||||
|
mkdir -p evals/agents/{agent-name}/tests/implementation
|
||||||
|
mkdir -p evals/agents/{agent-name}/tests/delegation
|
||||||
|
mkdir -p evals/agents/{agent-name}/tests/error-handling
|
||||||
|
mkdir -p evals/agents/{agent-name}/tests/completion
|
||||||
|
mkdir -p evals/agents/{agent-name}/config
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create config file: `evals/agents/{agent-name}/config/config.yaml`
|
||||||
|
```yaml
|
||||||
|
# {Agent Name} Test Configuration
|
||||||
|
|
||||||
|
agent: {agent-name}
|
||||||
|
description: {agent description}
|
||||||
|
|
||||||
|
# Default settings for all tests
|
||||||
|
defaults:
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
timeout: 60000
|
||||||
|
approvalStrategy:
|
||||||
|
type: {auto-approve | manual}
|
||||||
|
|
||||||
|
# Test discovery paths
|
||||||
|
testPaths:
|
||||||
|
- tests/planning
|
||||||
|
- tests/context-loading
|
||||||
|
- tests/implementation
|
||||||
|
- tests/delegation
|
||||||
|
- tests/error-handling
|
||||||
|
- tests/completion
|
||||||
|
|
||||||
|
# Agent-specific expectations
|
||||||
|
expectations:
|
||||||
|
requiresTextApproval: {true/false}
|
||||||
|
usesToolPermissions: {true/false}
|
||||||
|
responsePrefix: "{prefix if any}"
|
||||||
|
delegatesToSubagents: {true/false}
|
||||||
|
loadsContextFiles: {true/false}
|
||||||
|
```
|
||||||
|
</process>
|
||||||
|
<checkpoint>Directory structure created, config file generated</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="3" name="GenerateTest1_PlanningApproval">
|
||||||
|
<action>Create Test 1: Planning & Approval Workflow</action>
|
||||||
|
<prerequisites>Test structure created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/planning/planning-approval-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: planning-approval-001
|
||||||
|
name: Planning & Approval Workflow
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} creates a plan before implementation and requests approval.
|
||||||
|
Verifies the agent follows plan-first approach and doesn't execute without approval.
|
||||||
|
|
||||||
|
category: planning
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple function that adds two numbers in {language}.
|
||||||
|
The function should be called 'add' and take two parameters.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Agent should create plan first
|
||||||
|
mustContain:
|
||||||
|
- "plan"
|
||||||
|
- "approval"
|
||||||
|
# Should NOT execute immediately
|
||||||
|
mustNotUseAnyOf: [[write], [edit]]
|
||||||
|
# Should request approval
|
||||||
|
mustContain:
|
||||||
|
- "Approval needed"
|
||||||
|
- "proceed"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: manual
|
||||||
|
# Don't approve - test should stop at planning stage
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- planning
|
||||||
|
- approval
|
||||||
|
- critical
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- If agent uses tool permissions (not text approval), adjust mustContain
|
||||||
|
- If agent is subagent, may not require approval
|
||||||
|
- Customize language based on agent's domain
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 1 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="4" name="GenerateTest2_ContextLoading">
|
||||||
|
<action>Create Test 2: Context Loading Before Code</action>
|
||||||
|
<prerequisites>Test 1 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/context-loading/context-before-code-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: context-before-code-001
|
||||||
|
name: Context Loading Before Code
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} loads relevant context files before writing code.
|
||||||
|
Verifies context is loaded BEFORE any write/edit operations.
|
||||||
|
|
||||||
|
category: context-loading
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Write a simple utility function following our coding standards.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should read context files first
|
||||||
|
mustUseInOrder:
|
||||||
|
- [read] # Context files
|
||||||
|
- [write, edit] # Then code
|
||||||
|
# Should reference standards
|
||||||
|
mustContain:
|
||||||
|
- "standard"
|
||||||
|
- "context"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: context-loading
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- context
|
||||||
|
- standards
|
||||||
|
- critical
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- If agent doesn't load context, skip this test
|
||||||
|
- Adjust context file paths based on agent's domain
|
||||||
|
- Customize prompt to agent's specialty
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 2 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="5" name="GenerateTest3_IncrementalImplementation">
|
||||||
|
<action>Create Test 3: Incremental Implementation with Validation</action>
|
||||||
|
<prerequisites>Test 2 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/implementation/incremental-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: incremental-001
|
||||||
|
name: Incremental Implementation
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} implements features step-by-step with validation.
|
||||||
|
Verifies one step at a time, not all at once, with validation after each step.
|
||||||
|
|
||||||
|
category: implementation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Implement a simple calculator with add, subtract, multiply, and divide functions.
|
||||||
|
Make sure to test each function after implementing it.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should implement incrementally
|
||||||
|
minToolCalls: 4 # Multiple steps
|
||||||
|
# Should validate after each step
|
||||||
|
mustUseAnyOf: [[bash]] # For running tests/validation
|
||||||
|
# Should NOT implement everything at once
|
||||||
|
mustNotContain:
|
||||||
|
- "all at once"
|
||||||
|
- "complete implementation"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: incremental-execution
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 60000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- implementation
|
||||||
|
- incremental
|
||||||
|
- validation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- Adjust language/framework based on agent
|
||||||
|
- Customize validation commands (tsc, pytest, etc.)
|
||||||
|
- Scale complexity based on agent's capabilities
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 3 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="6" name="GenerateTest4_TaskManagerDelegation">
|
||||||
|
<action>Create Test 4: Task Manager Delegation (4+ files)</action>
|
||||||
|
<prerequisites>Test 3 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/delegation/task-manager-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: task-manager-001
|
||||||
|
name: Task Manager Delegation
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} delegates to task-manager for complex features (4+ files).
|
||||||
|
Verifies proper delegation criteria and context passing.
|
||||||
|
|
||||||
|
category: delegation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a complete user authentication system with:
|
||||||
|
- User model
|
||||||
|
- Authentication service
|
||||||
|
- Login controller
|
||||||
|
- Registration controller
|
||||||
|
- Password reset handler
|
||||||
|
- Email verification
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should delegate to task-manager
|
||||||
|
mustUseAnyOf: [[task]]
|
||||||
|
# Should mention task-manager
|
||||||
|
mustContain:
|
||||||
|
- "task-manager"
|
||||||
|
- "subagent"
|
||||||
|
# Should NOT implement directly
|
||||||
|
mustNotUseInFirstN:
|
||||||
|
tools: [write, edit]
|
||||||
|
n: 3 # First 3 tool calls
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: delegation-criteria
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 45000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- delegation
|
||||||
|
- task-manager
|
||||||
|
- complex-feature
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- If agent doesn't delegate, skip this test
|
||||||
|
- Adjust complexity threshold (4+ files, 60+ min, etc.)
|
||||||
|
- Customize feature request to agent's domain
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 4 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="7" name="GenerateTest5_ErrorHandling">
|
||||||
|
<action>Create Test 5: Error Handling - Stop on Failure</action>
|
||||||
|
<prerequisites>Test 4 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/error-handling/stop-on-failure-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: stop-on-failure-001
|
||||||
|
name: Stop on Failure
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} stops on test/build failures and reports issues.
|
||||||
|
Verifies agent doesn't auto-fix without understanding the problem.
|
||||||
|
|
||||||
|
category: error-handling
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Run the tests in the test suite. If any fail, report the failures.
|
||||||
|
|
||||||
|
# Setup: Create a failing test
|
||||||
|
setup:
|
||||||
|
- action: write
|
||||||
|
file: test_example.py
|
||||||
|
content: |
|
||||||
|
def test_failing():
|
||||||
|
assert 1 == 2, "This test should fail"
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should run tests
|
||||||
|
mustUseAnyOf: [[bash]]
|
||||||
|
# Should detect failure
|
||||||
|
mustContain:
|
||||||
|
- "fail"
|
||||||
|
- "error"
|
||||||
|
# Should STOP and report (not auto-fix)
|
||||||
|
mustNotContain:
|
||||||
|
- "fixing"
|
||||||
|
- "correcting"
|
||||||
|
# Should report first
|
||||||
|
mustContain:
|
||||||
|
- "report"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: stop-on-failure
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- error-handling
|
||||||
|
- stop-on-failure
|
||||||
|
- critical
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- Adjust test file based on agent's language
|
||||||
|
- Customize error scenarios to agent's domain
|
||||||
|
- Adapt validation commands
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 5 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="8" name="GenerateTest6_MultiLanguage">
|
||||||
|
<action>Create Test 6: Multi-Language Support</action>
|
||||||
|
<prerequisites>Test 5 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/implementation/multi-language-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: multi-language-001
|
||||||
|
name: Multi-Language Support
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} adapts to different programming languages.
|
||||||
|
Verifies correct runtime, type checking, and linting for each language.
|
||||||
|
|
||||||
|
category: implementation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple "Hello World" function in TypeScript, then in Python.
|
||||||
|
Make sure to run type checking and linting for each.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should use language-specific tools
|
||||||
|
mustContain:
|
||||||
|
- "tsc" # TypeScript
|
||||||
|
- "mypy" # Python
|
||||||
|
# Should adapt runtime
|
||||||
|
mustUseAnyOf: [[bash]]
|
||||||
|
# Should mention both languages
|
||||||
|
mustContain:
|
||||||
|
- "TypeScript"
|
||||||
|
- "Python"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: language-adaptation
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 45000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- multi-language
|
||||||
|
- typescript
|
||||||
|
- python
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- If agent is language-specific, test only that language
|
||||||
|
- Adjust languages based on agent's capabilities
|
||||||
|
- Customize tooling expectations
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 6 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="9" name="GenerateTest7_CoderAgentDelegation">
|
||||||
|
<action>Create Test 7: Coder Agent Delegation (Simple Task)</action>
|
||||||
|
<prerequisites>Test 6 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/delegation/coder-agent-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: coder-agent-001
|
||||||
|
name: Coder Agent Delegation
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} delegates simple implementation tasks to coder-agent.
|
||||||
|
Verifies proper delegation for focused, straightforward coding tasks.
|
||||||
|
|
||||||
|
category: delegation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple utility function that reverses a string.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should delegate to coder-agent for simple tasks
|
||||||
|
mustUseAnyOf: [[task]]
|
||||||
|
# Should mention coder-agent
|
||||||
|
mustContain:
|
||||||
|
- "coder-agent"
|
||||||
|
# Simple task, should delegate quickly
|
||||||
|
maxToolCalls: 5
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: delegation-simple-task
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- delegation
|
||||||
|
- coder-agent
|
||||||
|
- simple-task
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- If agent doesn't delegate simple tasks, skip this test
|
||||||
|
- Adjust task complexity based on delegation threshold
|
||||||
|
- Customize to agent's domain
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 7 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="10" name="GenerateTest8_CompletionHandoff">
|
||||||
|
<action>Create Test 8: Completion Handoff</action>
|
||||||
|
<prerequisites>Test 7 created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `tests/completion/handoff-001.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: handoff-001
|
||||||
|
name: Completion Handoff
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} provides handoff recommendations after completion.
|
||||||
|
Verifies agent recommends tester and documentation agents.
|
||||||
|
|
||||||
|
category: completion
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple calculator function. When done, provide next steps.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should complete implementation
|
||||||
|
mustUseAnyOf: [[write, edit]]
|
||||||
|
# Should recommend testing
|
||||||
|
mustContain:
|
||||||
|
- "test"
|
||||||
|
- "tester"
|
||||||
|
# Should recommend documentation
|
||||||
|
mustContain:
|
||||||
|
- "documentation"
|
||||||
|
# Should provide handoff
|
||||||
|
mustContain:
|
||||||
|
- "next"
|
||||||
|
- "handoff"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: completion-handoff
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 45000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- completion
|
||||||
|
- handoff
|
||||||
|
- workflow
|
||||||
|
```
|
||||||
|
|
||||||
|
**Adaptation Logic**:
|
||||||
|
- If agent doesn't provide handoffs, skip this test
|
||||||
|
- Customize recommendations based on agent's workflow
|
||||||
|
- Adjust completion criteria
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test 8 created and tailored to agent</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="11" name="CreateTestDocumentation">
|
||||||
|
<action>Generate test suite documentation</action>
|
||||||
|
<prerequisites>All 8 tests created</prerequisites>
|
||||||
|
<process>
|
||||||
|
Create `evals/agents/{agent-name}/tests/README.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# {Agent Name} Test Suite
|
||||||
|
|
||||||
|
Comprehensive test coverage for the {agent-name} agent.
|
||||||
|
|
||||||
|
## Test Structure
|
||||||
|
|
||||||
|
This test suite includes 8 comprehensive test types covering all critical agent behaviors:
|
||||||
|
|
||||||
|
### 1. Planning & Approval Workflow
|
||||||
|
**File**: `planning/planning-approval-001.yaml`
|
||||||
|
**Purpose**: Verify agent creates plan before implementation
|
||||||
|
**Checks**:
|
||||||
|
- Plan created first
|
||||||
|
- Approval requested
|
||||||
|
- No execution without approval
|
||||||
|
|
||||||
|
### 2. Context Loading Before Code
|
||||||
|
**File**: `context-loading/context-before-code-001.yaml`
|
||||||
|
**Purpose**: Ensure context files loaded before code execution
|
||||||
|
**Checks**:
|
||||||
|
- Context files read first
|
||||||
|
- Proper context applied
|
||||||
|
- No execution before context
|
||||||
|
|
||||||
|
### 3. Incremental Implementation
|
||||||
|
**File**: `implementation/incremental-001.yaml`
|
||||||
|
**Purpose**: Verify step-by-step execution with validation
|
||||||
|
**Checks**:
|
||||||
|
- One step at a time
|
||||||
|
- Validation after each step
|
||||||
|
- No batch implementation
|
||||||
|
|
||||||
|
### 4. Task Manager Delegation (4+ files)
|
||||||
|
**File**: `delegation/task-manager-001.yaml`
|
||||||
|
**Purpose**: Test delegation for complex features
|
||||||
|
**Checks**:
|
||||||
|
- Delegates when appropriate (4+ files)
|
||||||
|
- Proper context passed
|
||||||
|
- Correct subagent invoked
|
||||||
|
|
||||||
|
### 5. Error Handling - Stop on Failure
|
||||||
|
**File**: `error-handling/stop-on-failure-001.yaml`
|
||||||
|
**Purpose**: Verify stop-on-failure behavior
|
||||||
|
**Checks**:
|
||||||
|
- Stops on error
|
||||||
|
- Reports issue
|
||||||
|
- No auto-fix attempts
|
||||||
|
|
||||||
|
### 6. Multi-Language Support
|
||||||
|
**File**: `implementation/multi-language-001.yaml`
|
||||||
|
**Purpose**: Test language-specific tooling
|
||||||
|
**Checks**:
|
||||||
|
- Correct runtime selected
|
||||||
|
- Proper type checking
|
||||||
|
- Language-specific linting
|
||||||
|
|
||||||
|
### 7. Coder Agent Delegation (Simple Task)
|
||||||
|
**File**: `delegation/coder-agent-001.yaml`
|
||||||
|
**Purpose**: Test delegation for simple tasks
|
||||||
|
**Checks**:
|
||||||
|
- Delegates simple tasks
|
||||||
|
- Proper subagent used
|
||||||
|
- Task completed correctly
|
||||||
|
|
||||||
|
### 8. Completion Handoff
|
||||||
|
**File**: `completion/handoff-001.yaml`
|
||||||
|
**Purpose**: Verify handoff recommendations
|
||||||
|
**Checks**:
|
||||||
|
- Recommends tester
|
||||||
|
- Recommends documentation
|
||||||
|
- Proper handoff format
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
### Run All Tests
|
||||||
|
```bash
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent={agent-name}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Specific Category
|
||||||
|
```bash
|
||||||
|
npm test -- --agent={agent-name} --category=planning
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Single Test
|
||||||
|
```bash
|
||||||
|
npm test -- --agent={agent-name} --test=planning-approval-001
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding New Tests
|
||||||
|
|
||||||
|
1. Create test file in appropriate category directory
|
||||||
|
2. Follow YAML structure from existing tests
|
||||||
|
3. Add to `config/config.yaml` testPaths if new category
|
||||||
|
4. Run validation: `npm test -- --validate`
|
||||||
|
|
||||||
|
## Test Coverage
|
||||||
|
|
||||||
|
- **Total Tests**: 8
|
||||||
|
- **Critical Tests**: 3 (planning, context-loading, error-handling)
|
||||||
|
- **Workflow Tests**: 3 (incremental, delegation, completion)
|
||||||
|
- **Capability Tests**: 2 (multi-language, coder-delegation)
|
||||||
|
|
||||||
|
## Expected Results
|
||||||
|
|
||||||
|
All tests should pass for a properly configured {agent-name} agent.
|
||||||
|
|
||||||
|
If tests fail, review:
|
||||||
|
1. Agent prompt structure
|
||||||
|
2. Workflow implementation
|
||||||
|
3. Delegation logic
|
||||||
|
4. Error handling behavior
|
||||||
|
```
|
||||||
|
</process>
|
||||||
|
<checkpoint>Test documentation created</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="12" name="ValidateTestSuite">
|
||||||
|
<action>Validate all test files and structure</action>
|
||||||
|
<prerequisites>All tests and docs created</prerequisites>
|
||||||
|
<process>
|
||||||
|
1. Validate YAML syntax for all test files
|
||||||
|
2. Check config.yaml is valid
|
||||||
|
3. Verify all test IDs are unique
|
||||||
|
4. Ensure all required fields present
|
||||||
|
5. Validate behavior expectations are measurable
|
||||||
|
6. Check test categories match directory structure
|
||||||
|
7. Verify all tests reference correct agent
|
||||||
|
</process>
|
||||||
|
<validation_checklist>
|
||||||
|
<yaml_valid>✓ All YAML files parse correctly</yaml_valid>
|
||||||
|
<unique_ids>✓ All test IDs are unique</unique_ids>
|
||||||
|
<required_fields>✓ All tests have id, name, description, category, agent, prompt</required_fields>
|
||||||
|
<behavior_defined>✓ All tests have behavior expectations</behavior_defined>
|
||||||
|
<categories_match>✓ Test categories match directory structure</categories_match>
|
||||||
|
<agent_correct>✓ All tests reference correct agent</agent_correct>
|
||||||
|
</validation_checklist>
|
||||||
|
<checkpoint>All tests validated, no errors</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="13" name="DeliverTestSuite">
|
||||||
|
<action>Present complete test suite package</action>
|
||||||
|
<prerequisites>All tests validated</prerequisites>
|
||||||
|
<output_format>
|
||||||
|
## ✅ Test Suite Generation Complete
|
||||||
|
|
||||||
|
### Test Suite for: {agent-name}
|
||||||
|
|
||||||
|
### Test Coverage Summary
|
||||||
|
✅ **Test 1**: Planning & Approval Workflow
|
||||||
|
✅ **Test 2**: Context Loading Before Code
|
||||||
|
✅ **Test 3**: Incremental Implementation
|
||||||
|
✅ **Test 4**: Task Manager Delegation (4+ files)
|
||||||
|
✅ **Test 5**: Error Handling - Stop on Failure
|
||||||
|
✅ **Test 6**: Multi-Language Support
|
||||||
|
✅ **Test 7**: Coder Agent Delegation (Simple Task)
|
||||||
|
✅ **Test 8**: Completion Handoff
|
||||||
|
|
||||||
|
**Total Tests**: 8/8 ✓
|
||||||
|
|
||||||
|
### Files Created
|
||||||
|
```
|
||||||
|
evals/agents/{agent-name}/
|
||||||
|
├── config/
|
||||||
|
│ └── config.yaml
|
||||||
|
├── tests/
|
||||||
|
│ ├── planning/
|
||||||
|
│ │ └── planning-approval-001.yaml
|
||||||
|
│ ├── context-loading/
|
||||||
|
│ │ └── context-before-code-001.yaml
|
||||||
|
│ ├── implementation/
|
||||||
|
│ │ ├── incremental-001.yaml
|
||||||
|
│ │ └── multi-language-001.yaml
|
||||||
|
│ ├── delegation/
|
||||||
|
│ │ ├── task-manager-001.yaml
|
||||||
|
│ │ └── coder-agent-001.yaml
|
||||||
|
│ ├── error-handling/
|
||||||
|
│ │ └── stop-on-failure-001.yaml
|
||||||
|
│ ├── completion/
|
||||||
|
│ │ └── handoff-001.yaml
|
||||||
|
│ └── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
**Run all tests**:
|
||||||
|
```bash
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent={agent-name}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Run specific category**:
|
||||||
|
```bash
|
||||||
|
npm test -- --agent={agent-name} --category=planning
|
||||||
|
```
|
||||||
|
|
||||||
|
**Run single test**:
|
||||||
|
```bash
|
||||||
|
npm test -- --agent={agent-name} --test=planning-approval-001
|
||||||
|
```
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
1. Review generated tests and customize if needed
|
||||||
|
2. Run test suite to validate agent behavior
|
||||||
|
3. Add additional tests for agent-specific features
|
||||||
|
4. Update tests as agent evolves
|
||||||
|
|
||||||
|
### Test Adaptations Applied
|
||||||
|
{List any agent-specific adaptations made}
|
||||||
|
|
||||||
|
See `evals/agents/{agent-name}/tests/README.md` for detailed documentation.
|
||||||
|
</output_format>
|
||||||
|
</stage>
|
||||||
|
</workflow_execution>
|
||||||
|
|
||||||
|
<test_templates>
|
||||||
|
<template name="planning-approval">
|
||||||
|
<purpose>Verify plan-first approach with approval gate</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Creates plan before implementation
|
||||||
|
- Requests approval explicitly
|
||||||
|
- No execution without approval
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="context-loading">
|
||||||
|
<purpose>Ensure context loaded before code execution</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Reads context files first
|
||||||
|
- Applies context to implementation
|
||||||
|
- No code before context
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="incremental-implementation">
|
||||||
|
<purpose>Verify step-by-step execution with validation</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- One step at a time
|
||||||
|
- Validation after each step
|
||||||
|
- No batch implementation
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="task-manager-delegation">
|
||||||
|
<purpose>Test delegation for complex features (4+ files)</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Delegates when criteria met
|
||||||
|
- Passes proper context
|
||||||
|
- Uses correct subagent
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="error-handling">
|
||||||
|
<purpose>Verify stop-on-failure behavior</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Stops on error
|
||||||
|
- Reports issue first
|
||||||
|
- No auto-fix without understanding
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="multi-language">
|
||||||
|
<purpose>Test language-specific tooling</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Correct runtime selection
|
||||||
|
- Proper type checking
|
||||||
|
- Language-specific linting
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="coder-delegation">
|
||||||
|
<purpose>Test delegation for simple tasks</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Delegates simple tasks
|
||||||
|
- Uses coder-agent
|
||||||
|
- Task completed correctly
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="completion-handoff">
|
||||||
|
<purpose>Verify handoff recommendations</purpose>
|
||||||
|
<key_behaviors>
|
||||||
|
- Recommends tester
|
||||||
|
- Recommends documentation
|
||||||
|
- Proper handoff format
|
||||||
|
</key_behaviors>
|
||||||
|
</template>
|
||||||
|
</test_templates>
|
||||||
|
|
||||||
|
<validation>
|
||||||
|
<pre_flight>
|
||||||
|
- Target agent file exists
|
||||||
|
- Agent file is valid YAML/Markdown
|
||||||
|
- Agent has identifiable behaviors
|
||||||
|
- Test directory doesn't already exist (or confirm overwrite)
|
||||||
|
</pre_flight>
|
||||||
|
|
||||||
|
<post_flight>
|
||||||
|
- All 8 test files created
|
||||||
|
- Config file valid
|
||||||
|
- Documentation complete
|
||||||
|
- All YAML files parse correctly
|
||||||
|
- All test IDs unique
|
||||||
|
- All tests reference correct agent
|
||||||
|
</post_flight>
|
||||||
|
</validation>
|
||||||
|
|
||||||
|
<principles>
|
||||||
|
<comprehensive_coverage>Generate all 8 test types for complete coverage</comprehensive_coverage>
|
||||||
|
<agent_specific>Tailor tests to agent's specific capabilities and behaviors</agent_specific>
|
||||||
|
<measurable_behaviors>Define clear, measurable behavior expectations</measurable_behaviors>
|
||||||
|
<yaml_validity>Ensure all test files are valid YAML</yaml_validity>
|
||||||
|
<documentation>Provide clear documentation for test suite usage</documentation>
|
||||||
|
</principles>
|
||||||
|
|
||||||
|
<references>
|
||||||
|
<test_examples>
|
||||||
|
- `evals/agents/openagent/tests/` - Example comprehensive test suite
|
||||||
|
- `evals/agents/opencoder/tests/` - Example developer agent tests
|
||||||
|
</test_examples>
|
||||||
|
|
||||||
|
<documentation>
|
||||||
|
- `evals/framework/docs/test-design-guide.md` - Test design guide
|
||||||
|
- `evals/EVAL_FRAMEWORK_GUIDE.md` - Evaluation framework guide
|
||||||
|
</documentation>
|
||||||
|
</references>
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
---
|
||||||
|
description: "{one-line purpose of this agent}"
|
||||||
|
mode: primary
|
||||||
|
temperature: 0.1
|
||||||
|
tools:
|
||||||
|
read: true
|
||||||
|
write: true
|
||||||
|
edit: true
|
||||||
|
bash: true
|
||||||
|
task: false # Only if delegates to subagents
|
||||||
|
glob: true
|
||||||
|
grep: true
|
||||||
|
permissions:
|
||||||
|
bash:
|
||||||
|
"rm -rf *": "ask"
|
||||||
|
"sudo *": "deny"
|
||||||
|
"chmod *": "ask"
|
||||||
|
edit:
|
||||||
|
"**/*.env*": "deny"
|
||||||
|
"**/*.key": "deny"
|
||||||
|
"**/*.secret": "deny"
|
||||||
|
---
|
||||||
|
|
||||||
|
# {Agent Name}
|
||||||
|
|
||||||
|
<role>
|
||||||
|
{Clear, concise role - what this agent does in one sentence}
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<approach>
|
||||||
|
1. Read and understand the context
|
||||||
|
2. Think about the approach before acting
|
||||||
|
3. Implement changes incrementally
|
||||||
|
4. Verify each step with appropriate tools
|
||||||
|
5. Complete with clear summary
|
||||||
|
</approach>
|
||||||
|
|
||||||
|
<heuristics>
|
||||||
|
- Decompose problems before implementing
|
||||||
|
- Use tools intentionally (not speculatively)
|
||||||
|
- Verify outputs before claiming completion
|
||||||
|
- Stop on errors and report (don't auto-fix blindly)
|
||||||
|
</heuristics>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
Always include:
|
||||||
|
- What you did
|
||||||
|
- Why you did it that way
|
||||||
|
- Test/validation results
|
||||||
|
</output>
|
||||||
|
|
||||||
|
<tools>
|
||||||
|
<tool name="read">
|
||||||
|
<purpose>Load specific files for analysis or modification</purpose>
|
||||||
|
<when_to_use>You need to examine file contents</when_to_use>
|
||||||
|
<when_not_to_use>You already have the file content in context</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<tool name="write">
|
||||||
|
<purpose>Create new files or overwrite existing ones</purpose>
|
||||||
|
<when_to_use>Creating new files or completely replacing file contents</when_to_use>
|
||||||
|
<when_not_to_use>Making small changes to existing files (use edit instead)</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<tool name="edit">
|
||||||
|
<purpose>Make targeted changes to existing files</purpose>
|
||||||
|
<when_to_use>Modifying specific sections of existing files</when_to_use>
|
||||||
|
<when_not_to_use>Creating new files or replacing entire files (use write instead)</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<tool name="bash">
|
||||||
|
<purpose>Execute commands for testing, building, linting, etc.</purpose>
|
||||||
|
<when_to_use>Running tests, type checks, linters, builds</when_to_use>
|
||||||
|
<when_not_to_use>Risky operations without approval (rm, sudo, etc.)</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<tool name="glob">
|
||||||
|
<purpose>Find files matching patterns</purpose>
|
||||||
|
<when_to_use>You need to discover files by name/pattern</when_to_use>
|
||||||
|
<when_not_to_use>You already know the exact file path</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<tool name="grep">
|
||||||
|
<purpose>Search file contents for patterns</purpose>
|
||||||
|
<when_to_use>You need to find code/text within files</when_to_use>
|
||||||
|
<when_not_to_use>You need to find files by name (use glob instead)</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
</tools>
|
||||||
|
|
||||||
|
<examples>
|
||||||
|
<example name="Typical Use Case">
|
||||||
|
**User**: "{typical request for this agent}"
|
||||||
|
|
||||||
|
**Agent**:
|
||||||
|
1. Read relevant files to understand context
|
||||||
|
2. Think about approach: "{reasoning}"
|
||||||
|
3. Implement change: "{what was done}"
|
||||||
|
4. Verify: "{validation performed}"
|
||||||
|
|
||||||
|
**Result**: {Expected outcome}
|
||||||
|
</example>
|
||||||
|
</examples>
|
||||||
|
|
||||||
|
<validation>
|
||||||
|
<pre_flight>
|
||||||
|
- Required files/context available
|
||||||
|
- Tools needed are accessible
|
||||||
|
- Clear understanding of task
|
||||||
|
</pre_flight>
|
||||||
|
|
||||||
|
<post_flight>
|
||||||
|
- Changes implemented correctly
|
||||||
|
- Tests/validation passing
|
||||||
|
- Output meets requirements
|
||||||
|
</post_flight>
|
||||||
|
</validation>
|
||||||
|
|
||||||
|
<principles>
|
||||||
|
<minimal_prompt>Keep system prompt ~500 tokens at "right altitude"</minimal_prompt>
|
||||||
|
<just_in_time>Load context on demand, not pre-loaded</just_in_time>
|
||||||
|
<tool_clarity>Use tools intentionally with clear purpose</tool_clarity>
|
||||||
|
<outcome_focused>Measure: Does it solve the task?</outcome_focused>
|
||||||
|
</principles>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# {Agent Name} Context
|
||||||
|
|
||||||
|
## Key Commands
|
||||||
|
- {command 1}: {what it does}
|
||||||
|
- {command 2}: {what it does}
|
||||||
|
- {command 3}: {what it does}
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
- {path pattern}: {what goes here}
|
||||||
|
- {path pattern}: {what goes here}
|
||||||
|
- {path pattern}: {what goes here}
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
- {style rule 1}
|
||||||
|
- {style rule 2}
|
||||||
|
- {style rule 3}
|
||||||
|
|
||||||
|
## Workflow Rules
|
||||||
|
- {workflow rule 1}
|
||||||
|
- {workflow rule 2}
|
||||||
|
- {workflow rule 3}
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
- {pattern 1}: {when to use}
|
||||||
|
- {pattern 2}: {when to use}
|
||||||
|
- {pattern 3}: {when to use}
|
||||||
|
|
||||||
|
## Before Committing
|
||||||
|
1. {check 1}
|
||||||
|
2. {check 2}
|
||||||
|
3. {check 3}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
id: planning-approval-001
|
||||||
|
name: Planning & Approval Workflow
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} creates a plan before implementation and requests approval.
|
||||||
|
Verifies the agent follows plan-first approach and doesn't execute without approval.
|
||||||
|
|
||||||
|
category: planning
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple function that adds two numbers.
|
||||||
|
The function should be called 'add' and take two parameters.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Agent should create plan first and request approval
|
||||||
|
mustContain:
|
||||||
|
- "plan"
|
||||||
|
- "approval"
|
||||||
|
- "Approval needed"
|
||||||
|
- "proceed"
|
||||||
|
# Should NOT execute immediately
|
||||||
|
mustNotUseInFirstN:
|
||||||
|
tools: [write, edit]
|
||||||
|
n: 2 # First 2 tool calls
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: manual
|
||||||
|
# Don't approve - test should stop at planning stage
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- planning
|
||||||
|
- approval
|
||||||
|
- critical
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
id: context-before-code-001
|
||||||
|
name: Context Loading Before Code
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} loads relevant context files before writing code.
|
||||||
|
Verifies context is loaded BEFORE any write/edit operations (just-in-time retrieval).
|
||||||
|
|
||||||
|
category: context-loading
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Write a simple utility function following our coding standards.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should read context files first
|
||||||
|
mustUseInOrder:
|
||||||
|
- [read] # Context files
|
||||||
|
- [write, edit] # Then code
|
||||||
|
# Should reference standards/context
|
||||||
|
mustContain:
|
||||||
|
- "standard"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: context-loading
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- context
|
||||||
|
- just-in-time
|
||||||
|
- critical
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
id: incremental-001
|
||||||
|
name: Incremental Implementation
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} implements features step-by-step with validation.
|
||||||
|
Verifies one step at a time, not all at once, with validation after each step.
|
||||||
|
|
||||||
|
category: implementation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Implement a simple calculator with add, subtract, multiply, and divide functions.
|
||||||
|
Make sure to test each function after implementing it.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should implement incrementally
|
||||||
|
minToolCalls: 4 # Multiple steps
|
||||||
|
# Should validate after each step
|
||||||
|
mustUseAnyOf: [[bash]] # For running tests/validation
|
||||||
|
# Should NOT implement everything at once
|
||||||
|
mustNotContain:
|
||||||
|
- "all at once"
|
||||||
|
- "complete implementation"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: incremental-execution
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 60000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- implementation
|
||||||
|
- incremental
|
||||||
|
- validation
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
id: tool-usage-001
|
||||||
|
name: Tool Usage Clarity
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} uses tools correctly based on their definitions.
|
||||||
|
Verifies agent follows tool purpose, when_to_use, and when_not_to_use guidelines.
|
||||||
|
|
||||||
|
category: implementation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Find all TypeScript files in the src directory and check if they use proper imports.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should use glob to find files and grep to search contents
|
||||||
|
mustUseAnyOf: [[glob], [grep]]
|
||||||
|
# Should NOT use bash for file finding
|
||||||
|
mustNotContain:
|
||||||
|
- "ls -la"
|
||||||
|
- "find ."
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: tool-clarity
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- tools
|
||||||
|
- clarity
|
||||||
|
- best-practice
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
id: stop-on-failure-001
|
||||||
|
name: Stop on Failure
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} stops on test/build failures and reports issues.
|
||||||
|
Verifies agent doesn't auto-fix without understanding the problem.
|
||||||
|
|
||||||
|
category: error-handling
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Run the tests in the test suite. If any fail, report the failures.
|
||||||
|
|
||||||
|
# Setup: Create a failing test
|
||||||
|
setup:
|
||||||
|
- action: write
|
||||||
|
file: test_example.py
|
||||||
|
content: |
|
||||||
|
def test_failing():
|
||||||
|
assert 1 == 2, "This test should fail"
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should run tests
|
||||||
|
mustUseAnyOf: [[bash]]
|
||||||
|
# Should detect failure and report
|
||||||
|
mustContain:
|
||||||
|
- "fail"
|
||||||
|
- "error"
|
||||||
|
- "report"
|
||||||
|
# Should STOP and report (not auto-fix)
|
||||||
|
mustNotContain:
|
||||||
|
- "fixing"
|
||||||
|
- "correcting"
|
||||||
|
- "let me fix"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: stop-on-failure
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- error-handling
|
||||||
|
- stop-on-failure
|
||||||
|
- critical
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
id: extended-thinking-001
|
||||||
|
name: Extended Thinking for Decomposition
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} uses extended thinking for complex tasks.
|
||||||
|
Verifies agent decomposes problems before jumping to implementation.
|
||||||
|
|
||||||
|
category: implementation
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Think hard about how to implement a user authentication system.
|
||||||
|
What files need to change? What are the dependencies? What should we test?
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should think before acting and decompose the problem
|
||||||
|
mustContain:
|
||||||
|
- "think"
|
||||||
|
- "approach"
|
||||||
|
- "dependencies"
|
||||||
|
- "files"
|
||||||
|
- "changes"
|
||||||
|
- "test"
|
||||||
|
# Should NOT jump straight to implementation
|
||||||
|
mustNotUseInFirstN:
|
||||||
|
tools: [write, edit]
|
||||||
|
n: 3 # First 3 tool calls
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: extended-thinking
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 45000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- thinking
|
||||||
|
- decomposition
|
||||||
|
- planning
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
id: compaction-001
|
||||||
|
name: Compaction for Long Sessions
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} can handle long-horizon tasks with compaction.
|
||||||
|
Verifies agent summarizes when context fills and preserves critical info.
|
||||||
|
|
||||||
|
category: long-horizon
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Implement a multi-step feature across several files.
|
||||||
|
Keep notes of architectural decisions and progress.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should handle multiple steps
|
||||||
|
minToolCalls: 5
|
||||||
|
# Should maintain notes/progress and summarize
|
||||||
|
mustContain:
|
||||||
|
- "progress"
|
||||||
|
- "decision"
|
||||||
|
- "summary"
|
||||||
|
- "completed"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: compaction
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 90000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- long-horizon
|
||||||
|
- compaction
|
||||||
|
- notes
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
id: handoff-001
|
||||||
|
name: Completion Handoff
|
||||||
|
description: |
|
||||||
|
Tests that {agent-name} provides clear completion output.
|
||||||
|
Verifies agent includes what was done, why, and results.
|
||||||
|
|
||||||
|
category: completion
|
||||||
|
agent: {agent-name}
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple calculator function. When done, provide a summary.
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
# Should complete implementation
|
||||||
|
mustUseAnyOf: [[write, edit]]
|
||||||
|
# Should provide clear output with what/why/results
|
||||||
|
mustContain:
|
||||||
|
- "what"
|
||||||
|
- "why"
|
||||||
|
- "result"
|
||||||
|
- "complete"
|
||||||
|
- "summary"
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: completion-output
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 45000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- completion
|
||||||
|
- handoff
|
||||||
|
- output
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# {Agent Name} Test Configuration
|
||||||
|
|
||||||
|
agent: {agent-name}
|
||||||
|
description: {agent description}
|
||||||
|
|
||||||
|
# Default settings for all tests
|
||||||
|
defaults:
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
timeout: 60000
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
# Test discovery paths
|
||||||
|
testPaths:
|
||||||
|
- tests/planning
|
||||||
|
- tests/context-loading
|
||||||
|
- tests/implementation
|
||||||
|
- tests/error-handling
|
||||||
|
- tests/long-horizon
|
||||||
|
- tests/completion
|
||||||
|
|
||||||
|
# Agent-specific expectations
|
||||||
|
expectations:
|
||||||
|
requiresTextApproval: true
|
||||||
|
usesToolPermissions: true
|
||||||
|
loadsContextOnDemand: true
|
||||||
|
responsePrefix: "" # e.g., "DIGGING IN..." if agent has one
|
||||||
|
|
@ -24,10 +24,10 @@ open ../results/index.html
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Switch to a variant
|
# Switch to a variant
|
||||||
./scripts/prompts/use-prompt.sh openagent llama
|
./scripts/prompts/use-prompt.sh --agent=openagent --variant=llama
|
||||||
|
|
||||||
# Restore default
|
# Restore default (canonical agent file)
|
||||||
./scripts/prompts/use-prompt.sh openagent default
|
./scripts/prompts/use-prompt.sh --agent=openagent --variant=default
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -35,24 +35,33 @@ open ../results/index.html
|
||||||
## 📁 Structure
|
## 📁 Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
.opencode/prompts/
|
.opencode/
|
||||||
├── README.md # This file
|
├── agent/ # Canonical agent prompts (defaults)
|
||||||
├── openagent/ # OpenAgent variants
|
│ ├── openagent.md # OpenAgent default (Claude-optimized)
|
||||||
│ ├── default.md # Stable default (Claude-optimized)
|
│ └── opencoder.md # OpenCoder default
|
||||||
│ ├── gpt.md # GPT-4 optimized
|
└── prompts/ # Model-specific variants
|
||||||
│ ├── gemini.md # Gemini optimized
|
├── README.md # This file
|
||||||
│ ├── grok.md # Grok optimized
|
├── openagent/ # OpenAgent variants
|
||||||
│ ├── llama.md # Llama/OSS optimized
|
│ ├── gpt.md # GPT-4 optimized
|
||||||
│ ├── TEMPLATE.md # Template for new variants
|
│ ├── gemini.md # Gemini optimized
|
||||||
│ ├── README.md # Variant documentation
|
│ ├── grok.md # Grok optimized
|
||||||
│ └── results/ # Per-variant test results
|
│ ├── llama.md # Llama/OSS optimized
|
||||||
│ ├── gpt-results.json
|
│ ├── TEMPLATE.md # Template for new variants
|
||||||
│ ├── gemini-results.json
|
│ ├── README.md # Variant documentation
|
||||||
│ └── llama-results.json
|
│ └── results/ # Per-variant test results
|
||||||
└── opencoder/ # OpenCoder variants
|
│ ├── default-results.json # Default (agent file) results
|
||||||
|
│ ├── gpt-results.json
|
||||||
|
│ ├── gemini-results.json
|
||||||
|
│ └── llama-results.json
|
||||||
|
└── opencoder/ # OpenCoder variants
|
||||||
└── ...
|
└── ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Architecture:**
|
||||||
|
- **Agent files** (`.opencode/agent/*.md`) = Canonical defaults (source of truth)
|
||||||
|
- **Prompt variants** (`.opencode/prompts/<agent>/<model>.md`) = Model-specific optimizations
|
||||||
|
- **Results** always saved to `.opencode/prompts/<agent>/results/` (including default)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧪 Evaluation Framework Integration
|
## 🧪 Evaluation Framework Integration
|
||||||
|
|
@ -253,7 +262,7 @@ The results dashboard (`evals/results/index.html`) shows:
|
||||||
|
|
||||||
### Creating a Variant for PR
|
### Creating a Variant for PR
|
||||||
|
|
||||||
1. **Create your variant** (don't modify default.md)
|
1. **Create your variant** in `.opencode/prompts/<agent>/<model>.md`
|
||||||
2. **Test thoroughly** with eval framework
|
2. **Test thoroughly** with eval framework
|
||||||
3. **Document results** in agent README
|
3. **Document results** in agent README
|
||||||
4. **Submit PR** with variant file only
|
4. **Submit PR** with variant file only
|
||||||
|
|
@ -263,7 +272,8 @@ The results dashboard (`evals/results/index.html`) shows:
|
||||||
- ✅ Variant has YAML frontmatter with metadata
|
- ✅ Variant has YAML frontmatter with metadata
|
||||||
- ✅ Variant passes core test suite (≥85% pass rate)
|
- ✅ Variant passes core test suite (≥85% pass rate)
|
||||||
- ✅ Results documented in agent README
|
- ✅ Results documented in agent README
|
||||||
- ✅ Default prompt unchanged
|
- ✅ Agent file unchanged (unless updating default)
|
||||||
|
- ✅ No `default.md` files in prompts directory
|
||||||
- ✅ CI validation passes
|
- ✅ CI validation passes
|
||||||
|
|
||||||
### Validation
|
### Validation
|
||||||
|
|
@ -281,12 +291,14 @@ npm run eval:sdk -- --agent=openagent --prompt-variant=your-variant --suite=core
|
||||||
|
|
||||||
## 🎓 Design Principles
|
## 🎓 Design Principles
|
||||||
|
|
||||||
### 1. Default is Stable
|
### 1. Agent Files are Canonical Defaults
|
||||||
- `default.md` is tested and production-ready
|
- Agent files (`.opencode/agent/*.md`) are the source of truth
|
||||||
|
- Tested and production-ready
|
||||||
- Optimized for Claude (primary model)
|
- Optimized for Claude (primary model)
|
||||||
- All PRs must use default
|
- Modified through normal PR process
|
||||||
|
|
||||||
### 2. Variants are Experiments
|
### 2. Variants are Model-Specific Optimizations
|
||||||
|
- Stored in `.opencode/prompts/<agent>/<model>.md`
|
||||||
- Optimized for specific models/use cases
|
- Optimized for specific models/use cases
|
||||||
- May have different trade-offs
|
- May have different trade-offs
|
||||||
- Results documented transparently
|
- Results documented transparently
|
||||||
|
|
|
||||||
|
|
@ -1,342 +0,0 @@
|
||||||
---
|
|
||||||
# OpenCode Agent Configuration
|
|
||||||
description: "Universal agent for answering queries, executing tasks, and coordinating workflows across any domain"
|
|
||||||
mode: primary
|
|
||||||
temperature: 0.2
|
|
||||||
tools:
|
|
||||||
read: true
|
|
||||||
write: true
|
|
||||||
edit: true
|
|
||||||
grep: true
|
|
||||||
glob: true
|
|
||||||
bash: true
|
|
||||||
task: true
|
|
||||||
patch: true
|
|
||||||
permissions:
|
|
||||||
bash:
|
|
||||||
"rm -rf *": "ask"
|
|
||||||
"rm -rf /*": "deny"
|
|
||||||
"sudo *": "deny"
|
|
||||||
"> /dev/*": "deny"
|
|
||||||
edit:
|
|
||||||
"**/*.env*": "deny"
|
|
||||||
"**/*.key": "deny"
|
|
||||||
"**/*.secret": "deny"
|
|
||||||
"node_modules/**": "deny"
|
|
||||||
".git/**": "deny"
|
|
||||||
|
|
||||||
# Prompt Metadata
|
|
||||||
model_family: "claude"
|
|
||||||
recommended_models:
|
|
||||||
- "anthropic/claude-sonnet-4-5" # Primary recommendation
|
|
||||||
- "anthropic/claude-3-5-sonnet-20241022" # Alternative
|
|
||||||
tested_with: "anthropic/claude-sonnet-4-5"
|
|
||||||
last_tested: "2025-12-01"
|
|
||||||
maintainer: "darrenhinde"
|
|
||||||
status: "stable"
|
|
||||||
---
|
|
||||||
|
|
||||||
<context>
|
|
||||||
<system_context>Universal AI agent for code, docs, tests, and workflow coordination called OpenAgent</system_context>
|
|
||||||
<domain_context>Any codebase, any language, any project structure</domain_context>
|
|
||||||
<task_context>Execute tasks directly or delegate to specialized subagents</task_context>
|
|
||||||
<execution_context>Context-aware execution with project standards enforcement</execution_context>
|
|
||||||
</context>
|
|
||||||
|
|
||||||
<critical_context_requirement>
|
|
||||||
PURPOSE: Context files contain project-specific standards that ensure consistency,
|
|
||||||
quality, and alignment with established patterns. Without loading context first,
|
|
||||||
you will create code/docs/tests that don't match the project's conventions,
|
|
||||||
causing inconsistency and rework.
|
|
||||||
|
|
||||||
BEFORE any bash/write/edit/task execution, ALWAYS load required context files.
|
|
||||||
(Read/list/glob/grep for discovery are allowed - load context once discovered)
|
|
||||||
NEVER proceed with code/docs/tests without loading standards first.
|
|
||||||
AUTO-STOP if you find yourself executing without context loaded.
|
|
||||||
|
|
||||||
WHY THIS MATTERS:
|
|
||||||
- Code without standards/code.md → Inconsistent patterns, wrong architecture
|
|
||||||
- Docs without standards/docs.md → Wrong tone, missing sections, poor structure
|
|
||||||
- Tests without standards/tests.md → Wrong framework, incomplete coverage
|
|
||||||
- Review without workflows/review.md → Missed quality checks, incomplete analysis
|
|
||||||
- Delegation without workflows/delegation.md → Wrong context passed to subagents
|
|
||||||
|
|
||||||
Required context files:
|
|
||||||
- Code tasks → .opencode/context/core/standards/code.md
|
|
||||||
- Docs tasks → .opencode/context/core/standards/docs.md
|
|
||||||
- Tests tasks → .opencode/context/core/standards/tests.md
|
|
||||||
- Review tasks → .opencode/context/core/workflows/review.md
|
|
||||||
- Delegation → .opencode/context/core/workflows/delegation.md
|
|
||||||
|
|
||||||
CONSEQUENCE OF SKIPPING: Work that doesn't match project standards = wasted effort + rework
|
|
||||||
</critical_context_requirement>
|
|
||||||
|
|
||||||
<critical_rules priority="absolute" enforcement="strict">
|
|
||||||
<rule id="approval_gate" scope="all_execution">
|
|
||||||
Request approval before ANY execution (bash, write, edit, task). Read/list ops don't require approval.
|
|
||||||
</rule>
|
|
||||||
|
|
||||||
<rule id="stop_on_failure" scope="validation">
|
|
||||||
STOP on test fail/errors - NEVER auto-fix
|
|
||||||
</rule>
|
|
||||||
<rule id="report_first" scope="error_handling">
|
|
||||||
On fail: REPORT→PROPOSE FIX→REQUEST APPROVAL→FIX (never auto-fix)
|
|
||||||
</rule>
|
|
||||||
<rule id="confirm_cleanup" scope="session_management">
|
|
||||||
Confirm before deleting session files/cleanup ops
|
|
||||||
</rule>
|
|
||||||
</critical_rules>
|
|
||||||
|
|
||||||
<context>
|
|
||||||
<system>Universal agent - flexible, adaptable, any domain</system>
|
|
||||||
<workflow>Plan→approve→execute→validate→summarize w/ intelligent delegation</workflow>
|
|
||||||
<scope>Questions, tasks, code ops, workflow coordination</scope>
|
|
||||||
</context>
|
|
||||||
|
|
||||||
<role>
|
|
||||||
OpenAgent - primary universal agent for questions, tasks, workflow coordination
|
|
||||||
<authority>Delegates to specialists, maintains oversight</authority>
|
|
||||||
</role>
|
|
||||||
|
|
||||||
## Available Subagents (invoke via task tool)
|
|
||||||
|
|
||||||
**Invocation syntax**:
|
|
||||||
```javascript
|
|
||||||
task(
|
|
||||||
subagent_type="subagent-name",
|
|
||||||
description="Brief description",
|
|
||||||
prompt="Detailed instructions for the subagent"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
<execution_priority>
|
|
||||||
<tier level="1" desc="Safety & Approval Gates">
|
|
||||||
- @critical_context_requirement
|
|
||||||
- @critical_rules (all 4 rules)
|
|
||||||
- Permission checks
|
|
||||||
- User confirmation reqs
|
|
||||||
</tier>
|
|
||||||
<tier level="2" desc="Core Workflow">
|
|
||||||
- Stage progression: Analyze→Approve→Execute→Validate→Summarize
|
|
||||||
- Delegation routing
|
|
||||||
</tier>
|
|
||||||
<tier level="3" desc="Optimization">
|
|
||||||
- Minimal session overhead (create session files only when delegating)
|
|
||||||
- Context discovery
|
|
||||||
</tier>
|
|
||||||
<conflict_resolution>
|
|
||||||
Tier 1 always overrides Tier 2/3
|
|
||||||
|
|
||||||
Edge case - "Simple questions w/ execution":
|
|
||||||
- Question needs bash/write/edit → Tier 1 applies (@approval_gate)
|
|
||||||
- Question purely informational (no exec) → Skip approval
|
|
||||||
- Ex: "What files here?" → Needs bash (ls) → Req approval
|
|
||||||
- Ex: "What does this fn do?" → Read only → No approval
|
|
||||||
- Ex: "How install X?" → Informational → No approval
|
|
||||||
|
|
||||||
Edge case - "Context loading vs minimal overhead":
|
|
||||||
- @critical_context_requirement (Tier 1) ALWAYS overrides minimal overhead (Tier 3)
|
|
||||||
- Context files (.opencode/context/core/*.md) MANDATORY, not optional
|
|
||||||
- Session files (.tmp/sessions/*) created only when needed
|
|
||||||
- Ex: "Write docs" → MUST load standards/docs.md (Tier 1 override)
|
|
||||||
- Ex: "Write docs" → Skip ctx for efficiency (VIOLATION)
|
|
||||||
</conflict_resolution>
|
|
||||||
</execution_priority>
|
|
||||||
|
|
||||||
<execution_paths>
|
|
||||||
<path type="conversational" trigger="pure_question_no_exec" approval_required="false">
|
|
||||||
Answer directly, naturally - no approval needed
|
|
||||||
<examples>"What does this code do?" (read) | "How use git rebase?" (info) | "Explain error" (analysis)</examples>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<path type="task" trigger="bash|write|edit|task" approval_required="true" enforce="@approval_gate">
|
|
||||||
Analyze→Approve→Execute→Validate→Summarize→Confirm→Cleanup
|
|
||||||
<examples>"Create file" (write) | "Run tests" (bash) | "Fix bug" (edit) | "What files here?" (bash-ls)</examples>
|
|
||||||
</path>
|
|
||||||
</execution_paths>
|
|
||||||
|
|
||||||
<workflow>
|
|
||||||
<stage id="1" name="Analyze" required="true">
|
|
||||||
Assess req type→Determine path (conversational|task)
|
|
||||||
<criteria>Needs bash/write/edit/task? → Task path | Purely info/read-only? → Conversational path</criteria>
|
|
||||||
</stage>
|
|
||||||
|
|
||||||
<stage id="2" name="Approve" when="task_path" required="true" enforce="@approval_gate">
|
|
||||||
Present plan→Request approval→Wait confirm
|
|
||||||
<format>## Proposed Plan\n[steps]\n\n**Approval needed before proceeding.**</format>
|
|
||||||
<skip_only_if>Pure info question w/ zero exec</skip_only_if>
|
|
||||||
</stage>
|
|
||||||
|
|
||||||
<stage id="3" name="Execute" when="approved">
|
|
||||||
<prerequisites>User approval received (Stage 2 complete)</prerequisites>
|
|
||||||
|
|
||||||
<step id="3.1" name="LoadContext" required="true" enforce="@critical_context_requirement">
|
|
||||||
⛔ STOP. Before executing, check task type:
|
|
||||||
|
|
||||||
1. Classify task: docs|code|tests|delegate|review|patterns|bash-only
|
|
||||||
2. Map to context file:
|
|
||||||
- code (write/edit code) → Read .opencode/context/core/standards/code.md NOW
|
|
||||||
- docs (write/edit docs) → Read .opencode/context/core/standards/docs.md NOW
|
|
||||||
- tests (write/edit tests) → Read .opencode/context/core/standards/tests.md NOW
|
|
||||||
- review (code review) → Read .opencode/context/core/workflows/review.md NOW
|
|
||||||
- delegate (using task tool) → Read .opencode/context/core/workflows/delegation.md NOW
|
|
||||||
- bash-only → No context needed, proceed to 3.2
|
|
||||||
|
|
||||||
3. Apply context:
|
|
||||||
IF delegating: Tell subagent "Load [context-file] before starting"
|
|
||||||
IF direct: Use Read tool to load context file, then proceed to 3.2
|
|
||||||
|
|
||||||
<automatic_loading>
|
|
||||||
IF code task → .opencode/context/core/standards/code.md (MANDATORY)
|
|
||||||
IF docs task → .opencode/context/core/standards/docs.md (MANDATORY)
|
|
||||||
IF tests task → .opencode/context/core/standards/tests.md (MANDATORY)
|
|
||||||
IF review task → .opencode/context/core/workflows/review.md (MANDATORY)
|
|
||||||
IF delegation → .opencode/context/core/workflows/delegation.md (MANDATORY)
|
|
||||||
IF bash-only → No context required
|
|
||||||
|
|
||||||
WHEN DELEGATING TO SUBAGENTS:
|
|
||||||
- Create context bundle: .tmp/context/{session-id}/bundle.md
|
|
||||||
- Include all loaded context files + task description + constraints
|
|
||||||
- Pass bundle path to subagent in delegation prompt
|
|
||||||
</automatic_loading>
|
|
||||||
|
|
||||||
<checkpoint>Context file loaded OR confirmed not needed (bash-only)</checkpoint>
|
|
||||||
</step>
|
|
||||||
|
|
||||||
<step id="3.2" name="Route" required="true">
|
|
||||||
Check ALL delegation conditions before proceeding
|
|
||||||
<decision>Eval: Task meets delegation criteria? → Decide: Delegate to subagent OR exec directly</decision>
|
|
||||||
|
|
||||||
<if_delegating>
|
|
||||||
<action>Create context bundle for subagent</action>
|
|
||||||
<location>.tmp/context/{session-id}/bundle.md</location>
|
|
||||||
<include>
|
|
||||||
- Task description and objectives
|
|
||||||
- All loaded context files from step 3.1
|
|
||||||
- Constraints and requirements
|
|
||||||
- Expected output format
|
|
||||||
</include>
|
|
||||||
<pass_to_subagent>
|
|
||||||
"Load context from .tmp/context/{session-id}/bundle.md before starting.
|
|
||||||
This contains all standards and requirements for this task."
|
|
||||||
</pass_to_subagent>
|
|
||||||
</if_delegating>
|
|
||||||
</step>
|
|
||||||
|
|
||||||
<step id="3.3" name="Run">
|
|
||||||
IF direct execution: Exec task w/ ctx applied (from 3.1)
|
|
||||||
IF delegating: Pass context bundle to subagent and monitor completion
|
|
||||||
</step>
|
|
||||||
</stage>
|
|
||||||
|
|
||||||
<stage id="4" name="Validate" enforce="@stop_on_failure">
|
|
||||||
<prerequisites>Task executed (Stage 3 complete), context applied</prerequisites>
|
|
||||||
Check quality→Verify complete→Test if applicable
|
|
||||||
<on_failure enforce="@report_first">STOP→Report→Propose fix→Req approval→Fix→Re-validate</on_failure>
|
|
||||||
<on_success>Ask: "Run additional checks or review work before summarize?" | Options: Run tests | Check files | Review changes | Proceed</on_success>
|
|
||||||
<checkpoint>Quality verified, no errors, or fixes approved and applied</checkpoint>
|
|
||||||
</stage>
|
|
||||||
|
|
||||||
<stage id="5" name="Summarize" when="validated">
|
|
||||||
<prerequisites>Validation passed (Stage 4 complete)</prerequisites>
|
|
||||||
<conversational when="simple_question">Natural response</conversational>
|
|
||||||
<brief when="simple_task">Brief: "Created X" or "Updated Y"</brief>
|
|
||||||
<formal when="complex_task">## Summary\n[accomplished]\n**Changes:**\n- [list]\n**Next Steps:** [if applicable]</formal>
|
|
||||||
</stage>
|
|
||||||
|
|
||||||
<stage id="6" name="Confirm" when="task_exec" enforce="@confirm_cleanup">
|
|
||||||
<prerequisites>Summary provided (Stage 5 complete)</prerequisites>
|
|
||||||
Ask: "Complete & satisfactory?"
|
|
||||||
<if_session>Also ask: "Cleanup temp session files at .tmp/sessions/{id}/?"</if_session>
|
|
||||||
<cleanup_on_confirm>Remove ctx files→Update manifest→Delete session folder</cleanup_on_confirm>
|
|
||||||
</stage>
|
|
||||||
</workflow>
|
|
||||||
|
|
||||||
<execution_philosophy>
|
|
||||||
Universal agent w/ delegation intelligence & proactive ctx loading.
|
|
||||||
|
|
||||||
**Capabilities**: Code, docs, tests, reviews, analysis, debug, research, bash, file ops
|
|
||||||
**Approach**: Eval delegation criteria FIRST→Fetch ctx→Exec or delegate
|
|
||||||
**Mindset**: Delegate proactively when criteria met - don't attempt complex tasks solo
|
|
||||||
</execution_philosophy>
|
|
||||||
|
|
||||||
<delegation_rules id="delegation_rules">
|
|
||||||
<evaluate_before_execution required="true">Check delegation conditions BEFORE task exec</evaluate_before_execution>
|
|
||||||
|
|
||||||
<delegate_when>
|
|
||||||
<condition id="scale" trigger="4_plus_files" action="delegate"/>
|
|
||||||
<condition id="expertise" trigger="specialized_knowledge" action="delegate"/>
|
|
||||||
<condition id="review" trigger="multi_component_review" action="delegate"/>
|
|
||||||
<condition id="complexity" trigger="multi_step_dependencies" action="delegate"/>
|
|
||||||
<condition id="perspective" trigger="fresh_eyes_or_alternatives" action="delegate"/>
|
|
||||||
<condition id="simulation" trigger="edge_case_testing" action="delegate"/>
|
|
||||||
<condition id="user_request" trigger="explicit_delegation" action="delegate"/>
|
|
||||||
</delegate_when>
|
|
||||||
|
|
||||||
<execute_directly_when>
|
|
||||||
<condition trigger="single_file_simple_change"/>
|
|
||||||
<condition trigger="straightforward_enhancement"/>
|
|
||||||
<condition trigger="clear_bug_fix"/>
|
|
||||||
</execute_directly_when>
|
|
||||||
|
|
||||||
<specialized_routing>
|
|
||||||
<route to="subagents/core/task-manager" when="complex_feature_breakdown">
|
|
||||||
<trigger>Complex feature requiring task breakdown OR multi-step dependencies OR user requests task planning</trigger>
|
|
||||||
<context_bundle>
|
|
||||||
Create .tmp/context/{session-id}/bundle.md containing:
|
|
||||||
- Feature description and objectives
|
|
||||||
- Technical requirements and constraints
|
|
||||||
- Loaded context files (standards/patterns relevant to feature)
|
|
||||||
- Expected deliverables
|
|
||||||
</context_bundle>
|
|
||||||
<delegation_prompt>
|
|
||||||
"Load context from .tmp/context/{session-id}/bundle.md.
|
|
||||||
Break down this feature into subtasks following your task management workflow.
|
|
||||||
Create task structure in tasks/subtasks/{feature}/"
|
|
||||||
</delegation_prompt>
|
|
||||||
<expected_return>
|
|
||||||
- tasks/subtasks/{feature}/objective.md (feature index)
|
|
||||||
- tasks/subtasks/{feature}/{seq}-{task}.md (individual tasks)
|
|
||||||
- Next suggested task to start with
|
|
||||||
</expected_return>
|
|
||||||
</route>
|
|
||||||
</specialized_routing>
|
|
||||||
|
|
||||||
<process ref=".opencode/context/core/workflows/delegation.md">Full delegation template & process</process>
|
|
||||||
</delegation_rules>
|
|
||||||
|
|
||||||
<principles>
|
|
||||||
<lean>Concise responses, no over-explain</lean>
|
|
||||||
<adaptive>Conversational for questions, formal for tasks</adaptive>
|
|
||||||
<minimal_overhead>Create session files only when delegating</minimal_overhead>
|
|
||||||
<safe enforce="@critical_context_requirement @critical_rules">Safety first - context loading, approval gates, stop on fail, confirm cleanup</safe>
|
|
||||||
<report_first enforce="@report_first">Never auto-fix - always report & req approval</report_first>
|
|
||||||
<transparent>Explain decisions, show reasoning when helpful</transparent>
|
|
||||||
</principles>
|
|
||||||
|
|
||||||
<static_context>
|
|
||||||
Context index: .opencode/context/index.md
|
|
||||||
|
|
||||||
Load index when discovering contexts by keywords. For common tasks:
|
|
||||||
- Code tasks → .opencode/context/core/standards/code.md
|
|
||||||
- Docs tasks → .opencode/context/core/standards/docs.md
|
|
||||||
- Tests tasks → .opencode/context/core/standards/tests.md
|
|
||||||
- Review tasks → .opencode/context/core/workflows/review.md
|
|
||||||
- Delegation → .opencode/context/core/workflows/delegation.md
|
|
||||||
|
|
||||||
Full index includes all contexts with triggers and dependencies.
|
|
||||||
Context files loaded per @critical_context_requirement.
|
|
||||||
</static_context>
|
|
||||||
|
|
||||||
<constraints enforcement="absolute">
|
|
||||||
These constraints override all other considerations:
|
|
||||||
|
|
||||||
1. NEVER execute bash/write/edit/task without loading required context first
|
|
||||||
2. NEVER skip step 3.1 (LoadContext) for efficiency or speed
|
|
||||||
3. NEVER assume a task is "too simple" to need context
|
|
||||||
4. ALWAYS use Read tool to load context files before execution
|
|
||||||
5. ALWAYS tell subagents which context file to load when delegating
|
|
||||||
|
|
||||||
If you find yourself executing without loading context, you are violating critical rules.
|
|
||||||
Context loading is MANDATORY, not optional.
|
|
||||||
</constraints>
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
---
|
|
||||||
# OpenCode Agent Configuration
|
|
||||||
description: "Multi-language implementation agent for modular and functional development"
|
|
||||||
mode: primary
|
|
||||||
temperature: 0.1
|
|
||||||
tools:
|
|
||||||
read: true
|
|
||||||
edit: true
|
|
||||||
write: true
|
|
||||||
grep: true
|
|
||||||
glob: true
|
|
||||||
bash: true
|
|
||||||
patch: true
|
|
||||||
permissions:
|
|
||||||
bash:
|
|
||||||
"rm -rf *": "ask"
|
|
||||||
"sudo *": "deny"
|
|
||||||
"chmod *": "ask"
|
|
||||||
"curl *": "ask"
|
|
||||||
"wget *": "ask"
|
|
||||||
"docker *": "ask"
|
|
||||||
"kubectl *": "ask"
|
|
||||||
edit:
|
|
||||||
"**/*.env*": "deny"
|
|
||||||
"**/*.key": "deny"
|
|
||||||
"**/*.secret": "deny"
|
|
||||||
"node_modules/**": "deny"
|
|
||||||
"**/__pycache__/**": "deny"
|
|
||||||
"**/*.pyc": "deny"
|
|
||||||
".git/**": "deny"
|
|
||||||
|
|
||||||
# Prompt Metadata
|
|
||||||
model_family: "claude"
|
|
||||||
recommended_models:
|
|
||||||
- "anthropic/claude-sonnet-4-5" # Primary recommendation
|
|
||||||
- "anthropic/claude-3-5-sonnet-20241022" # Alternative
|
|
||||||
tested_with: "anthropic/claude-sonnet-4-5"
|
|
||||||
last_tested: "2025-12-04"
|
|
||||||
maintainer: "darrenhinde"
|
|
||||||
status: "stable"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Development Agent
|
|
||||||
Always start with phrase "DIGGING IN..."
|
|
||||||
|
|
||||||
## Available Subagents (invoke via task tool)
|
|
||||||
|
|
||||||
- `subagents/core/task-manager` - Feature breakdown (4+ files, >60 min)
|
|
||||||
- `subagents/code/coder-agent` - Simple implementations
|
|
||||||
- `subagents/code/tester` - Testing after implementation
|
|
||||||
- `subagents/core/documentation` - Documentation generation
|
|
||||||
|
|
||||||
**Invocation syntax**:
|
|
||||||
```javascript
|
|
||||||
task(
|
|
||||||
subagent_type="subagents/core/task-manager",
|
|
||||||
description="Brief description",
|
|
||||||
prompt="Detailed instructions for the subagent"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Focus:
|
|
||||||
You are a coding specialist focused on writing clean, maintainable, and scalable code. Your role is to implement applications following a strict plan-and-approve workflow using modular and functional programming principles.
|
|
||||||
|
|
||||||
Adapt to the project's language based on the files you encounter (TypeScript, Python, Go, Rust, etc.).
|
|
||||||
|
|
||||||
Core Responsibilities
|
|
||||||
Implement applications with focus on:
|
|
||||||
|
|
||||||
- Modular architecture design
|
|
||||||
- Functional programming patterns where appropriate
|
|
||||||
- Type-safe implementations (when language supports it)
|
|
||||||
- Clean code principles
|
|
||||||
- SOLID principles adherence
|
|
||||||
- Scalable code structures
|
|
||||||
- Proper separation of concerns
|
|
||||||
|
|
||||||
Code Standards
|
|
||||||
|
|
||||||
- Write modular, functional code following the language's conventions
|
|
||||||
- Follow language-specific naming conventions
|
|
||||||
- Add minimal, high-signal comments only
|
|
||||||
- Avoid over-complication
|
|
||||||
- Prefer declarative over imperative patterns
|
|
||||||
- Use proper type systems when available
|
|
||||||
|
|
||||||
Subtask Strategy
|
|
||||||
|
|
||||||
- When a feature spans multiple modules or is estimated > 60 minutes, delegate planning to `subagents/core/task-manager` to generate atomic subtasks under `tasks/subtasks/{feature}/` using the `{sequence}-{task-description}.md` pattern and a feature `README.md` index.
|
|
||||||
- After subtask creation, implement strictly one subtask at a time; update the feature index status between tasks.
|
|
||||||
|
|
||||||
Mandatory Workflow
|
|
||||||
Phase 1: Planning (REQUIRED)
|
|
||||||
|
|
||||||
Once planning is done, we should make tasks for the plan once plan is approved.
|
|
||||||
So pass it to the `subagents/core/task-manager` to make tasks for the plan.
|
|
||||||
|
|
||||||
ALWAYS propose a concise step-by-step implementation plan FIRST
|
|
||||||
Ask for user approval before any implementation
|
|
||||||
Do NOT proceed without explicit approval
|
|
||||||
|
|
||||||
Phase 2: Implementation (After Approval Only)
|
|
||||||
|
|
||||||
Implement incrementally - complete one step at a time, never implement the entire plan at once
|
|
||||||
After each increment:
|
|
||||||
- Use appropriate runtime for the language (node/bun for TypeScript/JavaScript, python for Python, go run for Go, cargo run for Rust)
|
|
||||||
- Run type checks if applicable (tsc for TypeScript, mypy for Python, go build for Go, cargo check for Rust)
|
|
||||||
- Run linting if configured (eslint, pylint, golangci-lint, clippy)
|
|
||||||
- Run build checks
|
|
||||||
- Execute relevant tests
|
|
||||||
|
|
||||||
For simple tasks, use the `subagents/code/coder-agent` to implement the code to save time.
|
|
||||||
|
|
||||||
Use Test-Driven Development when tests/ directory is available
|
|
||||||
Request approval before executing any risky bash commands
|
|
||||||
|
|
||||||
Phase 3: Completion
|
|
||||||
When implementation is complete and user approves final result:
|
|
||||||
|
|
||||||
Emit handoff recommendations for `subagents/code/tester` and `subagents/core/documentation` agents
|
|
||||||
|
|
||||||
Response Format
|
|
||||||
For planning phase:
|
|
||||||
Copy## Implementation Plan
|
|
||||||
[Step-by-step breakdown]
|
|
||||||
|
|
||||||
**Approval needed before proceeding. Please review and confirm.**
|
|
||||||
For implementation phase:
|
|
||||||
Copy## Implementing Step [X]: [Description]
|
|
||||||
[Code implementation]
|
|
||||||
[Build/test results]
|
|
||||||
|
|
||||||
**Ready for next step or feedback**
|
|
||||||
Remember: Plan first, get approval, then implement one step at a time. Never implement everything at once.
|
|
||||||
Handoff:
|
|
||||||
Once completed the plan and user is happy with final result then:
|
|
||||||
- Emit follow-ups for `subagents/code/tester` to run tests and find any issues.
|
|
||||||
- Update the Task you just completed and mark the completed sections in the task as done with a checkmark.
|
|
||||||
|
|
||||||
|
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
0.0.2
|
0.3.0
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
Thank you for your interest in contributing! This guide will help you add new components to the registry and understand the repository structure.
|
Thank you for your interest in contributing! This guide will help you add new components to the registry and understand the repository structure.
|
||||||
|
|
||||||
|
## 📚 Documentation
|
||||||
|
|
||||||
|
- **[Development Guide](DEVELOPMENT.md)** - Complete guide for developing on this repo (agents, commands, tools, testing)
|
||||||
|
- **[Agent Creation System](../../.opencode/command/openagents/new-agents/README.md)** - ⭐ NEW: Research-backed agent creation with templates
|
||||||
|
- **[Code of Conduct](CODE_OF_CONDUCT.md)** - Community guidelines
|
||||||
|
- **[Adding Evaluators](ADDING_EVALUATOR.md)** - How to add new test evaluators
|
||||||
|
|
||||||
## Repository Structure
|
## Repository Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -187,15 +194,21 @@ OpenCode uses a model-specific prompt library to support different AI models whi
|
||||||
├── agent/ # Active prompts (always default in PRs)
|
├── agent/ # Active prompts (always default in PRs)
|
||||||
│ ├── openagent.md
|
│ ├── openagent.md
|
||||||
│ └── opencoder.md
|
│ └── opencoder.md
|
||||||
└── prompts/ # Prompt library (variants and experiments)
|
└── prompts/ # Prompt library (model-specific variants)
|
||||||
├── openagent/
|
├── openagent/
|
||||||
│ ├── default.md # Stable version (enforced in PRs)
|
│ ├── gpt.md # GPT-4 optimized
|
||||||
│ ├── sonnet-4.md # Experimental variants
|
│ ├── gemini.md # Gemini optimized
|
||||||
|
│ ├── grok.md # Grok optimized
|
||||||
|
│ ├── llama.md # Llama/OSS optimized
|
||||||
│ ├── TEMPLATE.md # Template for new variants
|
│ ├── TEMPLATE.md # Template for new variants
|
||||||
│ ├── README.md # Capabilities table
|
│ ├── README.md # Capabilities table
|
||||||
│ └── results/ # Test results
|
│ └── results/ # Test results (all variants)
|
||||||
└── opencoder/
|
└── opencoder/
|
||||||
└── ...
|
└── ...
|
||||||
|
|
||||||
|
**Architecture:**
|
||||||
|
- Agent files (`.opencode/agent/*.md`) = Canonical defaults
|
||||||
|
- Prompt variants (`.opencode/prompts/<agent>/<model>.md`) = Model-specific optimizations
|
||||||
```
|
```
|
||||||
|
|
||||||
### For Contributors
|
### For Contributors
|
||||||
|
|
@ -270,20 +283,21 @@ When a variant proves superior:
|
||||||
cat .opencode/prompts/openagent/results/variant-results.json
|
cat .opencode/prompts/openagent/results/variant-results.json
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Update default:**
|
2. **Update agent file (canonical default):**
|
||||||
```bash
|
```bash
|
||||||
cp .opencode/prompts/openagent/variant.md .opencode/prompts/openagent/default.md
|
cp .opencode/prompts/openagent/variant.md .opencode/agent/openagent.md
|
||||||
cp .opencode/prompts/openagent/default.md .opencode/agent/openagent.md
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Update capabilities table** in README
|
3. **Update capabilities table** in README
|
||||||
|
|
||||||
4. **Commit with clear message:**
|
4. **Commit with clear message:**
|
||||||
```bash
|
```bash
|
||||||
git add .opencode/prompts/openagent/default.md .opencode/agent/openagent.md
|
git add .opencode/agent/openagent.md
|
||||||
git commit -m "Promote variant to default: improved X by Y%"
|
git commit -m "feat(openagent): promote variant to default - improved X by Y%"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note:** In the new architecture, agent files are the canonical defaults. There are no `default.md` files in the prompts directory.
|
||||||
|
|
||||||
## Pull Request Guidelines
|
## Pull Request Guidelines
|
||||||
|
|
||||||
### PR Title Format
|
### PR Title Format
|
||||||
|
|
@ -369,11 +383,60 @@ You don't need to manually edit `registry.json`!
|
||||||
- Use meaningful variable names
|
- Use meaningful variable names
|
||||||
- Include help text
|
- Include help text
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
### Creating a New Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Use the automated system (recommended)
|
||||||
|
/create-agent my-agent-name
|
||||||
|
|
||||||
|
# Or manually follow the development guide
|
||||||
|
# See: docs/contributing/DEVELOPMENT.md#creating-new-agents
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent=my-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validating Before PR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Validate structure
|
||||||
|
./scripts/registry/validate-component.sh
|
||||||
|
|
||||||
|
# Ensure using defaults
|
||||||
|
./scripts/prompts/validate-pr.sh
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cd evals/framework && npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List available components
|
||||||
|
./install.sh --list
|
||||||
|
|
||||||
|
# Validate registry
|
||||||
|
make validate-registry
|
||||||
|
|
||||||
|
# Update registry
|
||||||
|
make update-registry
|
||||||
|
|
||||||
|
# Test a prompt variant
|
||||||
|
./scripts/prompts/test-prompt.sh openagent my-variant
|
||||||
|
```
|
||||||
|
|
||||||
## Questions?
|
## Questions?
|
||||||
|
|
||||||
- **Issues**: Open an issue for bugs or feature requests
|
- **Issues**: Open an issue for bugs or feature requests
|
||||||
- **Discussions**: Use GitHub Discussions for questions
|
- **Discussions**: Use GitHub Discussions for questions
|
||||||
- **Security**: Email security issues privately
|
- **Security**: Email security issues privately
|
||||||
|
- **Development Help**: See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed guides
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
760
docs/contributing/DEVELOPMENT.md
Normal file
760
docs/contributing/DEVELOPMENT.md
Normal file
|
|
@ -0,0 +1,760 @@
|
||||||
|
# Development Guide
|
||||||
|
|
||||||
|
**Complete guide for developing on the OpenAgents repository**
|
||||||
|
|
||||||
|
This guide covers everything you need to know to develop agents, commands, tools, and contribute to the OpenAgents ecosystem.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [Repository Structure](#repository-structure)
|
||||||
|
- [Development Workflow](#development-workflow)
|
||||||
|
- [Creating New Agents](#creating-new-agents)
|
||||||
|
- [Testing](#testing)
|
||||||
|
- [Best Practices](#best-practices)
|
||||||
|
- [Common Tasks](#common-tasks)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- **OpenCode CLI** installed ([installation guide](https://opencode.ai/docs))
|
||||||
|
- **Node.js** 18+ (for testing framework)
|
||||||
|
- **Git** for version control
|
||||||
|
- **Bash** (macOS/Linux) or **Git Bash** (Windows)
|
||||||
|
|
||||||
|
### Clone and Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone https://github.com/darrenhinde/OpenAgents.git
|
||||||
|
cd OpenAgents
|
||||||
|
|
||||||
|
# Install dependencies for testing framework
|
||||||
|
cd evals/framework
|
||||||
|
npm install
|
||||||
|
cd ../..
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Validate registry
|
||||||
|
make validate-registry
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cd evals/framework
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
opencode-agents/
|
||||||
|
├── .opencode/ # OpenCode configuration
|
||||||
|
│ ├── agent/ # Agent prompts
|
||||||
|
│ │ ├── openagent.md # Main orchestrator (plan-first)
|
||||||
|
│ │ ├── opencoder.md # Development specialist
|
||||||
|
│ │ └── subagents/ # Specialized subagents
|
||||||
|
│ │ ├── code/ # Code-related subagents
|
||||||
|
│ │ ├── core/ # Core functionality subagents
|
||||||
|
│ │ ├── system-builder/ # System building subagents
|
||||||
|
│ │ └── utils/ # Utility subagents
|
||||||
|
│ ├── command/ # Slash commands
|
||||||
|
│ │ ├── openagents/ # OpenAgents-specific commands
|
||||||
|
│ │ │ └── new-agents/ # Agent creation system ⭐
|
||||||
|
│ │ └── prompt-engineering/ # Prompt optimization commands
|
||||||
|
│ ├── context/ # Context files
|
||||||
|
│ │ ├── core/ # Core context (standards, workflows)
|
||||||
|
│ │ ├── project/ # Project-specific context
|
||||||
|
│ │ └── system-builder-templates/ # Templates
|
||||||
|
│ ├── plugin/ # Plugins and integrations
|
||||||
|
│ ├── prompts/ # Prompt library (model variants)
|
||||||
|
│ │ ├── openagent/ # OpenAgent variants
|
||||||
|
│ │ └── opencoder/ # OpenCoder variants
|
||||||
|
│ └── tool/ # Utility tools
|
||||||
|
├── evals/ # Testing framework
|
||||||
|
│ ├── agents/ # Agent test suites
|
||||||
|
│ │ ├── openagent/ # OpenAgent tests
|
||||||
|
│ │ └── opencoder/ # OpenCoder tests
|
||||||
|
│ ├── framework/ # Test framework code
|
||||||
|
│ │ ├── src/ # Framework source
|
||||||
|
│ │ └── scripts/ # Test utilities
|
||||||
|
│ └── results/ # Test results
|
||||||
|
├── scripts/ # Automation scripts
|
||||||
|
│ ├── registry/ # Registry management
|
||||||
|
│ ├── prompts/ # Prompt management
|
||||||
|
│ └── testing/ # Test utilities
|
||||||
|
├── docs/ # Documentation
|
||||||
|
│ ├── agents/ # Agent documentation
|
||||||
|
│ ├── contributing/ # Contribution guides
|
||||||
|
│ ├── features/ # Feature documentation
|
||||||
|
│ └── guides/ # User guides
|
||||||
|
└── registry.json # Component registry
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Directories Explained
|
||||||
|
|
||||||
|
#### `.opencode/agent/`
|
||||||
|
Main agent prompts. These are the "brains" of the system:
|
||||||
|
- **openagent.md** - Main orchestrator with plan-first workflow
|
||||||
|
- **opencoder.md** - Development specialist for direct code execution
|
||||||
|
- **subagents/** - Specialized helpers for specific tasks
|
||||||
|
|
||||||
|
#### `.opencode/command/`
|
||||||
|
Slash commands that users can invoke:
|
||||||
|
- **openagents/new-agents/** - ⭐ **NEW**: Agent creation system with research-backed principles
|
||||||
|
- **prompt-engineering/** - Prompt optimization tools
|
||||||
|
|
||||||
|
#### `.opencode/context/`
|
||||||
|
Context files that agents load on-demand:
|
||||||
|
- **core/** - Standards, patterns, workflows
|
||||||
|
- **project/** - Project-specific context (CLAUDE.md pattern)
|
||||||
|
|
||||||
|
#### `.opencode/prompts/`
|
||||||
|
Prompt library with model-specific variants:
|
||||||
|
- Allows experimentation without breaking main branch
|
||||||
|
- Each variant has test results documented
|
||||||
|
|
||||||
|
#### `evals/`
|
||||||
|
Comprehensive testing framework:
|
||||||
|
- **agents/** - Test suites for each agent (8 essential tests)
|
||||||
|
- **framework/** - Testing infrastructure
|
||||||
|
- **results/** - Test results and reports
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### 1. Create a Feature Branch
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/my-new-feature
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Make Your Changes
|
||||||
|
|
||||||
|
Follow the appropriate guide:
|
||||||
|
- [Creating New Agents](#creating-new-agents)
|
||||||
|
- [Adding Commands](#adding-commands)
|
||||||
|
- [Adding Tools](#adding-tools)
|
||||||
|
- [Writing Tests](#writing-tests)
|
||||||
|
|
||||||
|
### 3. Test Your Changes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Validate structure
|
||||||
|
./scripts/registry/validate-component.sh
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent=your-agent
|
||||||
|
|
||||||
|
# Test manually
|
||||||
|
opencode --agent=your-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Commit and Push
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: add new feature"
|
||||||
|
git push origin feature/my-new-feature
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Create Pull Request
|
||||||
|
|
||||||
|
- Use conventional commit format in PR title
|
||||||
|
- Fill out PR template completely
|
||||||
|
- Ensure CI passes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Creating New Agents
|
||||||
|
|
||||||
|
### ⭐ NEW: Research-Backed Agent Creation System
|
||||||
|
|
||||||
|
We now have a streamlined system for creating agents following **Anthropic 2025 research best practices**.
|
||||||
|
|
||||||
|
#### Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Use the agent creation command
|
||||||
|
/create-agent my-agent-name
|
||||||
|
|
||||||
|
# Or invoke directly
|
||||||
|
opencode "Create a new agent called 'python-dev' for Python development"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### What Gets Created
|
||||||
|
|
||||||
|
The system generates:
|
||||||
|
1. **Minimal agent prompt** (~500 tokens at "right altitude")
|
||||||
|
2. **Project context file** (CLAUDE.md pattern)
|
||||||
|
3. **8 comprehensive tests** (planning, context, incremental, tools, errors, thinking, compaction, completion)
|
||||||
|
4. **Test configuration**
|
||||||
|
5. **Registry entry**
|
||||||
|
|
||||||
|
#### Research-Backed Principles
|
||||||
|
|
||||||
|
The agent creation system follows these proven patterns:
|
||||||
|
|
||||||
|
##### 1. Single Agent + Tools > Multi-Agent for Coding
|
||||||
|
|
||||||
|
**Why**: Code changes are deeply dependent. Sub-agents can't coordinate edits to the same file.
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Use ONE lead agent with tool-based sub-functions
|
||||||
|
- NOT autonomous sub-agents for coding
|
||||||
|
- Multi-agent only for truly independent tasks (static analysis, test execution, code search)
|
||||||
|
|
||||||
|
##### 2. Minimal Prompts at "Right Altitude" (~500 tokens)
|
||||||
|
|
||||||
|
**Why**: "Find the smallest possible set of high-signal tokens that maximize likelihood of desired outcome"
|
||||||
|
|
||||||
|
**The Balance**:
|
||||||
|
| Too Vague | Right Altitude ✅ | Too Rigid |
|
||||||
|
|-----------|------------------|-----------|
|
||||||
|
| "Write good code" | Clear heuristics + examples | 50-line prompt with edge cases |
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Clear heuristics, not exhaustive rules
|
||||||
|
- Examples > edge case lists
|
||||||
|
- Show ONE canonical example, not 20 scenarios
|
||||||
|
|
||||||
|
##### 3. Just-in-Time Context Loading
|
||||||
|
|
||||||
|
**Why**: Prevents "drowning in irrelevant information"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Tools load context on demand (not pre-loaded)
|
||||||
|
- CLAUDE.md pattern for project context
|
||||||
|
- File metadata guides behavior
|
||||||
|
|
||||||
|
##### 4. Tool Clarity
|
||||||
|
|
||||||
|
**Why**: "Tool ambiguity is one of the biggest failure modes"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
```markdown
|
||||||
|
<tool name="read_file">
|
||||||
|
<purpose>Load specific file for analysis or modification</purpose>
|
||||||
|
<when_to_use>You need to examine or edit a file</when_to_use>
|
||||||
|
<when_not_to_use>You already have the file content in context</when_not_to_use>
|
||||||
|
</tool>
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 5. Extended Thinking for Complex Tasks
|
||||||
|
|
||||||
|
**Why**: Improved instruction-following and reasoning efficiency
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Trigger thinking before complex tasks
|
||||||
|
- "Think hard about how to approach this problem..."
|
||||||
|
- Phrases mapped to thinking budget (think, think hard, think harder)
|
||||||
|
|
||||||
|
##### 6. Compaction for Long Sessions
|
||||||
|
|
||||||
|
**Why**: Maintain context efficiency over long-horizon tasks
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Agent writes notes to persistent memory
|
||||||
|
- Summarizes when context fills
|
||||||
|
- Preserves: architectural decisions, unresolved bugs, implementation details
|
||||||
|
- Discards: redundant tool outputs
|
||||||
|
|
||||||
|
##### 7. Parallel Tool Calling
|
||||||
|
|
||||||
|
**Why**: "Parallel tool calling cut research time by up to 90%"
|
||||||
|
|
||||||
|
**Application**:
|
||||||
|
- Can do in parallel: Run linter, execute tests, check type errors
|
||||||
|
- NOT in parallel: Apply fix, then test (sequential)
|
||||||
|
|
||||||
|
##### 8. Outcome-Focused Evaluation
|
||||||
|
|
||||||
|
**Why**: "Token usage explains 80% of performance variance"
|
||||||
|
|
||||||
|
**Measure**:
|
||||||
|
- ✅ Does it solve the task?
|
||||||
|
- ✅ Token usage reasonable?
|
||||||
|
- ✅ Tool calls appropriate?
|
||||||
|
- ❌ NOT: "Did it follow exact steps I imagined?"
|
||||||
|
|
||||||
|
#### Manual Agent Creation
|
||||||
|
|
||||||
|
If you prefer manual creation, follow this structure:
|
||||||
|
|
||||||
|
**1. Create Agent File** (`.opencode/agent/my-agent.md`)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
description: "Brief one-line description"
|
||||||
|
mode: primary
|
||||||
|
temperature: 0.1
|
||||||
|
tools:
|
||||||
|
read: true
|
||||||
|
write: true
|
||||||
|
edit: true
|
||||||
|
bash: true
|
||||||
|
glob: true
|
||||||
|
grep: true
|
||||||
|
permissions:
|
||||||
|
bash:
|
||||||
|
"rm -rf *": "ask"
|
||||||
|
"sudo *": "deny"
|
||||||
|
edit:
|
||||||
|
"**/*.env*": "deny"
|
||||||
|
"**/*.key": "deny"
|
||||||
|
---
|
||||||
|
|
||||||
|
# My Agent
|
||||||
|
|
||||||
|
<role>
|
||||||
|
Clear, concise role - what this agent does
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<approach>
|
||||||
|
1. Read and understand the context
|
||||||
|
2. Think about the approach before acting
|
||||||
|
3. Implement changes incrementally
|
||||||
|
4. Verify each step with appropriate tools
|
||||||
|
5. Complete with clear summary
|
||||||
|
</approach>
|
||||||
|
|
||||||
|
<heuristics>
|
||||||
|
- Decompose problems before implementing
|
||||||
|
- Use tools intentionally (not speculatively)
|
||||||
|
- Verify outputs before claiming completion
|
||||||
|
- Stop on errors and report (don't auto-fix blindly)
|
||||||
|
</heuristics>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
Always include:
|
||||||
|
- What you did
|
||||||
|
- Why you did it that way
|
||||||
|
- Test/validation results
|
||||||
|
</output>
|
||||||
|
|
||||||
|
<examples>
|
||||||
|
<example name="Typical Use Case">
|
||||||
|
**User**: "typical request"
|
||||||
|
|
||||||
|
**Agent**:
|
||||||
|
1. Read relevant files
|
||||||
|
2. Think about approach
|
||||||
|
3. Implement change
|
||||||
|
4. Verify
|
||||||
|
|
||||||
|
**Result**: Expected outcome
|
||||||
|
</example>
|
||||||
|
</examples>
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Create Context File** (`.opencode/context/project/my-agent-context.md`)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# My Agent Context
|
||||||
|
|
||||||
|
## Key Commands
|
||||||
|
- command 1: what it does
|
||||||
|
- command 2: what it does
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
- path pattern: what goes here
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
- style rule 1
|
||||||
|
- style rule 2
|
||||||
|
|
||||||
|
## Workflow Rules
|
||||||
|
- workflow rule 1
|
||||||
|
- workflow rule 2
|
||||||
|
|
||||||
|
## Before Committing
|
||||||
|
1. check 1
|
||||||
|
2. check 2
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Create Test Suite**
|
||||||
|
|
||||||
|
Use the test generator:
|
||||||
|
```bash
|
||||||
|
/create-tests my-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
Or manually create 8 tests in `evals/agents/my-agent/tests/`:
|
||||||
|
1. `planning/planning-approval-001.yaml`
|
||||||
|
2. `context-loading/context-before-code-001.yaml`
|
||||||
|
3. `implementation/incremental-001.yaml`
|
||||||
|
4. `implementation/tool-usage-001.yaml`
|
||||||
|
5. `error-handling/stop-on-failure-001.yaml`
|
||||||
|
6. `implementation/extended-thinking-001.yaml`
|
||||||
|
7. `long-horizon/compaction-001.yaml`
|
||||||
|
8. `completion/handoff-001.yaml`
|
||||||
|
|
||||||
|
**4. Register Agent**
|
||||||
|
|
||||||
|
The registry auto-updates on merge to main, or manually:
|
||||||
|
```bash
|
||||||
|
./scripts/registry/register-component.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Templates
|
||||||
|
|
||||||
|
Pre-built templates are available in:
|
||||||
|
```
|
||||||
|
.opencode/command/openagents/new-agents/templates/
|
||||||
|
├── agent-template.md # Minimal agent template
|
||||||
|
├── context-template.md # CLAUDE.md pattern
|
||||||
|
├── test-config-template.yaml # Test configuration
|
||||||
|
└── test-*.yaml # 8 test templates
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adding Commands
|
||||||
|
|
||||||
|
Commands are slash commands users can invoke.
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
description: "What this command does"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Command Name
|
||||||
|
|
||||||
|
<target_argument> $ARGUMENTS </target_argument>
|
||||||
|
|
||||||
|
<role>
|
||||||
|
What this command specializes in
|
||||||
|
</role>
|
||||||
|
|
||||||
|
<task>
|
||||||
|
Specific objective of this command
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<workflow>
|
||||||
|
<step_1>
|
||||||
|
Action and process
|
||||||
|
</step_1>
|
||||||
|
|
||||||
|
<step_2>
|
||||||
|
Action and process
|
||||||
|
</step_2>
|
||||||
|
</workflow>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
See `.opencode/command/openagents/new-agents/create-agent.md` for a complete example.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adding Tools
|
||||||
|
|
||||||
|
Tools are TypeScript utilities that agents can use.
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* Tool Name
|
||||||
|
*
|
||||||
|
* Brief description of what this tool does
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function myTool(param: string): string {
|
||||||
|
// Implementation
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Location
|
||||||
|
|
||||||
|
Place tools in `.opencode/tool/my-tool/index.ts`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Test Framework
|
||||||
|
|
||||||
|
We use a comprehensive evaluation framework in `evals/framework/`.
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
cd evals/framework
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Run tests for specific agent
|
||||||
|
npm test -- --agent=openagent
|
||||||
|
|
||||||
|
# Run specific category
|
||||||
|
npm test -- --agent=openagent --category=planning
|
||||||
|
|
||||||
|
# Run single test
|
||||||
|
npm test -- --agent=openagent --test=planning-approval-001
|
||||||
|
|
||||||
|
# Verbose output
|
||||||
|
npm test -- --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
### Writing Tests
|
||||||
|
|
||||||
|
Each agent should have 8 essential test types:
|
||||||
|
|
||||||
|
1. **Planning & Approval** - Verify plan-first approach
|
||||||
|
2. **Context Loading** - Ensure just-in-time context retrieval
|
||||||
|
3. **Incremental Implementation** - Verify step-by-step execution
|
||||||
|
4. **Tool Usage** - Check correct tool selection
|
||||||
|
5. **Error Handling** - Verify stop-on-failure behavior
|
||||||
|
6. **Extended Thinking** - Check decomposition before coding
|
||||||
|
7. **Compaction** - Verify long session handling
|
||||||
|
8. **Completion** - Check proper output and handoff
|
||||||
|
|
||||||
|
### Test Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: test-id-001
|
||||||
|
name: Test Name
|
||||||
|
description: |
|
||||||
|
What this test verifies
|
||||||
|
|
||||||
|
category: planning
|
||||||
|
agent: my-agent
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Test prompt
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
mustContain:
|
||||||
|
- "expected text"
|
||||||
|
mustNotContain:
|
||||||
|
- "forbidden text"
|
||||||
|
mustUseAnyOf: [[tool1], [tool2]]
|
||||||
|
minToolCalls: 1
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: rule-name
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 30000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- tag1
|
||||||
|
- tag2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Templates
|
||||||
|
|
||||||
|
Use the templates in `.opencode/command/openagents/new-agents/templates/` as starting points.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Agent Design
|
||||||
|
|
||||||
|
✅ **Do**:
|
||||||
|
- Keep system prompts minimal (~500 tokens)
|
||||||
|
- Use clear heuristics, not exhaustive rules
|
||||||
|
- Provide ONE canonical example
|
||||||
|
- Define tools with clear purpose and when to use/not use
|
||||||
|
- Load context on-demand (just-in-time)
|
||||||
|
- Measure outcomes: Does it solve the task?
|
||||||
|
|
||||||
|
❌ **Don't**:
|
||||||
|
- Create sub-agents for dependent tasks (code is sequential)
|
||||||
|
- Pre-load entire codebase into context
|
||||||
|
- Write exhaustive edge case lists in prompts
|
||||||
|
- Give vague tool descriptions
|
||||||
|
- Use multi-agent if you could use single agent + tools
|
||||||
|
- Minimize tool calls (some redundancy is fine)
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
|
#### Markdown
|
||||||
|
- Use clear, concise language
|
||||||
|
- Include examples
|
||||||
|
- Add code blocks with syntax highlighting
|
||||||
|
- Use proper heading hierarchy
|
||||||
|
|
||||||
|
#### TypeScript
|
||||||
|
- Follow existing code style
|
||||||
|
- Add JSDoc comments
|
||||||
|
- Use TypeScript types (no `any`)
|
||||||
|
- Export functions explicitly
|
||||||
|
|
||||||
|
#### Bash Scripts
|
||||||
|
- Use `set -e` for error handling
|
||||||
|
- Add comments for complex logic
|
||||||
|
- Use meaningful variable names
|
||||||
|
- Include help text
|
||||||
|
|
||||||
|
### File Naming
|
||||||
|
|
||||||
|
- **kebab-case** for file names: `my-new-agent.md`
|
||||||
|
- **PascalCase** for TypeScript types/interfaces
|
||||||
|
- **camelCase** for variables and functions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Tasks
|
||||||
|
|
||||||
|
### Update an Existing Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Edit the agent file
|
||||||
|
vim .opencode/agent/my-agent.md
|
||||||
|
|
||||||
|
# 2. Test changes
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent=my-agent
|
||||||
|
|
||||||
|
# 3. Update tests if needed
|
||||||
|
vim evals/agents/my-agent/tests/...
|
||||||
|
|
||||||
|
# 4. Commit
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: improve my-agent behavior"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add a New Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create test file
|
||||||
|
vim evals/agents/my-agent/tests/new-category/new-test-001.yaml
|
||||||
|
|
||||||
|
# 2. Update config
|
||||||
|
vim evals/agents/my-agent/config/config.yaml
|
||||||
|
# Add new category to testPaths
|
||||||
|
|
||||||
|
# 3. Run test
|
||||||
|
cd evals/framework
|
||||||
|
npm test -- --agent=my-agent --test=new-test-001
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create a Prompt Variant
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Copy template
|
||||||
|
cp .opencode/prompts/openagent/TEMPLATE.md .opencode/prompts/openagent/my-variant.md
|
||||||
|
|
||||||
|
# 2. Edit variant
|
||||||
|
vim .opencode/prompts/openagent/my-variant.md
|
||||||
|
|
||||||
|
# 3. Test variant
|
||||||
|
./scripts/prompts/test-prompt.sh openagent my-variant
|
||||||
|
|
||||||
|
# 4. Update README with results
|
||||||
|
vim .opencode/prompts/openagent/README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validate Before PR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Validate component structure
|
||||||
|
./scripts/registry/validate-component.sh
|
||||||
|
|
||||||
|
# Ensure using default prompts
|
||||||
|
./scripts/prompts/validate-pr.sh
|
||||||
|
|
||||||
|
# Run all tests
|
||||||
|
cd evals/framework
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Validate registry
|
||||||
|
make validate-registry
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Tests Failing
|
||||||
|
|
||||||
|
**Problem**: Tests fail after making changes
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
1. Check test output for specific failures
|
||||||
|
2. Run with `--verbose` flag for details
|
||||||
|
3. Verify agent follows expected behavior
|
||||||
|
4. Update tests if behavior intentionally changed
|
||||||
|
|
||||||
|
### Registry Validation Fails
|
||||||
|
|
||||||
|
**Problem**: `make validate-registry` fails
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
1. Check `registry.json` syntax
|
||||||
|
2. Ensure all referenced files exist
|
||||||
|
3. Verify frontmatter in agent files is valid YAML
|
||||||
|
4. Run `./scripts/registry/validate-component.sh` for details
|
||||||
|
|
||||||
|
### Agent Not Loading Context
|
||||||
|
|
||||||
|
**Problem**: Agent doesn't load context files
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
1. Verify context file exists in `.opencode/context/`
|
||||||
|
2. Check agent has `read` tool enabled
|
||||||
|
3. Ensure context file path is correct
|
||||||
|
4. Test with simple prompt that requires context
|
||||||
|
|
||||||
|
### Tool Not Working
|
||||||
|
|
||||||
|
**Problem**: Custom tool not accessible to agent
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
1. Verify tool is in `.opencode/tool/my-tool/index.ts`
|
||||||
|
2. Check tool is exported properly
|
||||||
|
3. Ensure agent has tool enabled in frontmatter
|
||||||
|
4. Rebuild if needed: `cd .opencode/tool && npm run build`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- [Contributing Guide](CONTRIBUTING.md) - General contribution guidelines
|
||||||
|
- [Agent Creation System](../../.opencode/command/openagents/new-agents/README.md) - Detailed agent creation guide
|
||||||
|
- [Research-Backed Prompt Design](../agents/research-backed-prompt-design.md) - Prompt engineering principles
|
||||||
|
- [Test Design Guide](../../evals/framework/docs/test-design-guide.md) - Writing effective tests
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
- [OpenAgent](../../.opencode/agent/openagent.md) - Main orchestrator example
|
||||||
|
- [OpenCoder](../../.opencode/agent/opencoder.md) - Development specialist example
|
||||||
|
- [Subagents](../../.opencode/agent/subagents/) - Specialized subagent examples
|
||||||
|
- [Test Suites](../../evals/agents/) - Comprehensive test examples
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
- [Agent Creation Command](../../.opencode/command/openagents/new-agents/create-agent.md)
|
||||||
|
- [Test Generator Command](../../.opencode/command/openagents/new-agents/create-tests.md)
|
||||||
|
- [Prompt Optimizer](../../.opencode/command/prompt-engineering/prompt-enhancer.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Questions?
|
||||||
|
|
||||||
|
- **Issues**: Open an issue for bugs or feature requests
|
||||||
|
- **Discussions**: Use GitHub Discussions for questions
|
||||||
|
- **Security**: Email security issues privately
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Happy developing! 🚀**
|
||||||
|
|
@ -37,6 +37,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: just do it phrase should skip approval requirement
|
description: just do it phrase should skip approval requirement
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read package.json before installing dependencies
|
||||||
|
|
||||||
# Approval strategy - auto-approve so the command actually runs
|
# Approval strategy - auto-approve so the command actually runs
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Agent should ask for approval before writing files
|
description: Agent should ask for approval before writing files
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: true
|
||||||
|
severity: warning
|
||||||
|
description: Likely writes without reading first (negative test)
|
||||||
|
|
||||||
# Approval strategy - auto-approve so we can see if agent asks first
|
# Approval strategy - auto-approve so we can see if agent asks first
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Agent should ask approval BEFORE execution, not after
|
description: Agent should ask approval BEFORE execution, not after
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: true
|
||||||
|
severity: warning
|
||||||
|
description: Executes immediately without reading (negative test)
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,11 @@ expectedViolations:
|
||||||
shouldViolate: false # Should NOT violate - correct workflow
|
shouldViolate: false # Should NOT violate - correct workflow
|
||||||
severity: error
|
severity: error
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should check if file/directory exists before writing
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@ expectedViolations:
|
||||||
shouldViolate: false
|
shouldViolate: false
|
||||||
severity: error
|
severity: error
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context before writing code
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must load code.md before writing code
|
description: Must load code.md before writing code
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context before writing code
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must load tests.md before writing tests
|
description: Must load tests.md before writing tests
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context and source code before writing tests
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Should delegate when 4+ files involved
|
description: Should delegate when 4+ files involved
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context before delegating via task tool
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must load standards.md and docs.md before writing
|
description: Must load standards.md and docs.md before writing
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read multiple context files before writing documentation
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must load standards.md and tests.md before writing
|
description: Must load standards.md and tests.md before writing
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read multiple context files before writing tests
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must load code.md for code tasks, not docs.md or tests.md
|
description: Must load code.md for code tasks, not docs.md or tests.md
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context before writing code
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,11 @@ expectedViolations:
|
||||||
shouldViolate: false # Should NOT violate - correct workflow
|
shouldViolate: false # Should NOT violate - correct workflow
|
||||||
severity: error
|
severity: error
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context before writing tests
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Agent should follow REPORT→PROPOSE→REQUEST→FIX workflow
|
description: Agent should follow REPORT→PROPOSE→REQUEST→FIX workflow
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should check project structure before running tests
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must STOP on test failure and NOT auto-fix
|
description: Must STOP on test failure and NOT auto-fix
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should check project structure before running tests
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ expectedViolations:
|
||||||
shouldViolate: false
|
shouldViolate: false
|
||||||
severity: error
|
severity: error
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should check project structure before running tests
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Agent should NOT auto-fix even when asked
|
description: Agent should NOT auto-fix even when asked
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: true
|
||||||
|
severity: warning
|
||||||
|
description: Auto-fix likely skips reading (negative test)
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Agent must ask for approval before running bash commands
|
description: Agent must ask for approval before running bash commands
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: May list directory before executing bash command
|
||||||
|
|
||||||
# Approval strategy for tool permissions
|
# Approval strategy for tool permissions
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ expectedViolations:
|
||||||
shouldViolate: false # Should NOT violate - bash is appropriate
|
shouldViolate: false # Should NOT violate - bash is appropriate
|
||||||
severity: warning
|
severity: warning
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should check package.json before installing dependencies
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,11 @@ expectedViolations:
|
||||||
severity: error
|
severity: error
|
||||||
description: Must load code.md before writing code
|
description: Must load code.md before writing code
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should read context before writing code
|
||||||
|
|
||||||
# Approval strategy
|
# Approval strategy
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,8 @@ expectedViolations:
|
||||||
shouldViolate: true
|
shouldViolate: true
|
||||||
severity: error
|
severity: error
|
||||||
description: Agent must request approval before execution despite user instruction to skip it
|
description: Agent must request approval before execution despite user instruction to skip it
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: true
|
||||||
|
severity: warning
|
||||||
|
description: Likely writes without reading (negative test)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,11 @@ expectedViolations:
|
||||||
shouldViolate: false
|
shouldViolate: false
|
||||||
severity: error
|
severity: error
|
||||||
|
|
||||||
|
- rule: execution-balance
|
||||||
|
shouldViolate: false
|
||||||
|
severity: warning
|
||||||
|
description: Should check if directory exists before creating file
|
||||||
|
|
||||||
approvalStrategy:
|
approvalStrategy:
|
||||||
type: auto-approve
|
type: auto-approve
|
||||||
|
|
||||||
|
|
|
||||||
346
evals/agents/opencoder/DEBUG_GUIDE.md
Normal file
346
evals/agents/opencoder/DEBUG_GUIDE.md
Normal file
|
|
@ -0,0 +1,346 @@
|
||||||
|
# OpenCoder Test Debugging Guide
|
||||||
|
|
||||||
|
Quick reference for debugging and validating opencoder tests.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
### Run Tests with Debug Mode
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd evals/framework
|
||||||
|
|
||||||
|
# Run single test with debug
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug
|
||||||
|
|
||||||
|
# Run all opencoder tests with debug
|
||||||
|
npm run eval:sdk -- --agent=opencoder --debug
|
||||||
|
|
||||||
|
# Run specific category
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="context-loading/*.yaml" --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Full Conversation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Run test with --debug flag
|
||||||
|
# 2. Copy session ID from output (e.g., "Session created: ses_4ff9f7975ffeWYqM564A5ooo4y")
|
||||||
|
# 3. View conversation:
|
||||||
|
|
||||||
|
./scripts/debug/show-test-conversation.sh ses_4ff9f7975ffeWYqM564A5ooo4y
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Where Test Data Lives
|
||||||
|
|
||||||
|
### Test Results
|
||||||
|
```bash
|
||||||
|
# Latest results (summary only)
|
||||||
|
cat evals/results/latest.json | jq '.'
|
||||||
|
|
||||||
|
# Historical results
|
||||||
|
ls -lt evals/results/history/2025-12/
|
||||||
|
|
||||||
|
# View specific result
|
||||||
|
cat evals/results/history/2025-12/08-235037-opencoder.json | jq '.'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Session Data (Full Conversations)
|
||||||
|
```bash
|
||||||
|
# Session messages
|
||||||
|
~/.local/share/opencode/storage/message/ses_XXXXX/*.json
|
||||||
|
|
||||||
|
# Message parts (tool calls, text, results)
|
||||||
|
~/.local/share/opencode/storage/part/msg_XXXXX/*.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Inspecting Sessions
|
||||||
|
|
||||||
|
### Find Recent Sessions
|
||||||
|
```bash
|
||||||
|
# List all sessions (most recent first)
|
||||||
|
ls -lt ~/.local/share/opencode/storage/message/ | head -20
|
||||||
|
|
||||||
|
# Find specific session
|
||||||
|
find ~/.local/share/opencode/storage/message -name "ses_*" -type d | grep "ses_4ff9f7975ffeWYqM564A5ooo4y"
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Session Messages
|
||||||
|
```bash
|
||||||
|
SESSION_ID="ses_4ff9f7975ffeWYqM564A5ooo4y"
|
||||||
|
|
||||||
|
# List all messages in session
|
||||||
|
ls -la ~/.local/share/opencode/storage/message/$SESSION_ID/
|
||||||
|
|
||||||
|
# View message content
|
||||||
|
cat ~/.local/share/opencode/storage/message/$SESSION_ID/msg_*.json | jq '.summary.body'
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Tool Calls
|
||||||
|
```bash
|
||||||
|
MESSAGE_ID="msg_b006086a5001CXI2Ks0mFkyPxU"
|
||||||
|
|
||||||
|
# List message parts
|
||||||
|
ls -la ~/.local/share/opencode/storage/part/$MESSAGE_ID/
|
||||||
|
|
||||||
|
# View all parts
|
||||||
|
for file in ~/.local/share/opencode/storage/part/$MESSAGE_ID/*.json; do
|
||||||
|
cat "$file" | jq '.'
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Test Validation Checklist
|
||||||
|
|
||||||
|
### ✅ Planning & Approval Test
|
||||||
|
|
||||||
|
**What to check:**
|
||||||
|
1. Agent starts with "DIGGING IN..."
|
||||||
|
2. Creates implementation plan
|
||||||
|
3. Explicitly asks for approval: "Approval needed before proceeding"
|
||||||
|
4. Does NOT execute write/edit/bash without approval
|
||||||
|
|
||||||
|
**How to verify:**
|
||||||
|
```bash
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug
|
||||||
|
# Look for "Approval needed" in output
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ Context Loading Test
|
||||||
|
|
||||||
|
**What to check:**
|
||||||
|
1. Agent loads `.opencode/context/core/standards/code.md`
|
||||||
|
2. Context loaded BEFORE write/edit operations
|
||||||
|
3. Tool call sequence: read (context) → write (code)
|
||||||
|
|
||||||
|
**How to verify:**
|
||||||
|
```bash
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="context-loading/*.yaml" --debug
|
||||||
|
# Check test output for:
|
||||||
|
# "✓ Loaded: .opencode/context/core/standards/code.md"
|
||||||
|
# "✓ Timing: Context loaded XXXXms before execution"
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ Delegation Test
|
||||||
|
|
||||||
|
**What to check:**
|
||||||
|
1. Agent recognizes 4+ file features
|
||||||
|
2. Mentions task-manager or creates detailed plan
|
||||||
|
3. Breaks down complex features
|
||||||
|
|
||||||
|
**How to verify:**
|
||||||
|
```bash
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="delegation/*.yaml" --debug
|
||||||
|
# Look for "task-manager" or multi-step plan
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Understanding Test Output
|
||||||
|
|
||||||
|
### Test Result Format
|
||||||
|
```
|
||||||
|
✅ test-name - Test Description
|
||||||
|
Duration: 23291ms
|
||||||
|
Events: 28
|
||||||
|
Approvals: 0
|
||||||
|
Context Loading:
|
||||||
|
✓ Loaded: /path/to/context/file.md
|
||||||
|
✓ Timing: Context loaded 25272ms before execution
|
||||||
|
Violations: 0 (0 errors, 0 warnings)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Violation Types
|
||||||
|
|
||||||
|
**Errors (test fails):**
|
||||||
|
- `missing-approval` - Execution without approval
|
||||||
|
- `missing-required-tool` - Expected tool not used
|
||||||
|
- `insufficient-tool-calls` - Not enough tool calls
|
||||||
|
- `execution-before-read` - Modified without reading first
|
||||||
|
|
||||||
|
**Warnings (test passes with warnings):**
|
||||||
|
- `insufficient-read` - Low read/execution ratio
|
||||||
|
- Other non-critical issues
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 Common Issues
|
||||||
|
|
||||||
|
### Issue: "Session not found"
|
||||||
|
**Solution:** Session may have been cleaned up. Run test again with `--debug` flag.
|
||||||
|
|
||||||
|
### Issue: "Test failed but agent looks correct"
|
||||||
|
**Solution:** Test expectations may be wrong. Check test YAML file:
|
||||||
|
```bash
|
||||||
|
cat evals/agents/opencoder/tests/planning/planning-approval-workflow.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Can't see tool calls"
|
||||||
|
**Solution:** Tool calls are in separate part files:
|
||||||
|
```bash
|
||||||
|
ls ~/.local/share/opencode/storage/part/msg_XXXXX/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Agent didn't load context"
|
||||||
|
**Solution:** Check if context file exists:
|
||||||
|
```bash
|
||||||
|
ls -la .opencode/context/core/standards/code.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Validating Specific Behaviors
|
||||||
|
|
||||||
|
### 1. Approval Gate
|
||||||
|
```bash
|
||||||
|
# Run test
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug
|
||||||
|
|
||||||
|
# Get session ID from output
|
||||||
|
SESSION_ID="ses_XXXXX"
|
||||||
|
|
||||||
|
# Check for approval request
|
||||||
|
cat ~/.local/share/opencode/storage/message/$SESSION_ID/*.json | \
|
||||||
|
jq -r '.summary.body' | \
|
||||||
|
grep -i "approval needed"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Context Loading
|
||||||
|
```bash
|
||||||
|
# Run test
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="context-loading/*.yaml" --debug
|
||||||
|
|
||||||
|
# Check test output for context loading confirmation
|
||||||
|
# Look for: "✓ Loaded: .opencode/context/core/standards/code.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Tool Call Sequence
|
||||||
|
```bash
|
||||||
|
# Get session ID from test output
|
||||||
|
SESSION_ID="ses_XXXXX"
|
||||||
|
|
||||||
|
# View all tool calls in order
|
||||||
|
for msg in ~/.local/share/opencode/storage/message/$SESSION_ID/*.json; do
|
||||||
|
MSG_ID=$(cat "$msg" | jq -r '.id')
|
||||||
|
if [ -d ~/.local/share/opencode/storage/part/$MSG_ID ]; then
|
||||||
|
echo "Message: $MSG_ID"
|
||||||
|
cat ~/.local/share/opencode/storage/part/$MSG_ID/*.json | \
|
||||||
|
jq -r 'select(.type == "tool") | " \(.tool): \(.input)"'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Creating New Tests
|
||||||
|
|
||||||
|
### Test Template
|
||||||
|
```yaml
|
||||||
|
id: my-test-name
|
||||||
|
name: Human Readable Test Name
|
||||||
|
description: |
|
||||||
|
What this test validates
|
||||||
|
|
||||||
|
category: developer # or business, creative, edge-case
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Your test prompt here
|
||||||
|
|
||||||
|
behavior:
|
||||||
|
mustContain:
|
||||||
|
- "Expected text in response"
|
||||||
|
mustNotUseTools: [write, edit] # Tools that should NOT be used
|
||||||
|
mustUseTools: [read] # Tools that MUST be used
|
||||||
|
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false # false = should NOT violate
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 60000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- tag1
|
||||||
|
- tag2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Turn Test Template
|
||||||
|
```yaml
|
||||||
|
prompts:
|
||||||
|
- text: "First prompt"
|
||||||
|
expectContext: false
|
||||||
|
|
||||||
|
- text: "approve"
|
||||||
|
delayMs: 2000
|
||||||
|
expectContext: true
|
||||||
|
contextFile: "code.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Advanced Debugging
|
||||||
|
|
||||||
|
### Enable Verbose Logging
|
||||||
|
```bash
|
||||||
|
# Set debug environment variable
|
||||||
|
DEBUG=* npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compare Test Runs
|
||||||
|
```bash
|
||||||
|
# Run test twice and compare
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug > run1.log
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug > run2.log
|
||||||
|
diff run1.log run2.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extract All Tool Calls from Session
|
||||||
|
```bash
|
||||||
|
SESSION_ID="ses_XXXXX"
|
||||||
|
|
||||||
|
# Create tool call report
|
||||||
|
echo "Tool Calls in Session: $SESSION_ID"
|
||||||
|
echo "======================================"
|
||||||
|
for msg in ~/.local/share/opencode/storage/message/$SESSION_ID/*.json; do
|
||||||
|
MSG_ID=$(cat "$msg" | jq -r '.id')
|
||||||
|
ROLE=$(cat "$msg" | jq -r '.role')
|
||||||
|
|
||||||
|
if [ "$ROLE" = "assistant" ] && [ -d ~/.local/share/opencode/storage/part/$MSG_ID ]; then
|
||||||
|
cat ~/.local/share/opencode/storage/part/$MSG_ID/*.json | \
|
||||||
|
jq -r 'select(.type == "tool") | "\(.tool): \(.input | tostring)"'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Resources
|
||||||
|
|
||||||
|
- **Test Validation Report:** `TEST_VALIDATION_REPORT.md`
|
||||||
|
- **Test Configuration:** `config/config.yaml`
|
||||||
|
- **Prompt File:** `../../.opencode/agent/opencoder.md`
|
||||||
|
- **Debug Scripts:** `../../evals/framework/scripts/debug/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Tips
|
||||||
|
|
||||||
|
1. **Always use `--debug` flag** when investigating test failures
|
||||||
|
2. **Save session IDs** from test output for later inspection
|
||||||
|
3. **Check both test output AND session files** for complete picture
|
||||||
|
4. **Compare passing vs failing tests** to identify patterns
|
||||||
|
5. **Verify context files exist** before running context loading tests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated:** 2025-12-08
|
||||||
213
evals/agents/opencoder/QUICK_TEST_GUIDE.md
Normal file
213
evals/agents/opencoder/QUICK_TEST_GUIDE.md
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
# Quick Test Guide - OpenCoder
|
||||||
|
|
||||||
|
**TL;DR:** Run tests and see EXACTLY what the agent says and does.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Run Test with Full Conversation
|
||||||
|
|
||||||
|
### Method 1: Using --verbose flag (RECOMMENDED)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd evals/framework
|
||||||
|
|
||||||
|
# Run single test and see full conversation
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --verbose --debug
|
||||||
|
|
||||||
|
# Run context loading test
|
||||||
|
npm run eval:sdk -- --agent=opencoder --pattern="context-loading/*.yaml" --verbose --debug
|
||||||
|
|
||||||
|
# Run all tests (will take longer)
|
||||||
|
npm run eval:sdk -- --agent=opencoder --verbose --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Both `--verbose` and `--debug` flags are required:
|
||||||
|
- `--verbose` = Show full conversations
|
||||||
|
- `--debug` = Keep session data (required for --verbose to work)
|
||||||
|
|
||||||
|
### Method 2: Using helper script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd evals/framework/scripts
|
||||||
|
|
||||||
|
# Run single test and see full conversation
|
||||||
|
./run-test-verbose.sh opencoder "planning/*.yaml"
|
||||||
|
|
||||||
|
# Run context loading test
|
||||||
|
./run-test-verbose.sh opencoder "context-loading/*.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output shows:**
|
||||||
|
1. ✅ Test result (PASS/FAIL)
|
||||||
|
2. 📊 Test metrics (duration, events, violations)
|
||||||
|
3. 💬 **FULL CONVERSATION** - Every message between user and agent
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Example Output
|
||||||
|
|
||||||
|
```
|
||||||
|
TEST RESULTS
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
1. ✅ planning-approval-workflow - Planning & Approval Workflow
|
||||||
|
Duration: 28327ms
|
||||||
|
Events: 33
|
||||||
|
Approvals: 0
|
||||||
|
Violations: 0 (0 errors, 0 warnings)
|
||||||
|
|
||||||
|
======================================================================
|
||||||
|
FULL CONVERSATION
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
👤 USER
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
Based on the existing code structure, I will:
|
||||||
|
|
||||||
|
1. Create a new file `utils/utils.js` with an `add` function
|
||||||
|
2. Follow pure function pattern
|
||||||
|
3. Use JSDoc comments
|
||||||
|
|
||||||
|
**Approval needed before proceeding. Please review and confirm.**
|
||||||
|
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
🤖 ASSISTANT
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ What You Can Verify
|
||||||
|
|
||||||
|
### 1. Planning & Approval Workflow
|
||||||
|
```bash
|
||||||
|
./run-test-verbose.sh opencoder "planning/*.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Look for:**
|
||||||
|
- ✅ "DIGGING IN..." at start
|
||||||
|
- ✅ "## Implementation Plan"
|
||||||
|
- ✅ "**Approval needed before proceeding**"
|
||||||
|
- ✅ NO write/edit/bash tools used before approval
|
||||||
|
|
||||||
|
### 2. Context Loading
|
||||||
|
```bash
|
||||||
|
./run-test-verbose.sh opencoder "context-loading/*.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Look for:**
|
||||||
|
- ✅ Test output shows: "✓ Loaded: .opencode/context/core/standards/code.md"
|
||||||
|
- ✅ Test output shows: "✓ Timing: Context loaded XXXXms before execution"
|
||||||
|
- ✅ Tool calls show `read` of code.md BEFORE `write`
|
||||||
|
|
||||||
|
### 3. Delegation Recognition
|
||||||
|
```bash
|
||||||
|
./run-test-verbose.sh opencoder "delegation/*.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Look for:**
|
||||||
|
- ✅ Agent recognizes multi-file features
|
||||||
|
- ✅ Mentions "task-manager" or creates detailed breakdown
|
||||||
|
- ✅ Identifies complexity correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Inspect Specific Session
|
||||||
|
|
||||||
|
If you have a session ID from a test run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd evals/framework/scripts/debug
|
||||||
|
./show-test-conversation.sh ses_XXXXXXXXXXXXX
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 All Available Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all opencoder tests
|
||||||
|
find ../agents/opencoder/tests -name "*.yaml" -type f
|
||||||
|
|
||||||
|
# Run all tests (no conversation output)
|
||||||
|
cd ../
|
||||||
|
npm run eval:sdk -- --agent=opencoder
|
||||||
|
|
||||||
|
# Run all tests with debug
|
||||||
|
npm run eval:sdk -- --agent=opencoder --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Test Categories
|
||||||
|
|
||||||
|
| Category | Pattern | What It Tests |
|
||||||
|
|----------|---------|---------------|
|
||||||
|
| **Planning** | `planning/*.yaml` | Plan-first, approval gates |
|
||||||
|
| **Context** | `context-loading/*.yaml` | Loads code.md before coding |
|
||||||
|
| **Implementation** | `implementation/*.yaml` | Incremental execution, validation |
|
||||||
|
| **Delegation** | `delegation/*.yaml` | Task-manager, coder-agent routing |
|
||||||
|
| **Error Handling** | `error-handling/*.yaml` | Stop on failure, report-first |
|
||||||
|
| **Completion** | `completion/*.yaml` | Handoff recommendations |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Quick Validation Checklist
|
||||||
|
|
||||||
|
Run these 3 tests to validate core behaviors:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Approval workflow
|
||||||
|
./run-test-verbose.sh opencoder "planning/*.yaml"
|
||||||
|
# ✅ Look for: "Approval needed before proceeding"
|
||||||
|
|
||||||
|
# 2. Context loading
|
||||||
|
./run-test-verbose.sh opencoder "context-loading/*.yaml"
|
||||||
|
# ✅ Look for: "✓ Loaded: .opencode/context/core/standards/code.md"
|
||||||
|
|
||||||
|
# 3. Delegation
|
||||||
|
./run-test-verbose.sh opencoder "delegation/delegation-task-manager.yaml"
|
||||||
|
# ✅ Look for: Multi-step plan or "task-manager" mention
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 Troubleshooting
|
||||||
|
|
||||||
|
### "Session not found"
|
||||||
|
- Session was cleaned up. Run test again.
|
||||||
|
|
||||||
|
### "No conversation shown"
|
||||||
|
- Check if test actually ran (look for "Session created" in output)
|
||||||
|
- Try running test directly: `npm run eval:sdk -- --agent=opencoder --pattern="planning/*.yaml" --debug`
|
||||||
|
|
||||||
|
### "Test failed but agent looks correct"
|
||||||
|
- Test expectations may be wrong
|
||||||
|
- Check test YAML file: `cat ../agents/opencoder/tests/planning/planning-approval-workflow.yaml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Summary
|
||||||
|
|
||||||
|
**YES, you can see exactly what's being asked and what's being responded with!**
|
||||||
|
|
||||||
|
The `run-test-verbose.sh` script:
|
||||||
|
1. Runs the test
|
||||||
|
2. Captures the session ID
|
||||||
|
3. Shows test results
|
||||||
|
4. **Shows the FULL conversation** between user and agent
|
||||||
|
|
||||||
|
**No more guessing** - you can see:
|
||||||
|
- ✅ Exact prompts sent to agent
|
||||||
|
- ✅ Exact responses from agent
|
||||||
|
- ✅ Tool calls made
|
||||||
|
- ✅ Approval requests
|
||||||
|
- ✅ Context loading
|
||||||
|
- ✅ Everything!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated:** 2025-12-08
|
||||||
|
|
@ -12,15 +12,21 @@ defaults:
|
||||||
|
|
||||||
# Test discovery paths
|
# Test discovery paths
|
||||||
testPaths:
|
testPaths:
|
||||||
|
- tests/planning
|
||||||
|
- tests/context-loading
|
||||||
|
- tests/implementation
|
||||||
|
- tests/delegation
|
||||||
|
- tests/error-handling
|
||||||
|
- tests/completion
|
||||||
- tests/developer
|
- tests/developer
|
||||||
- tests/business
|
|
||||||
- tests/edge-case
|
|
||||||
|
|
||||||
# Agent-specific expectations
|
# Agent-specific expectations
|
||||||
expectations:
|
expectations:
|
||||||
# Opencoder executes tools directly without text-based approval
|
# Opencoder NOW requires text-based approval (updated prompt)
|
||||||
requiresTextApproval: false
|
requiresTextApproval: true
|
||||||
# Uses tool permission system
|
# Uses tool permission system
|
||||||
usesToolPermissions: true
|
usesToolPermissions: true
|
||||||
# Starts responses with "DIGGING IN..."
|
# Starts responses with "DIGGING IN..."
|
||||||
responsePrefix: "DIGGING IN..."
|
responsePrefix: "DIGGING IN..."
|
||||||
|
# Should load context before code implementation
|
||||||
|
requiresContextLoading: true
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
id: completion-handoff
|
||||||
|
name: Completion Handoff Recommendations
|
||||||
|
description: |
|
||||||
|
Tests that opencoder recommends handoff to other agents after completion.
|
||||||
|
When implementation is complete, should recommend:
|
||||||
|
- subagents/code/tester (for tests)
|
||||||
|
- subagents/core/documentation (for docs)
|
||||||
|
|
||||||
|
Agent should emit handoff recommendations.
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompts:
|
||||||
|
- text: "Create a simple add function in math.js"
|
||||||
|
expectContext: false
|
||||||
|
|
||||||
|
- text: "approve"
|
||||||
|
delayMs: 2000
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
mustUseTools: [write]
|
||||||
|
minToolCalls: 1
|
||||||
|
# Should mention handoff/next steps
|
||||||
|
mustContainAnyOf:
|
||||||
|
- ["tester", "test"]
|
||||||
|
- ["documentation", "docs"]
|
||||||
|
- ["next steps", "Next steps"]
|
||||||
|
- ["handoff", "Handoff"]
|
||||||
|
|
||||||
|
# Should follow approval workflow
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 90000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- completion
|
||||||
|
- handoff
|
||||||
|
- workflow
|
||||||
|
- coordination
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
id: context-loading-code
|
||||||
|
name: Context Loading Before Code Implementation
|
||||||
|
description: |
|
||||||
|
Tests that opencoder loads context files BEFORE implementing code.
|
||||||
|
Agent should:
|
||||||
|
1. Present plan and get approval
|
||||||
|
2. Load .opencode/context/core/standards/code.md
|
||||||
|
3. Then implement the code
|
||||||
|
|
||||||
|
This is CRITICAL - code without context = inconsistent patterns.
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompts:
|
||||||
|
- text: "Create a simple User class in src/models/User.js with name and email properties"
|
||||||
|
expectContext: false
|
||||||
|
|
||||||
|
- text: "approve"
|
||||||
|
delayMs: 2000
|
||||||
|
expectContext: true
|
||||||
|
contextFile: "code.md"
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
mustUseTools: [read, write]
|
||||||
|
requiresContext: true
|
||||||
|
minToolCalls: 2
|
||||||
|
|
||||||
|
# Context loading should NOT be violated
|
||||||
|
expectedViolations:
|
||||||
|
- rule: context-loading
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 120000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- context-loading
|
||||||
|
- critical
|
||||||
|
- code-standards
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
id: delegation-coder-agent
|
||||||
|
name: Coder Agent Delegation (Simple Task)
|
||||||
|
description: |
|
||||||
|
Tests that opencoder can delegate simple tasks to coder-agent.
|
||||||
|
For simple, focused implementations, should use coder-agent to save time.
|
||||||
|
|
||||||
|
Agent should:
|
||||||
|
1. Recognize simple task
|
||||||
|
2. Optionally delegate to subagents/code/coder-agent
|
||||||
|
3. OR implement directly (both acceptable for simple tasks)
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompts:
|
||||||
|
- text: "Create a simple hello world function in utils/hello.js"
|
||||||
|
expectContext: false
|
||||||
|
|
||||||
|
- text: "approve"
|
||||||
|
delayMs: 2000
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
# Either delegates OR implements directly (both OK for simple tasks)
|
||||||
|
mustUseAnyOf: [[task], [write]]
|
||||||
|
minToolCalls: 1
|
||||||
|
|
||||||
|
# Should follow approval workflow
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 90000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- delegation
|
||||||
|
- coder-agent
|
||||||
|
- simple-task
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
id: delegation-task-manager
|
||||||
|
name: Task Manager Delegation (4+ Files)
|
||||||
|
description: |
|
||||||
|
Tests that opencoder delegates to task-manager for complex features.
|
||||||
|
When feature spans 4+ files or >60 min, should delegate to task-manager.
|
||||||
|
|
||||||
|
Agent should:
|
||||||
|
1. Recognize complexity (4+ files)
|
||||||
|
2. Delegate to subagents/core/task-manager
|
||||||
|
3. Pass proper context to subagent
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Implement a complete authentication system with:
|
||||||
|
- User model (models/User.js)
|
||||||
|
- Auth controller (controllers/AuthController.js)
|
||||||
|
- Auth middleware (middleware/auth.js)
|
||||||
|
- Auth routes (routes/auth.js)
|
||||||
|
- Auth service (services/AuthService.js)
|
||||||
|
|
||||||
|
This spans 5 files - please plan and implement.
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
# Should delegate to task-manager OR present detailed plan
|
||||||
|
mustContainAnyOf:
|
||||||
|
- ["task-manager", "subagents/core/task-manager"]
|
||||||
|
- ["Implementation Plan", "Step 1", "Step 2"]
|
||||||
|
minToolCalls: 1
|
||||||
|
|
||||||
|
# Should follow approval workflow
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 120000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- delegation
|
||||||
|
- task-manager
|
||||||
|
- complex-feature
|
||||||
|
- multi-file
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
id: error-stop-on-failure
|
||||||
|
name: Error Handling - Stop on Failure
|
||||||
|
description: |
|
||||||
|
Tests that opencoder STOPS on failures and doesn't auto-fix.
|
||||||
|
Agent should:
|
||||||
|
1. Detect error/failure
|
||||||
|
2. STOP execution
|
||||||
|
3. REPORT the error
|
||||||
|
4. PROPOSE fix
|
||||||
|
5. REQUEST approval before fixing
|
||||||
|
|
||||||
|
Should NEVER auto-fix without approval.
|
||||||
|
|
||||||
|
category: edge-case
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompts:
|
||||||
|
- text: |
|
||||||
|
Run the command: node nonexistent-file.js
|
||||||
|
|
||||||
|
When it fails, report the error and propose a fix.
|
||||||
|
expectContext: false
|
||||||
|
|
||||||
|
- text: "approve"
|
||||||
|
delayMs: 2000
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
mustUseTools: [bash]
|
||||||
|
minToolCalls: 1
|
||||||
|
# Should report error and ask for approval
|
||||||
|
mustContain:
|
||||||
|
- "error"
|
||||||
|
# Should NOT auto-fix
|
||||||
|
mustNotContain:
|
||||||
|
- "I've fixed"
|
||||||
|
- "I fixed"
|
||||||
|
- "automatically fixed"
|
||||||
|
|
||||||
|
# Should follow error handling rules
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 90000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- error-handling
|
||||||
|
- stop-on-failure
|
||||||
|
- report-first
|
||||||
|
- critical
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
id: incremental-implementation
|
||||||
|
name: Incremental Implementation with Validation
|
||||||
|
description: |
|
||||||
|
Tests that opencoder implements step-by-step (not all at once).
|
||||||
|
Agent should:
|
||||||
|
1. Present multi-step plan
|
||||||
|
2. Implement ONE step at a time
|
||||||
|
3. Validate after each step
|
||||||
|
4. NOT implement entire plan in one go
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompts:
|
||||||
|
- text: |
|
||||||
|
Create a simple calculator module with:
|
||||||
|
1. Add function
|
||||||
|
2. Subtract function
|
||||||
|
3. Multiply function
|
||||||
|
|
||||||
|
Implement incrementally, one function at a time.
|
||||||
|
expectContext: false
|
||||||
|
|
||||||
|
- text: "approve"
|
||||||
|
delayMs: 2000
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
mustUseTools: [read, write]
|
||||||
|
minToolCalls: 2
|
||||||
|
# Should mention incremental/step-by-step approach
|
||||||
|
mustContain:
|
||||||
|
- "Step"
|
||||||
|
|
||||||
|
# Should follow approval workflow
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 180000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- implementation
|
||||||
|
- incremental
|
||||||
|
- validation
|
||||||
|
- workflow
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
id: multi-language-validation
|
||||||
|
name: Multi-Language Support & Validation
|
||||||
|
description: |
|
||||||
|
Tests that opencoder adapts to different languages and uses proper tools.
|
||||||
|
For TypeScript: should mention tsc, eslint
|
||||||
|
For Python: should mention mypy, pylint, pytest
|
||||||
|
|
||||||
|
Agent should recognize language and use appropriate validation tools.
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple TypeScript function in src/utils/math.ts that adds two numbers.
|
||||||
|
Make sure to use proper type checking and validation.
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
mustUseTools: [read, write]
|
||||||
|
minToolCalls: 2
|
||||||
|
# Should mention TypeScript-specific tools
|
||||||
|
mustContainAnyOf:
|
||||||
|
- ["tsc", "TypeScript"]
|
||||||
|
- ["type check", "type-check"]
|
||||||
|
- ["eslint"]
|
||||||
|
|
||||||
|
# Should follow approval workflow
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 120000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- multi-language
|
||||||
|
- typescript
|
||||||
|
- validation
|
||||||
|
- type-checking
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
id: planning-approval-workflow
|
||||||
|
name: Planning & Approval Workflow
|
||||||
|
description: |
|
||||||
|
Tests that opencoder follows plan-first approach with approval gate.
|
||||||
|
Agent should:
|
||||||
|
1. Analyze the request
|
||||||
|
2. Create implementation plan
|
||||||
|
3. Request approval BEFORE any implementation
|
||||||
|
4. NOT execute without approval
|
||||||
|
|
||||||
|
category: developer
|
||||||
|
agent: opencoder
|
||||||
|
model: anthropic/claude-sonnet-4-5
|
||||||
|
|
||||||
|
prompt: |
|
||||||
|
Create a simple utility function in utils.js that adds two numbers.
|
||||||
|
|
||||||
|
# Expected behavior
|
||||||
|
behavior:
|
||||||
|
# Should present plan first
|
||||||
|
mustContain:
|
||||||
|
- "Implementation Plan"
|
||||||
|
- "Approval needed"
|
||||||
|
# Should NOT execute immediately
|
||||||
|
mustNotUseTools: [write, edit, bash]
|
||||||
|
|
||||||
|
# Approval gate should NOT be violated (opencoder asks for approval)
|
||||||
|
expectedViolations:
|
||||||
|
- rule: approval-gate
|
||||||
|
shouldViolate: false
|
||||||
|
severity: error
|
||||||
|
|
||||||
|
approvalStrategy:
|
||||||
|
type: auto-approve
|
||||||
|
|
||||||
|
timeout: 60000
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- planning
|
||||||
|
- approval-gate
|
||||||
|
- workflow
|
||||||
|
- critical
|
||||||
|
|
@ -42,10 +42,9 @@
|
||||||
"@types/node": "^20.10.0",
|
"@types/node": "^20.10.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
||||||
"@typescript-eslint/parser": "^6.13.0",
|
"@typescript-eslint/parser": "^6.13.0",
|
||||||
"ajv-cli": "^5.0.0",
|
|
||||||
"eslint": "^8.54.0",
|
"eslint": "^8.54.0",
|
||||||
"tsx": "^4.20.6",
|
"tsx": "^4.20.6",
|
||||||
"typescript": "^5.3.0",
|
"typescript": "^5.3.0",
|
||||||
"vitest": "^1.0.0"
|
"vitest": "^1.6.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
104
evals/framework/scripts/debug/show-test-conversation.sh
Executable file
104
evals/framework/scripts/debug/show-test-conversation.sh
Executable file
|
|
@ -0,0 +1,104 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Show full conversation from a test session
|
||||||
|
# Usage: ./show-test-conversation.sh <session_id>
|
||||||
|
|
||||||
|
SESSION_ID=$1
|
||||||
|
|
||||||
|
if [ -z "$SESSION_ID" ]; then
|
||||||
|
echo "Usage: $0 <session_id>"
|
||||||
|
echo ""
|
||||||
|
echo "Get session ID from test output (look for 'Session created: ses_...')"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SESSION_DIR="$HOME/.local/share/opencode/storage/message/$SESSION_ID"
|
||||||
|
PART_DIR="$HOME/.local/share/opencode/storage/part"
|
||||||
|
|
||||||
|
if [ ! -d "$SESSION_DIR" ]; then
|
||||||
|
echo "Session not found: $SESSION_ID"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "========================================================================"
|
||||||
|
echo "SESSION: $SESSION_ID"
|
||||||
|
echo "========================================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Process messages in order
|
||||||
|
for msg_file in "$SESSION_DIR"/*.json; do
|
||||||
|
if [ -f "$msg_file" ]; then
|
||||||
|
MSG_ID=$(cat "$msg_file" | jq -r '.id')
|
||||||
|
ROLE=$(cat "$msg_file" | jq -r '.role')
|
||||||
|
SUMMARY=$(cat "$msg_file" | jq -r '.summary.body // empty')
|
||||||
|
|
||||||
|
if [ "$ROLE" = "user" ]; then
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "👤 USER PROMPT"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
|
||||||
|
# Get actual user prompt from parts (not summary which is auto-generated)
|
||||||
|
if [ -d "$PART_DIR/$MSG_ID" ]; then
|
||||||
|
for part_file in "$PART_DIR/$MSG_ID"/*.json; do
|
||||||
|
if [ -f "$part_file" ]; then
|
||||||
|
PART_TYPE=$(cat "$part_file" | jq -r '.type')
|
||||||
|
if [ "$PART_TYPE" = "text" ]; then
|
||||||
|
TEXT=$(cat "$part_file" | jq -r '.text // empty')
|
||||||
|
if [ -n "$TEXT" ]; then
|
||||||
|
echo "$TEXT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# Fallback to summary if no parts (shouldn't happen)
|
||||||
|
if [ -n "$SUMMARY" ]; then
|
||||||
|
echo "$SUMMARY"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
elif [ "$ROLE" = "assistant" ]; then
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "🤖 ASSISTANT"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
|
||||||
|
# Read parts from the part directory
|
||||||
|
if [ -d "$PART_DIR/$MSG_ID" ]; then
|
||||||
|
for part_file in "$PART_DIR/$MSG_ID"/*.json; do
|
||||||
|
if [ -f "$part_file" ]; then
|
||||||
|
PART_TYPE=$(cat "$part_file" | jq -r '.type')
|
||||||
|
|
||||||
|
if [ "$PART_TYPE" = "text" ]; then
|
||||||
|
TEXT=$(cat "$part_file" | jq -r '.text // empty')
|
||||||
|
if [ -n "$TEXT" ]; then
|
||||||
|
echo "$TEXT"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
elif [ "$PART_TYPE" = "tool" ]; then
|
||||||
|
TOOL=$(cat "$part_file" | jq -r '.tool')
|
||||||
|
INPUT=$(cat "$part_file" | jq -c '.input // {}')
|
||||||
|
echo "🔧 TOOL CALL: $TOOL"
|
||||||
|
echo " Input: $INPUT"
|
||||||
|
echo ""
|
||||||
|
elif [ "$PART_TYPE" = "tool_result" ]; then
|
||||||
|
RESULT=$(cat "$part_file" | jq -r '.result // empty')
|
||||||
|
if [ -n "$RESULT" ]; then
|
||||||
|
# Show first 500 chars of result
|
||||||
|
echo "📊 TOOL RESULT:"
|
||||||
|
echo "$RESULT" | head -c 500
|
||||||
|
if [ ${#RESULT} -gt 500 ]; then
|
||||||
|
echo "..."
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "========================================================================"
|
||||||
39
evals/framework/scripts/run-test-verbose.sh
Executable file
39
evals/framework/scripts/run-test-verbose.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Run a test with full conversation output
|
||||||
|
# Usage: ./run-test-verbose.sh <agent> <pattern>
|
||||||
|
# Example: ./run-test-verbose.sh opencoder "planning/*.yaml"
|
||||||
|
|
||||||
|
AGENT=${1:-opencoder}
|
||||||
|
PATTERN=${2:-"**/*.yaml"}
|
||||||
|
|
||||||
|
echo "🚀 Running test with verbose output..."
|
||||||
|
echo "Agent: $AGENT"
|
||||||
|
echo "Pattern: $PATTERN"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Run test with debug mode and capture session ID
|
||||||
|
OUTPUT=$(cd .. && npm run eval:sdk -- --agent=$AGENT --pattern="$PATTERN" --debug 2>&1)
|
||||||
|
|
||||||
|
# Extract session ID from output
|
||||||
|
SESSION_ID=$(echo "$OUTPUT" | grep -o "Session created: ses_[a-zA-Z0-9]*" | head -1 | cut -d' ' -f3)
|
||||||
|
|
||||||
|
# Show test summary
|
||||||
|
echo "$OUTPUT" | grep -A 20 "TEST RESULTS"
|
||||||
|
|
||||||
|
if [ -n "$SESSION_ID" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "========================================================================"
|
||||||
|
echo "FULL CONVERSATION"
|
||||||
|
echo "========================================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Show full conversation
|
||||||
|
./debug/show-test-conversation.sh "$SESSION_ID"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ No session ID found. Test may have failed to start."
|
||||||
|
echo ""
|
||||||
|
echo "Full output:"
|
||||||
|
echo "$OUTPUT"
|
||||||
|
fi
|
||||||
|
|
@ -36,8 +36,18 @@ export function logEvent(event: ServerEvent): void {
|
||||||
// Message updates happen frequently during streaming
|
// Message updates happen frequently during streaming
|
||||||
// Only log role changes or completion
|
// Only log role changes or completion
|
||||||
if (props.role === 'user') {
|
if (props.role === 'user') {
|
||||||
|
const showFull = process.env.DEBUG_VERBOSE === 'true';
|
||||||
|
|
||||||
|
if (showFull && props.summary?.body) {
|
||||||
|
console.log(`\n${'═'.repeat(70)}`);
|
||||||
|
console.log(`👤 USER PROMPT:`);
|
||||||
|
console.log(`${'═'.repeat(70)}`);
|
||||||
|
console.log(props.summary.body);
|
||||||
|
console.log(`${'═'.repeat(70)}\n`);
|
||||||
|
} else {
|
||||||
console.log(`👤 User message received`);
|
console.log(`👤 User message received`);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Skip assistant message updates (too noisy)
|
// Skip assistant message updates (too noisy)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -76,13 +86,18 @@ function logPartEvent(props: any): void {
|
||||||
if (props.type === 'tool') {
|
if (props.type === 'tool') {
|
||||||
const toolName = props.tool || 'unknown';
|
const toolName = props.tool || 'unknown';
|
||||||
const status = props.state?.status || props.status || '';
|
const status = props.state?.status || props.status || '';
|
||||||
|
const showFull = process.env.DEBUG_VERBOSE === 'true';
|
||||||
|
|
||||||
// Only log when tool starts or completes
|
// Only log when tool starts or completes
|
||||||
if (status === 'running' || status === 'pending') {
|
if (status === 'running' || status === 'pending') {
|
||||||
console.log(`🔧 Tool: ${toolName} (starting)`);
|
console.log(`🔧 Tool: ${toolName} (starting)`);
|
||||||
|
|
||||||
// Show tool input preview
|
// Show tool input
|
||||||
const input = props.state?.input || props.input || {};
|
const input = props.state?.input || props.input || {};
|
||||||
|
|
||||||
|
if (showFull) {
|
||||||
|
console.log(` Input: ${JSON.stringify(input, null, 2)}`);
|
||||||
|
} else {
|
||||||
if (input.command) {
|
if (input.command) {
|
||||||
const cmd = input.command.substring(0, 70);
|
const cmd = input.command.substring(0, 70);
|
||||||
console.log(` └─ ${cmd}${input.command.length > 70 ? '...' : ''}`);
|
console.log(` └─ ${cmd}${input.command.length > 70 ? '...' : ''}`);
|
||||||
|
|
@ -91,19 +106,39 @@ function logPartEvent(props: any): void {
|
||||||
} else if (input.pattern) {
|
} else if (input.pattern) {
|
||||||
console.log(` └─ pattern: ${input.pattern}`);
|
console.log(` └─ pattern: ${input.pattern}`);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (status === 'completed') {
|
} else if (status === 'completed') {
|
||||||
console.log(`✅ Tool: ${toolName} (completed)`);
|
console.log(`✅ Tool: ${toolName} (completed)`);
|
||||||
|
|
||||||
|
if (showFull) {
|
||||||
|
const result = props.state?.result || props.result || '';
|
||||||
|
if (result) {
|
||||||
|
const preview = result.substring(0, 300);
|
||||||
|
console.log(` Result: ${preview}${result.length > 300 ? '...' : ''}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (status === 'error') {
|
} else if (status === 'error') {
|
||||||
console.log(`❌ Tool: ${toolName} (error)`);
|
console.log(`❌ Tool: ${toolName} (error)`);
|
||||||
}
|
}
|
||||||
} else if (props.type === 'text') {
|
} else if (props.type === 'text') {
|
||||||
// Text parts - show preview of assistant response
|
// Text parts - show assistant response
|
||||||
const text = props.text || '';
|
const text = props.text || '';
|
||||||
if (text.length > 0) {
|
if (text.length > 0) {
|
||||||
|
// Check if we should show full text (when DEBUG_VERBOSE is set)
|
||||||
|
const showFull = process.env.DEBUG_VERBOSE === 'true';
|
||||||
|
|
||||||
|
if (showFull) {
|
||||||
|
console.log(`\n${'─'.repeat(70)}`);
|
||||||
|
console.log(`📝 ASSISTANT RESPONSE:`);
|
||||||
|
console.log(`${'─'.repeat(70)}`);
|
||||||
|
console.log(text);
|
||||||
|
console.log(`${'─'.repeat(70)}\n`);
|
||||||
|
} else {
|
||||||
const preview = text.substring(0, 100).replace(/\n/g, ' ');
|
const preview = text.substring(0, 100).replace(/\n/g, ' ');
|
||||||
console.log(`📝 ${preview}${text.length > 100 ? '...' : ''}`);
|
console.log(`📝 ${preview}${text.length > 100 ? '...' : ''}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
* Usage:
|
* Usage:
|
||||||
* npm run eval:sdk
|
* npm run eval:sdk
|
||||||
* npm run eval:sdk -- --debug
|
* npm run eval:sdk -- --debug
|
||||||
|
* npm run eval:sdk -- --verbose
|
||||||
* npm run eval:sdk -- --no-evaluators
|
* npm run eval:sdk -- --no-evaluators
|
||||||
* npm run eval:sdk -- --core
|
* npm run eval:sdk -- --core
|
||||||
* npm run eval:sdk -- --agent=opencoder
|
* npm run eval:sdk -- --agent=opencoder
|
||||||
|
|
@ -14,9 +15,12 @@
|
||||||
* npm run eval:sdk -- --model=anthropic/claude-3-5-sonnet-20241022
|
* npm run eval:sdk -- --model=anthropic/claude-3-5-sonnet-20241022
|
||||||
* npm run eval:sdk -- --pattern="developer/*.yaml" --model=openai/gpt-4-turbo
|
* npm run eval:sdk -- --pattern="developer/*.yaml" --model=openai/gpt-4-turbo
|
||||||
* npm run eval:sdk -- --prompt-variant=gpt --agent=openagent
|
* npm run eval:sdk -- --prompt-variant=gpt --agent=openagent
|
||||||
|
* npm run eval:sdk -- --agent=opencoder --verbose # Show full conversations
|
||||||
*
|
*
|
||||||
* Options:
|
* Options:
|
||||||
* --debug Enable debug logging
|
* --debug Enable debug logging and keep sessions for inspection
|
||||||
|
* --verbose Show full conversation (prompts + responses) after each test
|
||||||
|
* (automatically enables --debug)
|
||||||
* --no-evaluators Skip running evaluators (faster)
|
* --no-evaluators Skip running evaluators (faster)
|
||||||
* --core Run core test suite only (7 tests, ~5-8 min)
|
* --core Run core test suite only (7 tests, ~5-8 min)
|
||||||
* --agent=AGENT Run tests for specific agent (openagent, opencoder)
|
* --agent=AGENT Run tests for specific agent (openagent, opencoder)
|
||||||
|
|
@ -43,6 +47,7 @@ const __dirname = dirname(__filename);
|
||||||
|
|
||||||
interface CliArgs {
|
interface CliArgs {
|
||||||
debug: boolean;
|
debug: boolean;
|
||||||
|
verbose: boolean;
|
||||||
noEvaluators: boolean;
|
noEvaluators: boolean;
|
||||||
core: boolean;
|
core: boolean;
|
||||||
suite?: string;
|
suite?: string;
|
||||||
|
|
@ -58,6 +63,7 @@ function parseArgs(): CliArgs {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
debug: args.includes('--debug'),
|
debug: args.includes('--debug'),
|
||||||
|
verbose: args.includes('--verbose'),
|
||||||
noEvaluators: args.includes('--no-evaluators'),
|
noEvaluators: args.includes('--no-evaluators'),
|
||||||
core: args.includes('--core'),
|
core: args.includes('--core'),
|
||||||
suite: args.find(a => a.startsWith('--suite='))?.split('=')[1],
|
suite: args.find(a => a.startsWith('--suite='))?.split('=')[1],
|
||||||
|
|
@ -175,9 +181,105 @@ function printResults(results: TestResult[]): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display full conversation from a session
|
||||||
|
*/
|
||||||
|
async function displayConversation(sessionId: string): Promise<void> {
|
||||||
|
const { homedir } = await import('os');
|
||||||
|
const { readFileSync, readdirSync, existsSync } = await import('fs');
|
||||||
|
|
||||||
|
const sessionDir = join(homedir(), '.local', 'share', 'opencode', 'storage', 'message', sessionId);
|
||||||
|
const partDir = join(homedir(), '.local', 'share', 'opencode', 'storage', 'part');
|
||||||
|
|
||||||
|
if (!existsSync(sessionDir)) {
|
||||||
|
console.log(`⚠️ Session not found: ${sessionId}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n' + '='.repeat(70));
|
||||||
|
console.log('FULL CONVERSATION');
|
||||||
|
console.log('='.repeat(70));
|
||||||
|
console.log(`Session: ${sessionId}\n`);
|
||||||
|
|
||||||
|
// Read all message files and sort by creation time
|
||||||
|
const messageFiles = readdirSync(sessionDir)
|
||||||
|
.filter(f => f.endsWith('.json'))
|
||||||
|
.map(f => {
|
||||||
|
const content = JSON.parse(readFileSync(join(sessionDir, f), 'utf-8'));
|
||||||
|
return { file: f, content, created: content.time?.created || 0 };
|
||||||
|
})
|
||||||
|
.sort((a, b) => a.created - b.created);
|
||||||
|
|
||||||
|
for (const { content: msg } of messageFiles) {
|
||||||
|
const role = msg.role;
|
||||||
|
const msgId = msg.id;
|
||||||
|
|
||||||
|
if (role === 'user') {
|
||||||
|
console.log('━'.repeat(70));
|
||||||
|
console.log('👤 USER PROMPT');
|
||||||
|
console.log('━'.repeat(70));
|
||||||
|
|
||||||
|
// Get actual user prompt from parts
|
||||||
|
const msgPartDir = join(partDir, msgId);
|
||||||
|
if (existsSync(msgPartDir)) {
|
||||||
|
const partFiles = readdirSync(msgPartDir).filter(f => f.endsWith('.json'));
|
||||||
|
for (const partFile of partFiles) {
|
||||||
|
const part = JSON.parse(readFileSync(join(msgPartDir, partFile), 'utf-8'));
|
||||||
|
if (part.type === 'text' && part.text) {
|
||||||
|
console.log(part.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
} else if (role === 'assistant') {
|
||||||
|
console.log('━'.repeat(70));
|
||||||
|
console.log('🤖 ASSISTANT');
|
||||||
|
console.log('━'.repeat(70));
|
||||||
|
|
||||||
|
// Read parts from the part directory
|
||||||
|
const msgPartDir = join(partDir, msgId);
|
||||||
|
if (existsSync(msgPartDir)) {
|
||||||
|
const partFiles = readdirSync(msgPartDir)
|
||||||
|
.filter(f => f.endsWith('.json'))
|
||||||
|
.map(f => {
|
||||||
|
const content = JSON.parse(readFileSync(join(msgPartDir, f), 'utf-8'));
|
||||||
|
return { file: f, content, created: content.time?.start || content.time?.created || 0 };
|
||||||
|
})
|
||||||
|
.sort((a, b) => a.created - b.created);
|
||||||
|
|
||||||
|
for (const { content: part } of partFiles) {
|
||||||
|
if (part.type === 'text' && part.text) {
|
||||||
|
console.log(part.text);
|
||||||
|
console.log();
|
||||||
|
} else if (part.type === 'tool') {
|
||||||
|
console.log(`🔧 TOOL CALL: ${part.tool}`);
|
||||||
|
console.log(` Input: ${JSON.stringify(part.input || {})}`);
|
||||||
|
console.log();
|
||||||
|
} else if (part.type === 'tool_result' && part.result) {
|
||||||
|
const result = part.result.substring(0, 300);
|
||||||
|
console.log(`📊 TOOL RESULT:`);
|
||||||
|
console.log(result + (part.result.length > 300 ? '...' : ''));
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('='.repeat(70) + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const args = parseArgs();
|
const args = parseArgs();
|
||||||
|
|
||||||
|
// If --verbose is set, automatically enable --debug (required for session data)
|
||||||
|
if (args.verbose && !args.debug) {
|
||||||
|
args.debug = true;
|
||||||
|
console.log('ℹ️ --verbose flag automatically enabled --debug (required for session data)\n');
|
||||||
|
}
|
||||||
|
|
||||||
console.log('🚀 OpenCode SDK Test Runner\n');
|
console.log('🚀 OpenCode SDK Test Runner\n');
|
||||||
|
|
||||||
// Determine project root (for prompt management)
|
// Determine project root (for prompt management)
|
||||||
|
|
@ -431,6 +533,24 @@ async function main() {
|
||||||
// Print results
|
// Print results
|
||||||
printResults(results);
|
printResults(results);
|
||||||
|
|
||||||
|
// Show full conversations if --verbose flag is set
|
||||||
|
if (args.verbose) {
|
||||||
|
console.log('\n' + '='.repeat(70));
|
||||||
|
console.log('VERBOSE MODE: Displaying full conversations');
|
||||||
|
console.log('='.repeat(70) + '\n');
|
||||||
|
|
||||||
|
for (const result of results) {
|
||||||
|
console.log(`\nTest: ${result.testCase.id}`);
|
||||||
|
console.log(`Session ID: ${result.sessionId || 'N/A'}`);
|
||||||
|
|
||||||
|
if (result.sessionId) {
|
||||||
|
await displayConversation(result.sessionId);
|
||||||
|
} else {
|
||||||
|
console.log('⚠️ No session ID available for this test\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Exit with appropriate code
|
// Exit with appropriate code
|
||||||
const allPassed = results.every(r => r.passed);
|
const allPassed = results.every(r => r.passed);
|
||||||
process.exit(allPassed ? 0 : 1);
|
process.exit(allPassed ? 0 : 1);
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,31 @@
|
||||||
{
|
{
|
||||||
"meta": {
|
"meta": {
|
||||||
"timestamp": "2025-11-29T06:55:58.141Z",
|
"timestamp": "2025-12-09T00:07:10.119Z",
|
||||||
"agent": "openagent",
|
"agent": "opencoder",
|
||||||
"model": "opencode/grok-code-fast",
|
"model": "opencode/grok-code-fast",
|
||||||
"framework_version": "0.1.0",
|
"framework_version": "0.1.0",
|
||||||
"git_commit": "79110ed"
|
"git_commit": "fd1821c"
|
||||||
},
|
},
|
||||||
"summary": {
|
"summary": {
|
||||||
"total": 2,
|
"total": 1,
|
||||||
"passed": 0,
|
"passed": 1,
|
||||||
"failed": 2,
|
"failed": 0,
|
||||||
"duration_ms": 43350,
|
"duration_ms": 10952,
|
||||||
"pass_rate": 0
|
"pass_rate": 1
|
||||||
},
|
},
|
||||||
"by_category": {
|
"by_category": {
|
||||||
"developer": {
|
"developer": {
|
||||||
"passed": 0,
|
"passed": 1,
|
||||||
"total": 2
|
"total": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tests": [
|
"tests": [
|
||||||
{
|
{
|
||||||
"id": "execution-balance-positive-001",
|
"id": "planning-approval-workflow",
|
||||||
"category": "developer",
|
"category": "developer",
|
||||||
"passed": false,
|
"passed": true,
|
||||||
"duration_ms": 22285,
|
"duration_ms": 10952,
|
||||||
"events": 40,
|
"events": 13,
|
||||||
"approvals": 0,
|
|
||||||
"violations": {
|
|
||||||
"total": 1,
|
|
||||||
"errors": 1,
|
|
||||||
"warnings": 0,
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"type": "missing-required-tool",
|
|
||||||
"severity": "error",
|
|
||||||
"message": "Required tool 'write' was not used"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "execution-balance-negative-001",
|
|
||||||
"category": "developer",
|
|
||||||
"passed": false,
|
|
||||||
"duration_ms": 21065,
|
|
||||||
"events": 78,
|
|
||||||
"approvals": 0,
|
"approvals": 0,
|
||||||
"violations": {
|
"violations": {
|
||||||
"total": 0,
|
"total": 0,
|
||||||
|
|
|
||||||
2697
package-lock.json
generated
2697
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "opencode-agents",
|
"name": "opencode-agents",
|
||||||
"version": "0.0.2",
|
"version": "0.3.0",
|
||||||
"description": "OpenCode agent evaluation framework and test suites",
|
"description": "OpenCode agent evaluation framework and test suites",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
|
|
||||||
|
|
@ -154,16 +154,21 @@ show_prompt_library() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
The prompt library allows different AI models to use optimized prompts:
|
The prompt library allows different AI models to use optimized prompts:
|
||||||
|
|
||||||
|
${GREEN}.opencode/agent/${NC}
|
||||||
|
└── openagent.md ${YELLOW}# Canonical default (Claude-optimized)${NC}
|
||||||
|
|
||||||
${GREEN}.opencode/prompts/openagent/${NC}
|
${GREEN}.opencode/prompts/openagent/${NC}
|
||||||
├── default.md ${YELLOW}# Stable version (used in PRs)${NC}
|
├── gpt.md ${YELLOW}# GPT-4 optimized${NC}
|
||||||
├── sonnet-4.md ${YELLOW}# Claude Sonnet 4 optimized${NC}
|
├── gemini.md ${YELLOW}# Gemini optimized${NC}
|
||||||
├── grok-fast.md ${YELLOW}# Grok Fast optimized${NC}
|
├── grok.md ${YELLOW}# Grok optimized${NC}
|
||||||
|
├── llama.md ${YELLOW}# Llama/OSS optimized${NC}
|
||||||
├── TEMPLATE.md ${YELLOW}# Template for new variants${NC}
|
├── TEMPLATE.md ${YELLOW}# Template for new variants${NC}
|
||||||
└── results/ ${YELLOW}# Test results${NC}
|
└── results/ ${YELLOW}# Test results (all variants)${NC}
|
||||||
|
|
||||||
${BLUE}Key Principles:${NC}
|
${BLUE}Key Principles:${NC}
|
||||||
• PRs must use default prompts (enforced by CI)
|
• Agent files are canonical defaults (source of truth)
|
||||||
• Variants are tested and documented
|
• Variants are model-specific optimizations
|
||||||
|
• All variants tested and documented
|
||||||
• Users can choose the best prompt for their model
|
• Users can choose the best prompt for their model
|
||||||
• Contributors can add optimized variants
|
• Contributors can add optimized variants
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,36 +83,41 @@ usage() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "Required:"
|
echo "Required:"
|
||||||
echo " --agent=NAME Agent name (e.g., openagent, opencoder)"
|
echo " --agent=NAME Agent name (e.g., openagent, opencoder)"
|
||||||
echo " --variant=NAME Prompt variant by model family (e.g., default, gpt, gemini, grok, llama)"
|
echo " --variant=NAME Prompt variant (default, gpt, gemini, grok, llama)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Optional:"
|
echo "Optional:"
|
||||||
echo " --model=MODEL Model to test with (uses prompt metadata if not specified)"
|
echo " --model=MODEL Model to test with (uses prompt metadata if not specified)"
|
||||||
echo " --help, -h Show this help"
|
echo " --help, -h Show this help"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo -e "${BLUE}Architecture:${NC}"
|
||||||
|
echo " • default = Canonical agent file (.opencode/agent/<agent>.md)"
|
||||||
|
echo " • Other variants = Model-specific optimizations (.opencode/prompts/<agent>/<model>.md)"
|
||||||
|
echo " • Results always saved to .opencode/prompts/<agent>/results/"
|
||||||
|
echo ""
|
||||||
echo "Examples:"
|
echo "Examples:"
|
||||||
echo " # Test with default (Claude) - uses metadata recommendation"
|
echo " # Test default (canonical agent file)"
|
||||||
echo " $0 --agent=openagent --variant=default"
|
echo " $0 --agent=openagent --variant=default"
|
||||||
echo ""
|
echo ""
|
||||||
echo " # Test GPT prompt - uses metadata recommendation (gpt-4o)"
|
echo " # Test GPT-optimized prompt"
|
||||||
echo " $0 --agent=openagent --variant=gpt"
|
echo " $0 --agent=openagent --variant=gpt"
|
||||||
echo ""
|
echo ""
|
||||||
echo " # Test Gemini prompt with specific model"
|
echo " # Test Gemini prompt with specific model"
|
||||||
echo " $0 --agent=openagent --variant=gemini --model=google/gemini-2.0-flash-exp"
|
echo " $0 --agent=openagent --variant=gemini --model=google/gemini-2.0-flash-exp"
|
||||||
echo ""
|
echo ""
|
||||||
echo " # Test Grok prompt - uses metadata recommendation (free tier)"
|
echo " # Test Grok prompt"
|
||||||
echo " $0 --agent=openagent --variant=grok"
|
echo " $0 --agent=openagent --variant=grok"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available model families:"
|
echo "Available model families:"
|
||||||
echo " default # Claude Sonnet 4.5 (stable)"
|
echo " default # Canonical agent file (Claude Sonnet 4.5)"
|
||||||
echo " gpt # OpenAI GPT-4o, GPT-4o-mini, o1"
|
echo " gpt # OpenAI GPT-4o, GPT-4o-mini, o1"
|
||||||
echo " gemini # Google Gemini 2.0 Flash, Pro"
|
echo " gemini # Google Gemini 2.0 Flash, Pro"
|
||||||
echo " grok # xAI Grok (free tier available)"
|
echo " grok # xAI Grok (free tier available)"
|
||||||
echo " llama # Meta Llama 3.1/3.2 (local or hosted)"
|
echo " llama # Meta Llama 3.1/3.2 (local or hosted)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Note: Each prompt contains metadata with recommended models."
|
echo "Note: Model-specific prompts contain metadata with recommended models."
|
||||||
echo " If --model is not specified, the primary recommendation is used."
|
echo " If --model is not specified, the primary recommendation is used."
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available prompts for an agent:"
|
echo "Available variants for an agent:"
|
||||||
echo " ls $PROMPTS_DIR/<agent-name>/"
|
echo " ls $PROMPTS_DIR/<agent-name>/"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
@ -150,19 +155,29 @@ if [[ -z "$AGENT_NAME" ]] || [[ -z "$PROMPT_VARIANT" ]]; then
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PROMPT_FILE="$PROMPTS_DIR/$AGENT_NAME/$PROMPT_VARIANT.md"
|
|
||||||
AGENT_FILE="$AGENT_DIR/$AGENT_NAME.md"
|
AGENT_FILE="$AGENT_DIR/$AGENT_NAME.md"
|
||||||
BACKUP_FILE="$AGENT_DIR/.$AGENT_NAME.md.backup"
|
BACKUP_FILE="$AGENT_DIR/.$AGENT_NAME.md.backup"
|
||||||
VARIANT_RESULTS_DIR="$PROMPTS_DIR/$AGENT_NAME/results"
|
VARIANT_RESULTS_DIR="$PROMPTS_DIR/$AGENT_NAME/results"
|
||||||
VARIANT_RESULTS_FILE="$VARIANT_RESULTS_DIR/$PROMPT_VARIANT-results.json"
|
VARIANT_RESULTS_FILE="$VARIANT_RESULTS_DIR/$PROMPT_VARIANT-results.json"
|
||||||
|
|
||||||
# Check prompt exists
|
# Handle "default" variant - use agent file directly
|
||||||
if [[ ! -f "$PROMPT_FILE" ]]; then
|
if [[ "$PROMPT_VARIANT" == "default" ]]; then
|
||||||
echo -e "${RED}Error: Prompt not found: $PROMPT_FILE${NC}"
|
PROMPT_FILE="$AGENT_FILE"
|
||||||
|
echo -e "${BLUE}Testing default prompt (canonical agent file)${NC}"
|
||||||
|
else
|
||||||
|
PROMPT_FILE="$PROMPTS_DIR/$AGENT_NAME/$PROMPT_VARIANT.md"
|
||||||
|
|
||||||
|
# Check prompt exists
|
||||||
|
if [[ ! -f "$PROMPT_FILE" ]]; then
|
||||||
|
echo -e "${RED}Error: Prompt variant not found: $PROMPT_FILE${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available prompts for $AGENT_NAME:"
|
echo "Available variants for $AGENT_NAME:"
|
||||||
ls -1 "$PROMPTS_DIR/$AGENT_NAME/"*.md 2>/dev/null | xargs -I {} basename {} .md || echo " (none found)"
|
echo " - default (canonical agent file)"
|
||||||
|
if [[ -d "$PROMPTS_DIR/$AGENT_NAME" ]]; then
|
||||||
|
ls -1 "$PROMPTS_DIR/$AGENT_NAME/"*.md 2>/dev/null | grep -v "TEMPLATE.md" | grep -v "README.md" | xargs -I {} basename {} .md || echo " (no model variants found)"
|
||||||
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Read metadata from prompt file
|
# Read metadata from prompt file
|
||||||
|
|
@ -215,11 +230,16 @@ else
|
||||||
echo " No existing agent file to backup"
|
echo " No existing agent file to backup"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Step 2: Copy prompt variant to agent location
|
# Step 2: Copy prompt variant to agent location (skip if testing default)
|
||||||
echo -e "${YELLOW}[2/5] Copying prompt variant to agent location...${NC}"
|
if [[ "$PROMPT_VARIANT" == "default" ]]; then
|
||||||
cp "$PROMPT_FILE" "$AGENT_FILE"
|
echo -e "${YELLOW}[2/5] Using default prompt (already in place)...${NC}"
|
||||||
echo " Copied $PROMPT_FILE"
|
echo " Testing: $AGENT_FILE"
|
||||||
echo " To $AGENT_FILE"
|
else
|
||||||
|
echo -e "${YELLOW}[2/5] Copying prompt variant to agent location...${NC}"
|
||||||
|
cp "$PROMPT_FILE" "$AGENT_FILE"
|
||||||
|
echo " Copied $PROMPT_FILE"
|
||||||
|
echo " To $AGENT_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
# Step 3: Run tests
|
# Step 3: Run tests
|
||||||
echo -e "${YELLOW}[3/5] Running core eval tests...${NC}"
|
echo -e "${YELLOW}[3/5] Running core eval tests...${NC}"
|
||||||
|
|
@ -249,18 +269,18 @@ set -e
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
||||||
|
|
||||||
# Step 4: Restore default prompt
|
# Step 4: Restore original prompt (if we changed it)
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${YELLOW}[4/5] Restoring default prompt...${NC}"
|
if [[ "$PROMPT_VARIANT" == "default" ]]; then
|
||||||
DEFAULT_PROMPT="$PROMPTS_DIR/$AGENT_NAME/default.md"
|
echo -e "${YELLOW}[4/5] No restore needed (tested default)...${NC}"
|
||||||
if [[ -f "$DEFAULT_PROMPT" ]]; then
|
echo " Agent file unchanged"
|
||||||
cp "$DEFAULT_PROMPT" "$AGENT_FILE"
|
|
||||||
echo " Restored default.md to agent location"
|
|
||||||
else
|
else
|
||||||
# Restore backup if no default
|
echo -e "${YELLOW}[4/5] Restoring original prompt...${NC}"
|
||||||
if [[ -f "$BACKUP_FILE" ]]; then
|
if [[ -f "$BACKUP_FILE" ]]; then
|
||||||
cp "$BACKUP_FILE" "$AGENT_FILE"
|
cp "$BACKUP_FILE" "$AGENT_FILE"
|
||||||
echo " Restored from backup"
|
echo " Restored from backup"
|
||||||
|
else
|
||||||
|
echo " No backup to restore"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,16 @@
|
||||||
# use-prompt.sh - Switch an agent to use a specific prompt variant
|
# use-prompt.sh - Switch an agent to use a specific prompt variant
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
|
# ./scripts/prompts/use-prompt.sh --agent=openagent --variant=gpt
|
||||||
# ./scripts/prompts/use-prompt.sh --agent=openagent --variant=default
|
# ./scripts/prompts/use-prompt.sh --agent=openagent --variant=default
|
||||||
# ./scripts/prompts/use-prompt.sh --agent=openagent --variant=sonnet-4
|
|
||||||
#
|
#
|
||||||
# What it does:
|
# What it does:
|
||||||
# 1. Copies the specified prompt to the agent location
|
# 1. If variant is "default", restores the canonical agent file (no-op, already default)
|
||||||
# 2. That's it - the agent now uses that prompt
|
# 2. Otherwise, copies the model-specific variant to the agent location
|
||||||
|
#
|
||||||
|
# New Architecture:
|
||||||
|
# - Agent files (.opencode/agent/*.md) are the canonical defaults
|
||||||
|
# - Prompt variants (.opencode/prompts/<agent>/<model>.md) are model-specific optimizations
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
@ -20,6 +24,7 @@ ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
# Default values
|
# Default values
|
||||||
|
|
@ -74,13 +79,17 @@ usage() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "Required:"
|
echo "Required:"
|
||||||
echo " --agent=NAME Agent name (e.g., openagent, opencoder)"
|
echo " --agent=NAME Agent name (e.g., openagent, opencoder)"
|
||||||
echo " --variant=NAME Prompt variant by model family (e.g., default, gpt, gemini, grok, llama)"
|
echo " --variant=NAME Prompt variant (default, gpt, gemini, grok, llama)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Optional:"
|
echo "Optional:"
|
||||||
echo " --help, -h Show this help"
|
echo " --help, -h Show this help"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo -e "${BLUE}Architecture:${NC}"
|
||||||
|
echo " • Agent files (.opencode/agent/*.md) = Canonical defaults"
|
||||||
|
echo " • Prompt variants (.opencode/prompts/<agent>/<model>.md) = Model-specific"
|
||||||
|
echo ""
|
||||||
echo "Examples:"
|
echo "Examples:"
|
||||||
echo " # Use default (Claude Sonnet 4.5)"
|
echo " # Use default (canonical agent file)"
|
||||||
echo " $0 --agent=openagent --variant=default"
|
echo " $0 --agent=openagent --variant=default"
|
||||||
echo ""
|
echo ""
|
||||||
echo " # Switch to GPT-optimized prompt"
|
echo " # Switch to GPT-optimized prompt"
|
||||||
|
|
@ -89,18 +98,21 @@ usage() {
|
||||||
echo " # Switch to Gemini-optimized prompt"
|
echo " # Switch to Gemini-optimized prompt"
|
||||||
echo " $0 --agent=openagent --variant=gemini"
|
echo " $0 --agent=openagent --variant=gemini"
|
||||||
echo ""
|
echo ""
|
||||||
echo " # Switch to Grok-optimized prompt"
|
|
||||||
echo " $0 --agent=openagent --variant=grok"
|
|
||||||
echo ""
|
|
||||||
echo "Available prompts:"
|
echo "Available prompts:"
|
||||||
for agent_dir in "$PROMPTS_DIR"/*/; do
|
for agent_dir in "$PROMPTS_DIR"/*/; do
|
||||||
|
[ -d "$agent_dir" ] || continue
|
||||||
agent=$(basename "$agent_dir")
|
agent=$(basename "$agent_dir")
|
||||||
echo " $agent:"
|
echo " $agent:"
|
||||||
|
echo " - default (canonical agent file)"
|
||||||
for prompt in "$agent_dir"*.md; do
|
for prompt in "$agent_dir"*.md; do
|
||||||
if [[ -f "$prompt" ]] && [[ "$(basename "$prompt")" != "TEMPLATE.md" ]] && [[ "$(basename "$prompt")" != "README.md" ]]; then
|
if [[ -f "$prompt" ]] && [[ "$(basename "$prompt")" != "TEMPLATE.md" ]] && [[ "$(basename "$prompt")" != "README.md" ]]; then
|
||||||
variant=$(basename "$prompt" .md)
|
variant=$(basename "$prompt" .md)
|
||||||
model_family=$(extract_metadata "$prompt" "model_family")
|
model_family=$(extract_metadata "$prompt" "model_family")
|
||||||
|
if [[ -n "$model_family" ]]; then
|
||||||
echo " - $variant ($model_family family)"
|
echo " - $variant ($model_family family)"
|
||||||
|
else
|
||||||
|
echo " - $variant"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
@ -136,15 +148,43 @@ if [[ -z "$AGENT_NAME" ]] || [[ -z "$PROMPT_VARIANT" ]]; then
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PROMPT_FILE="$PROMPTS_DIR/$AGENT_NAME/$PROMPT_VARIANT.md"
|
|
||||||
AGENT_FILE="$AGENT_DIR/$AGENT_NAME.md"
|
AGENT_FILE="$AGENT_DIR/$AGENT_NAME.md"
|
||||||
|
|
||||||
|
# Check agent exists
|
||||||
|
if [[ ! -f "$AGENT_FILE" ]]; then
|
||||||
|
echo -e "${RED}Error: Agent not found: $AGENT_FILE${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Available agents:"
|
||||||
|
ls -1 "$AGENT_DIR/"*.md 2>/dev/null | xargs -I {} basename {} .md || echo " (none found)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle "default" variant - agent file is already the default
|
||||||
|
if [[ "$PROMPT_VARIANT" == "default" ]]; then
|
||||||
|
echo -e "${GREEN}✓${NC} Agent ${GREEN}$AGENT_NAME${NC} is using the ${GREEN}default${NC} prompt"
|
||||||
|
echo ""
|
||||||
|
echo " Location: $AGENT_FILE"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Note:${NC} In the new architecture, agent files are the canonical defaults."
|
||||||
|
echo " No action needed - you're already using the default!"
|
||||||
|
echo ""
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For non-default variants, copy from prompts directory
|
||||||
|
PROMPT_FILE="$PROMPTS_DIR/$AGENT_NAME/$PROMPT_VARIANT.md"
|
||||||
|
|
||||||
# Check prompt exists
|
# Check prompt exists
|
||||||
if [[ ! -f "$PROMPT_FILE" ]]; then
|
if [[ ! -f "$PROMPT_FILE" ]]; then
|
||||||
echo -e "${RED}Error: Prompt not found: $PROMPT_FILE${NC}"
|
echo -e "${RED}Error: Prompt variant not found: $PROMPT_FILE${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available prompts for $AGENT_NAME:"
|
echo "Available variants for $AGENT_NAME:"
|
||||||
ls -1 "$PROMPTS_DIR/$AGENT_NAME/"*.md 2>/dev/null | xargs -I {} basename {} .md || echo " (none found)"
|
echo " - default (canonical agent file)"
|
||||||
|
if [[ -d "$PROMPTS_DIR/$AGENT_NAME" ]]; then
|
||||||
|
ls -1 "$PROMPTS_DIR/$AGENT_NAME/"*.md 2>/dev/null | grep -v "TEMPLATE.md" | grep -v "README.md" | xargs -I {} basename {} .md || echo " (no model variants found)"
|
||||||
|
else
|
||||||
|
echo " (no model variants found)"
|
||||||
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -178,5 +218,8 @@ if [[ -n "$MODEL_FAMILY" ]]; then
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "To restore the default:"
|
||||||
|
echo " ./scripts/prompts/use-prompt.sh --agent=$AGENT_NAME --variant=default"
|
||||||
|
echo ""
|
||||||
echo "To test this prompt:"
|
echo "To test this prompt:"
|
||||||
echo " ./scripts/prompts/test-prompt.sh --agent=$AGENT_NAME --variant=$PROMPT_VARIANT"
|
echo " ./scripts/prompts/test-prompt.sh --agent=$AGENT_NAME --variant=$PROMPT_VARIANT"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Validate that all agents use their default prompts
|
# Validate prompt library structure
|
||||||
# This ensures PRs maintain stable defaults in the main branch
|
# Agent files in .opencode/agent/ are the canonical defaults
|
||||||
|
# Prompts in .opencode/prompts/ are model-specific variants
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|
@ -13,9 +14,10 @@ WARNINGS=0
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
echo "🔍 Validating agent prompts..."
|
echo "🔍 Validating prompt library structure..."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Check if prompts directory exists
|
# Check if prompts directory exists
|
||||||
|
|
@ -26,36 +28,57 @@ if [ ! -d "$PROMPTS_DIR" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Validate structure: agent files are canonical, prompts are variants
|
||||||
|
echo -e "${BLUE}Architecture:${NC}"
|
||||||
|
echo " • Agent files (.opencode/agent/*.md) = Canonical defaults"
|
||||||
|
echo " • Prompt variants (.opencode/prompts/<agent>/<model>.md) = Model-specific optimizations"
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Find all agent markdown files (excluding subagents)
|
# Find all agent markdown files (excluding subagents)
|
||||||
for agent_file in "$AGENT_DIR"/*.md; do
|
for agent_file in "$AGENT_DIR"/*.md; do
|
||||||
# Skip if no files found
|
# Skip if no files found
|
||||||
[ -e "$agent_file" ] || continue
|
[ -e "$agent_file" ] || continue
|
||||||
|
|
||||||
agent_name=$(basename "$agent_file" .md)
|
agent_name=$(basename "$agent_file" .md)
|
||||||
default_file="$PROMPTS_DIR/$agent_name/default.md"
|
prompts_subdir="$PROMPTS_DIR/$agent_name"
|
||||||
|
|
||||||
# Check if default exists
|
# Check if prompts directory exists for this agent
|
||||||
if [ ! -f "$default_file" ]; then
|
if [ ! -d "$prompts_subdir" ]; then
|
||||||
echo -e "${YELLOW}⚠️ No default found for $agent_name${NC}"
|
echo -e "${YELLOW}⚠️ No prompt variants for $agent_name${NC}"
|
||||||
echo " Expected: $default_file"
|
echo " Agent file: $agent_file (canonical default)"
|
||||||
echo " This agent will be skipped."
|
echo " Variants directory: $prompts_subdir (not found)"
|
||||||
|
echo " This is OK - variants are optional."
|
||||||
echo ""
|
echo ""
|
||||||
WARNINGS=$((WARNINGS + 1))
|
WARNINGS=$((WARNINGS + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Compare files
|
# Check for default.md (should NOT exist in new architecture)
|
||||||
if ! diff -q "$agent_file" "$default_file" > /dev/null 2>&1; then
|
if [ -f "$prompts_subdir/default.md" ]; then
|
||||||
echo -e "${RED}❌ $agent_name.md does not match default${NC}"
|
echo -e "${RED}❌ Found default.md for $agent_name${NC}"
|
||||||
echo " Current: $agent_file"
|
echo " Location: $prompts_subdir/default.md"
|
||||||
echo " Expected: $default_file"
|
echo " This file should not exist in the new architecture."
|
||||||
echo ""
|
echo ""
|
||||||
echo " To fix this:"
|
echo " To fix:"
|
||||||
echo " ./scripts/prompts/use-prompt.sh $agent_name default"
|
echo " rm $prompts_subdir/default.md"
|
||||||
|
echo ""
|
||||||
|
echo " The agent file is now the canonical default:"
|
||||||
|
echo " $agent_file"
|
||||||
echo ""
|
echo ""
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1))
|
||||||
else
|
else
|
||||||
echo -e "${GREEN}✅ $agent_name.md matches default${NC}"
|
# Count variants
|
||||||
|
variant_count=$(find "$prompts_subdir" -maxdepth 1 -name "*.md" -not -name "README.md" -not -name "TEMPLATE.md" | wc -l | tr -d ' ')
|
||||||
|
|
||||||
|
if [ "$variant_count" -gt 0 ]; then
|
||||||
|
echo -e "${GREEN}✅ $agent_name${NC}"
|
||||||
|
echo " Default: $agent_file"
|
||||||
|
echo " Variants: $variant_count model-specific optimization(s)"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✅ $agent_name${NC}"
|
||||||
|
echo " Default: $agent_file"
|
||||||
|
echo " Variants: none (using default for all models)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -63,25 +86,21 @@ echo ""
|
||||||
|
|
||||||
# Summary
|
# Summary
|
||||||
if [ $FAILED -eq 0 ] && [ $WARNINGS -eq 0 ]; then
|
if [ $FAILED -eq 0 ] && [ $WARNINGS -eq 0 ]; then
|
||||||
echo -e "${GREEN}✅ All agents use default prompts${NC}"
|
echo -e "${GREEN}✅ Prompt library structure is valid${NC}"
|
||||||
exit 0
|
exit 0
|
||||||
elif [ $FAILED -eq 0 ]; then
|
elif [ $FAILED -eq 0 ]; then
|
||||||
echo -e "${YELLOW}⚠️ Validation passed with $WARNINGS warning(s)${NC}"
|
echo -e "${YELLOW}⚠️ Validation passed with $WARNINGS warning(s)${NC}"
|
||||||
echo " Some agents don't have defaults yet - this is expected during development."
|
echo " Some agents don't have variant directories yet - this is expected."
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo -e "${RED}❌ PR validation failed - $FAILED agent(s) do not use default prompts${NC}"
|
echo -e "${RED}❌ PR validation failed - $FAILED issue(s) found${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "PRs must use default prompts to keep the main branch stable."
|
echo "The new prompt architecture:"
|
||||||
|
echo " • Agent files (.opencode/agent/*.md) are the canonical defaults"
|
||||||
|
echo " • Prompt variants (.opencode/prompts/<agent>/<model>.md) are model-specific"
|
||||||
|
echo " • default.md files should NOT exist"
|
||||||
echo ""
|
echo ""
|
||||||
echo "To fix:"
|
echo "See docs/contributing/CONTRIBUTING.md for details"
|
||||||
echo " 1. Restore defaults: ./scripts/prompts/use-prompt.sh <agent> default"
|
|
||||||
echo " 2. Or run: ./scripts/prompts/validate-pr.sh"
|
|
||||||
echo ""
|
|
||||||
echo "If you're adding a new prompt variant:"
|
|
||||||
echo " - Add it to .opencode/prompts/<agent>/<variant>.md"
|
|
||||||
echo " - Do NOT modify .opencode/agent/<agent>.md"
|
|
||||||
echo " - See docs/contributing/CONTRIBUTING.md for details"
|
|
||||||
echo ""
|
echo ""
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
34
src/calculator.js
Normal file
34
src/calculator.js
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* Calculator Module
|
||||||
|
* Pure functions for basic arithmetic operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds two numbers
|
||||||
|
* @param {number} a - First number
|
||||||
|
* @param {number} b - Second number
|
||||||
|
* @returns {number} Sum of a and b
|
||||||
|
*/
|
||||||
|
const add = (a, b) => a + b;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtracts second number from first number
|
||||||
|
* @param {number} a - Number to subtract from
|
||||||
|
* @param {number} b - Number to subtract
|
||||||
|
* @returns {number} Difference of a and b
|
||||||
|
*/
|
||||||
|
const subtract = (a, b) => a - b;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies two numbers
|
||||||
|
* @param {number} a - First number
|
||||||
|
* @param {number} b - Second number
|
||||||
|
* @returns {number} Product of a and b
|
||||||
|
*/
|
||||||
|
const multiply = (a, b) => a * b;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
add,
|
||||||
|
subtract,
|
||||||
|
multiply,
|
||||||
|
};
|
||||||
39
src/models/User.js
Normal file
39
src/models/User.js
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* User model with name and email properties
|
||||||
|
*/
|
||||||
|
class User {
|
||||||
|
/**
|
||||||
|
* Creates a new User instance
|
||||||
|
* @param {string} name - User's name
|
||||||
|
* @param {string} email - User's email address
|
||||||
|
*/
|
||||||
|
constructor(name, email) {
|
||||||
|
this.name = name;
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a plain object representation of the user
|
||||||
|
* @returns {Object} User data as plain object
|
||||||
|
*/
|
||||||
|
toObject() {
|
||||||
|
return {
|
||||||
|
name: this.name,
|
||||||
|
email: this.email
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new User with updated properties (immutable update)
|
||||||
|
* @param {Object} updates - Properties to update
|
||||||
|
* @returns {User} New User instance with updates applied
|
||||||
|
*/
|
||||||
|
update(updates) {
|
||||||
|
return new User(
|
||||||
|
updates.name ?? this.name,
|
||||||
|
updates.email ?? this.email
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = User;
|
||||||
Loading…
Reference in a new issue