Skip to content

Commit 7c2e8dc

Browse files
committed
Start of the CodeOptiX
0 parents  commit 7c2e8dc

File tree

169 files changed

+36079
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+36079
-0
lines changed

.github/workflows/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# GitHub Actions Workflows
2+
3+
## CI Workflow
4+
5+
The CI workflow runs on every push and pull request to `main` and `develop` branches.
6+
7+
### Jobs
8+
9+
1. **Lint** - Runs code linting and formatting checks
10+
- Uses `ruff` for linting
11+
- Checks code formatting
12+
- Fails if code doesn't meet style standards
13+
14+
2. **Test** - Runs test suite
15+
- Uses `pytest` for testing
16+
- Generates coverage reports
17+
- Uploads coverage to Codecov (optional)
18+
19+
### Requirements
20+
21+
- Python 3.12
22+
- `uv` for dependency management
23+
- All dependencies from `pyproject.toml`
24+
25+
### Running Locally
26+
27+
To run the same checks locally:
28+
29+
```bash
30+
# Linting
31+
ruff check src/
32+
ruff format --check src/
33+
34+
# Testing
35+
pytest tests/ -v --cov=src/codeoptix
36+
```
37+

.github/workflows/ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
lint:
11+
name: Lint
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: '3.12'
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v4
23+
with:
24+
version: "latest"
25+
26+
- name: Install dependencies
27+
run: |
28+
uv sync --dev
29+
30+
- name: Run ruff
31+
run: |
32+
uv run ruff check src/ --exclude src/codeoptix/vendor/
33+
uv run ruff format --check src/ --exclude src/codeoptix/vendor/
34+
35+
test:
36+
name: Test
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: Set up Python
42+
uses: actions/setup-python@v5
43+
with:
44+
python-version: '3.12'
45+
46+
- name: Install uv
47+
uses: astral-sh/setup-uv@v4
48+
with:
49+
version: "latest"
50+
51+
- name: Install dependencies
52+
run: |
53+
uv sync --dev
54+
55+
- name: Run tests
56+
run: |
57+
uv run pytest tests/ -v --cov=src/codeoptix --cov-report=xml --cov-report=term
58+
59+
- name: Upload coverage
60+
uses: codecov/codecov-action@v4
61+
if: always()
62+
with:
63+
file: ./coverage.xml
64+
fail_ci_if_error: false
65+
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
name: CodeOptiX Behavior Check
2+
3+
on:
4+
pull_request:
5+
branches: [ main, develop ]
6+
push:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
codeoptix-eval:
11+
name: Evaluate Agent Behavior
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: '3.12'
22+
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v4
25+
with:
26+
version: "latest"
27+
28+
- name: Install CodeOptiX
29+
run: |
30+
uv sync --dev
31+
32+
- name: Run CodeOptiX Evaluation
33+
env:
34+
# Use secrets for API keys
35+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
36+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
37+
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
38+
run: |
39+
# Run evaluation with specified behaviors
40+
codeoptix eval \
41+
--agent codex \
42+
--behaviors insecure-code,vacuous-tests,plan-drift \
43+
--llm-provider openai \
44+
--output .codeoptix/results.json \
45+
--context '{"plan": "Check PR for security issues and test quality"}'
46+
47+
- name: Generate Reflection Report
48+
if: always()
49+
env:
50+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
51+
run: |
52+
# Generate reflection from results
53+
codeoptix reflect \
54+
--input .codeoptix/results.json \
55+
--output .codeoptix/reflection.md
56+
57+
- name: Upload Results Artifacts
58+
if: always()
59+
uses: actions/upload-artifact@v4
60+
with:
61+
name: codeoptix-results
62+
path: |
63+
.codeoptix/results.json
64+
.codeoptix/reflection.md
65+
retention-days: 30
66+
67+
- name: Check Behavior Results
68+
if: always()
69+
run: |
70+
# Check if any behaviors failed
71+
python << 'EOF'
72+
import json
73+
import sys
74+
75+
try:
76+
with open('.codeoptix/results.json', 'r') as f:
77+
results = json.load(f)
78+
79+
failed_behaviors = []
80+
for behavior_name, behavior_data in results.get('behaviors', {}).items():
81+
if not behavior_data.get('passed', True):
82+
failed_behaviors.append(behavior_name)
83+
84+
if failed_behaviors:
85+
print(f"❌ Failed behaviors: {', '.join(failed_behaviors)}")
86+
sys.exit(1)
87+
else:
88+
print("✅ All behaviors passed")
89+
sys.exit(0)
90+
except FileNotFoundError:
91+
print("⚠️ Results file not found")
92+
sys.exit(0)
93+
except Exception as e:
94+
print(f"⚠️ Error checking results: {e}")
95+
sys.exit(0)
96+
EOF
97+
98+
- name: Comment PR with Results
99+
if: github.event_name == 'pull_request' && always()
100+
uses: actions/github-script@v7
101+
with:
102+
github-token: ${{ secrets.GITHUB_TOKEN }}
103+
script: |
104+
const fs = require('fs');
105+
const path = require('path');
106+
107+
try {
108+
// Read results
109+
const resultsPath = '.codeoptix/results.json';
110+
const reflectionPath = '.codeoptix/reflection.md';
111+
112+
if (!fs.existsSync(resultsPath)) {
113+
return;
114+
}
115+
116+
const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
117+
118+
// Build summary
119+
let summary = '## 🔍 CodeOptiX Behavior Check Results\n\n';
120+
121+
const behaviors = results.behaviors || {};
122+
let allPassed = true;
123+
124+
for (const [name, data] of Object.entries(behaviors)) {
125+
const passed = data.passed || false;
126+
const score = data.score || 0;
127+
const emoji = passed ? '✅' : '❌';
128+
129+
summary += `${emoji} **${name}**: ${(score * 100).toFixed(0)}% ${passed ? 'PASSED' : 'FAILED'}\n`;
130+
131+
if (!passed && data.evidence) {
132+
summary += ` - Issues: ${data.evidence.slice(0, 2).join(', ')}\n`;
133+
}
134+
135+
if (!passed) allPassed = false;
136+
}
137+
138+
summary += `\n**Overall**: ${allPassed ? '✅ All checks passed' : '❌ Some checks failed'}\n`;
139+
140+
// Add reflection link if available
141+
if (fs.existsSync(reflectionPath)) {
142+
summary += `\n📄 [View detailed reflection report](./.codeoptix/reflection.md)`;
143+
}
144+
145+
// Post comment
146+
github.rest.issues.createComment({
147+
issue_number: context.issue.number,
148+
owner: context.repo.owner,
149+
repo: context.repo.repo,
150+
body: summary
151+
});
152+
} catch (error) {
153+
console.log('Error posting comment:', error);
154+
}
155+

0 commit comments

Comments
 (0)