Skip to content

Commit 702a19b

Browse files
authored
Merge branch 'codelion:main' into main
2 parents 6abe141 + bda1b39 commit 702a19b

File tree

18 files changed

+1723
-249
lines changed

18 files changed

+1723
-249
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
# Optional: Only run on specific file changes
7+
# paths:
8+
# - "src/**/*.ts"
9+
# - "src/**/*.tsx"
10+
# - "src/**/*.js"
11+
# - "src/**/*.jsx"
12+
13+
jobs:
14+
claude-review:
15+
# Optional: Filter by PR author
16+
# if: |
17+
# github.event.pull_request.user.login == 'external-contributor' ||
18+
# github.event.pull_request.user.login == 'new-developer' ||
19+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20+
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
pull-requests: read
25+
issues: read
26+
id-token: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 1
33+
34+
- name: Run Claude Code Review
35+
id: claude-review
36+
uses: anthropics/claude-code-action@beta
37+
with:
38+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39+
40+
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
41+
# model: "claude-opus-4-20250514"
42+
43+
# Direct prompt for automated review (no @claude mention needed)
44+
direct_prompt: |
45+
Please review this pull request and provide feedback on:
46+
- Code quality and best practices
47+
- Potential bugs or issues
48+
- Performance considerations
49+
- Security concerns
50+
- Test coverage
51+
52+
Be constructive and helpful in your feedback.
53+
54+
# Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
55+
# use_sticky_comment: true
56+
57+
# Optional: Customize review based on file types
58+
# direct_prompt: |
59+
# Review this PR focusing on:
60+
# - For TypeScript files: Type safety and proper interface usage
61+
# - For API endpoints: Security, input validation, and error handling
62+
# - For React components: Performance, accessibility, and best practices
63+
# - For tests: Coverage, edge cases, and test quality
64+
65+
# Optional: Different prompts for different authors
66+
# direct_prompt: |
67+
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
68+
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
69+
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
70+
71+
# Optional: Add specific tools for running tests or linting
72+
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
73+
74+
# Optional: Skip review for certain conditions
75+
# if: |
76+
# !contains(github.event.pull_request.title, '[skip-review]') &&
77+
# !contains(github.event.pull_request.title, '[WIP]')
78+

.github/workflows/claude.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@beta
36+
with:
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
39+
# This is an optional setting that allows Claude to read CI results on PRs
40+
additional_permissions: |
41+
actions: read
42+
43+
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
44+
# model: "claude-opus-4-20250514"
45+
46+
# Optional: Customize the trigger phrase (default: @claude)
47+
# trigger_phrase: "/claude"
48+
49+
# Optional: Trigger when specific user is assigned to an issue
50+
# assignee_trigger: "claude-bot"
51+
52+
# Optional: Allow Claude to run specific commands
53+
# allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
54+
55+
# Optional: Add custom instructions for Claude to customize its behavior for your project
56+
# custom_instructions: |
57+
# Follow our coding standards
58+
# Ensure all new code has tests
59+
# Use TypeScript for new files
60+
61+
# Optional: Custom environment variables for Claude
62+
# claude_env: |
63+
# NODE_ENV: test
64+

examples/rust_adaptive_sort/config.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,5 @@ evaluator:
4949
timeout: 60 # Rust compilation can take time
5050
parallel_evaluations: 3
5151

52-
# Use cascade evaluation for performance testing
53-
cascade_evaluation: true
54-
cascade_thresholds:
55-
- 0.5 # Compilation success and basic correctness
56-
- 0.7 # Good performance
57-
- 0.85 # Excellent adaptability
52+
# Direct evaluation - evaluator doesn't implement cascade functions
53+
cascade_evaluation: false

openevolve/config.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class LLMModelConfig:
3232
timeout: int = None
3333
retries: int = None
3434
retry_delay: int = None
35-
35+
3636
# Reproducibility
3737
random_seed: Optional[int] = None
3838

@@ -56,10 +56,12 @@ class LLMConfig(LLMModelConfig):
5656
retry_delay: int = 5
5757

5858
# n-model configuration for evolution LLM ensemble
59-
models: List[LLMModelConfig] = field(default_factory=lambda: [
60-
LLMModelConfig(name="gpt-4o-mini", weight=0.8),
61-
LLMModelConfig(name="gpt-4o", weight=0.2)
62-
])
59+
models: List[LLMModelConfig] = field(
60+
default_factory=lambda: [
61+
LLMModelConfig(name="gpt-4o-mini", weight=0.8),
62+
LLMModelConfig(name="gpt-4o", weight=0.2),
63+
]
64+
)
6365

6466
# n-model configuration for evaluator LLM ensemble
6567
evaluator_models: List[LLMModelConfig] = field(default_factory=lambda: [])
@@ -264,7 +266,7 @@ def from_dict(cls, config_dict: Dict[str, Any]) -> "Config":
264266
config.prompt = PromptConfig(**config_dict["prompt"])
265267
if "database" in config_dict:
266268
config.database = DatabaseConfig(**config_dict["database"])
267-
269+
268270
# Ensure database inherits the random seed if not explicitly set
269271
if config.database.random_seed is None and config.random_seed is not None:
270272
config.database.random_seed = config.random_seed
@@ -365,4 +367,4 @@ def load_config(config_path: Optional[Union[str, Path]] = None) -> Config:
365367
# Make the system message available to the individual models, in case it is not provided from the prompt sampler
366368
config.llm.update_model_params({"system_message": config.prompt.system_message})
367369

368-
return config
370+
return config

openevolve/controller.py

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,20 @@ def __init__(
104104
# Set global random seeds
105105
random.seed(self.config.random_seed)
106106
np.random.seed(self.config.random_seed)
107-
107+
108108
# Create hash-based seeds for different components
109-
base_seed = str(self.config.random_seed).encode('utf-8')
110-
llm_seed = int(hashlib.md5(base_seed + b'llm').hexdigest()[:8], 16) % (2**31)
111-
109+
base_seed = str(self.config.random_seed).encode("utf-8")
110+
llm_seed = int(hashlib.md5(base_seed + b"llm").hexdigest()[:8], 16) % (2**31)
111+
112112
# Propagate seed to LLM configurations
113113
self.config.llm.random_seed = llm_seed
114114
for model_cfg in self.config.llm.models:
115-
if not hasattr(model_cfg, 'random_seed') or model_cfg.random_seed is None:
115+
if not hasattr(model_cfg, "random_seed") or model_cfg.random_seed is None:
116116
model_cfg.random_seed = llm_seed
117117
for model_cfg in self.config.llm.evaluator_models:
118-
if not hasattr(model_cfg, 'random_seed') or model_cfg.random_seed is None:
118+
if not hasattr(model_cfg, "random_seed") or model_cfg.random_seed is None:
119119
model_cfg.random_seed = llm_seed
120-
120+
121121
logger.info(f"Set random seed to {self.config.random_seed} for reproducibility")
122122
logger.debug(f"Generated LLM seed: {llm_seed}")
123123

@@ -161,7 +161,7 @@ def __init__(
161161
self.evaluation_file = evaluation_file
162162

163163
logger.info(f"Initialized OpenEvolve with {initial_program_path}")
164-
164+
165165
# Initialize improved parallel processing components
166166
self.parallel_controller = None
167167

@@ -212,7 +212,7 @@ async def run(
212212
Best program found
213213
"""
214214
max_iterations = iterations or self.config.max_iterations
215-
215+
216216
# Determine starting iteration
217217
start_iteration = 0
218218
if checkpoint_path and os.path.exists(checkpoint_path):
@@ -260,30 +260,31 @@ async def run(
260260
self.parallel_controller = ImprovedParallelController(
261261
self.config, self.evaluation_file, self.database
262262
)
263-
263+
264264
# Set up signal handlers for graceful shutdown
265265
def signal_handler(signum, frame):
266266
logger.info(f"Received signal {signum}, initiating graceful shutdown...")
267267
self.parallel_controller.request_shutdown()
268-
268+
269269
# Set up a secondary handler for immediate exit if user presses Ctrl+C again
270270
def force_exit_handler(signum, frame):
271271
logger.info("Force exit requested - terminating immediately")
272272
import sys
273+
273274
sys.exit(0)
274-
275+
275276
signal.signal(signal.SIGINT, force_exit_handler)
276-
277+
277278
signal.signal(signal.SIGINT, signal_handler)
278279
signal.signal(signal.SIGTERM, signal_handler)
279-
280+
280281
self.parallel_controller.start()
281-
282+
282283
# Run evolution with improved parallel processing and checkpoint callback
283284
await self._run_evolution_with_checkpoints(
284285
start_iteration, max_iterations, target_score
285286
)
286-
287+
287288
finally:
288289
# Clean up parallel processing resources
289290
if self.parallel_controller:
@@ -420,31 +421,28 @@ def _load_checkpoint(self, checkpoint_path: str) -> None:
420421
"""Load state from a checkpoint directory"""
421422
if not os.path.exists(checkpoint_path):
422423
raise FileNotFoundError(f"Checkpoint directory {checkpoint_path} not found")
423-
424+
424425
logger.info(f"Loading checkpoint from {checkpoint_path}")
425426
self.database.load(checkpoint_path)
426-
logger.info(
427-
f"Checkpoint loaded successfully (iteration {self.database.last_iteration})"
428-
)
427+
logger.info(f"Checkpoint loaded successfully (iteration {self.database.last_iteration})")
429428

430429
async def _run_evolution_with_checkpoints(
431430
self, start_iteration: int, max_iterations: int, target_score: Optional[float]
432431
) -> None:
433432
"""Run evolution with checkpoint saving support"""
434433
logger.info(f"Using island-based evolution with {self.config.database.num_islands} islands")
435434
self.database.log_island_status()
436-
435+
437436
# Run the evolution process with checkpoint callback
438437
await self.parallel_controller.run_evolution(
439-
start_iteration, max_iterations, target_score,
440-
checkpoint_callback=self._save_checkpoint
438+
start_iteration, max_iterations, target_score, checkpoint_callback=self._save_checkpoint
441439
)
442-
440+
443441
# Check if shutdown was requested
444442
if self.parallel_controller.shutdown_flag.is_set():
445443
logger.info("Evolution stopped due to shutdown request")
446444
return
447-
445+
448446
# Save final checkpoint if needed
449447
final_iteration = start_iteration + max_iterations - 1
450448
if final_iteration > 0 and final_iteration % self.config.checkpoint_interval == 0:
@@ -499,4 +497,4 @@ def _save_best_program(self, program: Optional[Program] = None) -> None:
499497
indent=2,
500498
)
501499

502-
logger.info(f"Saved best program to {code_path} with program info to {info_path}")
500+
logger.info(f"Saved best program to {code_path} with program info to {info_path}")

0 commit comments

Comments
 (0)