diff --git a/.github/workflows/score.yml b/.github/workflows/score.yml index 7e78bfa..14c5799 100644 --- a/.github/workflows/score.yml +++ b/.github/workflows/score.yml @@ -12,6 +12,12 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true +# Serialize full-score jobs to avoid concurrent DB writes overwhelming the API. +# Pending runs wait; they do NOT cancel each other (each merged agent must be scored). +concurrency: + group: score-main + cancel-in-progress: false + jobs: find-agent: runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07b588d..dfc6b96 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,10 +28,11 @@ def generate(spec: dict, llm: LLMClient) -> bytes: ... ``` -The harness injects `LLMClient` — no API key required. Whitelisted models: `claude-haiku-4-5`, `claude-3-5-haiku`, `gpt-4o-mini`. Both parameters are required; agents that omit `llm` are rejected at eval time. +The harness injects `LLMClient` — no API key required. Whitelisted models: `anthropic/claude-haiku-4-5`, `anthropic/claude-3-5-haiku`, `openai/gpt-4o-mini`. Both parameters are required; agents that omit `llm` are rejected at eval time. Starting point in `examples/`: -- `metric-aware-agent/` — adapts strategy per scoring metric, call `llm.chat()` to reason about geometry +- `metric-aware-agent/` — adapts strategy per scoring metric; uses `llm.chat()` to reason about geometry +- `llm-agent/` — minimal single-call LLM agent, good for getting started The agent runs inside a Docker container: - **Time:** 60 seconds | **Memory:** 4 GB | **Network:** enabled (LLM calls only) diff --git a/agents/baseline/agent.py b/agents/baseline/agent.py index c7e0cc9..687c7b2 100644 --- a/agents/baseline/agent.py +++ b/agents/baseline/agent.py @@ -29,15 +29,19 @@ def generate(spec: dict, llm: LLMClient) -> bytes: # noqa: ARG001 constraints = spec["constraints"] bolt_pattern = constraints["bolt_pattern_mm"] bolt_d = constraints["bolt_diameter_clearance_mm"] + bv = constraints["build_volume_mm"] # [x, y, z] limits + load_pt = constraints["load_point_mm"] by_coords = [p[0] for p in bolt_pattern] bz_coords = [p[1] for p in bolt_pattern] - plate_y = max(by_coords) + 20.0 - plate_z = max(bz_coords) + 20.0 + # Clamp to build volume — leave 2mm margin to avoid floating-point boundary failures + plate_y = min(max(by_coords) + 20.0, bv[1] - 2.0) + plate_z = min(max(bz_coords) + 20.0, bv[2] - 2.0) plate_thickness = 10.0 - shelf_length = constraints["load_point_mm"][0] + 15.0 - shelf_thickness = 12.0 + # Shelf must reach the load point in X and cover its Z coordinate + shelf_length = min(load_pt[0] + 15.0, bv[0] - 2.0) + shelf_thickness = min(max(15.0, load_pt[2] + 10.0), bv[2] - 2.0) shelf_z = plate_z # Mounting plate