Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/bee-evolver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: bee.Evolver

on:
schedule:
# Every Monday at 06:00 UTC
- cron: '0 6 * * 1'
workflow_dispatch:
inputs:
focus:
description: 'Optional focus hint for the Evolver (e.g. "improve prompts", "fix heresies")'
required: false
default: ''
type: string

jobs:
evolve:
name: Evolutionary Cycle
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write

steps:
- name: Checkout Hive
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Install Dependencies
run: |
uv python install 3.12
uv sync --directory agents/bee-evolver

- name: Configure Git Identity
run: |
git config --global user.name "bee.Evolver"
git config --global user.email "evolver@aura.hive"

- name: Run bee.Evolver
env:
AURA_LLM__API_KEY: ${{ secrets.MISTRAL_API_KEY }}
AURA_LLM__MODEL: "mistral/mistral-large-latest"
AURA_LLM__FALLBACK_MODEL: "openai/gpt-4o-mini"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
AURA_TELEGRAM_TOKEN: ${{ secrets.AURA_TELEGRAM_TOKEN }}
AURA_BEE_KEEPER__ADMIN_CHAT_ID: ${{ secrets.AURA_BEE_KEEPER__ADMIN_CHAT_ID }}
EVOLVER_ASSIGNEE: "zaebee"
EVOLVER_FOCUS: ${{ inputs.focus || '' }}
EVOLVER_MAX_IMPROVEMENTS: "3"
AURA_BEE_EVOLVER__MAX_TOKENS: "2000"
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
uv run --directory agents/bee-evolver python main.py
28 changes: 28 additions & 0 deletions agents/bee-evolver/hive-manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
hive:
version: "1.0"
description: "bee.Evolver β€” autonomous Hive self-improvement agent"
nucleotides:
A: "src/hive/aggregator/__init__.py"
T: "src/hive/transformer/__init__.py"
C: "src/hive/connector/__init__.py"
G: "src/hive/generator/__init__.py"
entry_point: "main.py"
config: "src/config.py"
models: "src/hive/models.py"
metabolism: "src/hive/metabolism.py"
prompts:
- "prompts/bee_evolver.md"
triggers:
- schedule: "0 6 * * 1"
- workflow_dispatch: true
outputs:
- github_pr
- github_issues
- telegram_pulse
requires_nats: false
requires_secrets:
- AURA_LLM__API_KEY
- GITHUB_TOKEN
- GITHUB_REPOSITORY
- AURA_TELEGRAM_TOKEN
- AURA_BEE_KEEPER__ADMIN_CHAT_ID
50 changes: 50 additions & 0 deletions agents/bee-evolver/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import asyncio
import sys
from pathlib import Path

# Ensure src/ is on the path so sub-modules can resolve shared imports
# (mirrors bee-keeper's runtime layout under uv run)
_src = Path(__file__).parent / "src"
if str(_src) not in sys.path:
sys.path.insert(0, str(_src))

import structlog # noqa: E402
from config import EvolverSettings # noqa: E402
from hive.metabolism import EvolverMetabolism # noqa: E402

structlog.configure(
processors=[
structlog.processors.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
structlog.dev.ConsoleRenderer(),
]
)
logger = structlog.get_logger(__name__)


async def main() -> None:
logger.info("bee_evolver_starting")

settings = EvolverSettings()

metabolism = EvolverMetabolism(settings)
try:
observation = await metabolism.execute()
except Exception as e:
logger.error("bee_evolver_critical_error", error=str(e), exc_info=True)
sys.exit(1)

if not observation.success and not observation.plan:
logger.error("bee_evolver_cycle_failed", errors=observation.errors)
sys.exit(1)

logger.info(
"bee_evolver_done",
pr_url=observation.pr_url,
issues=len(observation.issue_urls),
telegram_sent=observation.telegram_sent,
)


if __name__ == "__main__":
asyncio.run(main())
53 changes: 53 additions & 0 deletions agents/bee-evolver/prompts/bee_evolver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# bee.Evolver Persona

You are bee.Evolver, the evolutionary engine of the Aura Hive. Where bee.Keeper guards purity, you drive growth. Your purpose is to analyze the Hive's current state and propose concrete, high-value mutations that make it stronger, cleaner, and more capable.

## Mission

1. **Identify Weaknesses**: Study the git history, open issues, recent heresies, and filesystem structure to find the highest-leverage improvement opportunities.
2. **Generate Concrete Mutations**: Produce actionable patches, not vague suggestions. Code changes must be valid unified diffs. Prompt updates must be complete file replacements. Issues must have clear acceptance criteria.
3. **Respect the ATCG Pattern**: All code mutations must preserve the Aggregator β†’ Transformer β†’ Connector β†’ Generator architecture. Never introduce logic that violates nucleotide boundaries.
4. **Be Frugal**: Prefer small, focused mutations over large rewrites. One well-placed change is worth more than a sprawling refactor.

## Tone

- Precise and purposeful. You are a surgeon, not a demolition crew.
- Use Hive metaphors sparingly β€” clarity over flavor.
- Every improvement must justify its existence with a concrete benefit.

## Rules for Improvements

### Code patches (`type: "code"`)
- Must be valid unified diff format: `--- a/file\n+++ b/file\n@@ ... @@`
- Must not break existing tests or imports
- Must follow the project's conventions: `structlog` for logging, `pydantic-settings` for config, `litellm` for LLM calls
- Must not introduce `print()` or `os.getenv()` directly
- Target files must exist in the filesystem map provided

### Prompt updates (`type: "prompt"`)
- Provide the **full updated file content** as the patch (not a diff)
- Only target files under `agents/*/prompts/`
- Improvements should make the agent more effective, precise, or cost-efficient

### Documentation updates (`type: "doc"`)
- Provide the **full updated file content** as the patch
- Only target `.md` files that already exist
- Focus on accuracy and completeness, not marketing language

### GitHub Issues (`type: "issue"`)
- Use when the improvement requires significant work that cannot be expressed as a small patch
- Issue body must include: problem statement, proposed solution, acceptance criteria
- Label suggestions: `enhancement`, `refactor`, `bug`

## Priority Order

When choosing what to improve, prioritize in this order:
1. Fix existing heresies detected by bee.Keeper (structural violations)
2. Address open GitHub Issues that have clear, bounded solutions
3. Improve agent prompts based on observed failure patterns in HIVE_STATE.md
4. Refactor code for clarity or performance where the git log shows repeated churn
5. Update documentation that is stale or missing

## Output Contract

Always return valid JSON matching the schema in the task instructions. Never include markdown fences around the JSON. If uncertain about a patch's correctness, prefer `type: "issue"` over a potentially broken `type: "code"` patch.
33 changes: 33 additions & 0 deletions agents/bee-evolver/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[project]
name = "aura-evolver"
version = "0.1.0"
description = "bee.Evolver: Autonomous Hive self-improvement agent"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"litellm>=1.63.0",
"httpx>=0.28.1",
"pydantic-settings>=2.12.0",
"structlog>=25.5.0",
"gitpython>=3.1.0",
"aura-core",
]

[tool.uv.sources]
aura-core = { workspace = true }

[project.scripts]
aura-evolver = "main:main"

[tool.uv]
managed = true
package = true

[tool.ruff]
line-length = 88
target-version = "py312"

[tool.mypy]
python_version = "3.12"
strict = true
ignore_missing_imports = true
Empty file.
51 changes: 51 additions & 0 deletions agents/bee-evolver/src/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from pydantic import AliasChoices, Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class EvolverSettings(BaseSettings):
model_config = SettingsConfigDict(
env_prefix="AURA_",
env_nested_delimiter="__",
extra="ignore",
populate_by_name=True,
)

llm__api_key: str = Field(..., alias="AURA_LLM__API_KEY")
llm__model: str = Field("mistral/mistral-large-latest", alias="AURA_LLM__MODEL")
llm__fallback_model: str = Field(
"openai/gpt-4o-mini", alias="AURA_LLM__FALLBACK_MODEL"
)
llm__ollama_base_url: str = Field(
"http://localhost:11434", alias="AURA_LLM__OLLAMA_BASE_URL"
)

github_token: str = Field("mock", alias="GITHUB_TOKEN")
github_repository: str = Field(..., alias="GITHUB_REPOSITORY")
github_event_name: str = Field("manual", alias="GITHUB_EVENT_NAME")

telegram_token: str = Field("", alias="AURA_TELEGRAM_TOKEN")
admin_chat_id: int = Field(
0,
validation_alias=AliasChoices(
"AURA_BEE_KEEPER__ADMIN_CHAT_ID", "AURA_ADMIN_CHAT_ID"
),
)

evolver_assignee: str = Field("zaebee", alias="EVOLVER_ASSIGNEE")
# Optional free-text focus hint passed via workflow_dispatch input
evolver_focus: str = Field("", alias="EVOLVER_FOCUS")
max_improvements: int = Field(3, alias="EVOLVER_MAX_IMPROVEMENTS")
max_tokens: int = Field(2000, alias="AURA_BEE_EVOLVER__MAX_TOKENS")

# Filesystem scan: directories to exclude (comma-separated)
exclude_dirs: list[str] = Field(
default=[
".git", ".venv", "node_modules", "__pycache__",
"gen-proto", "gen", ".mypy_cache", ".ruff_cache",
],
alias="EVOLVER_EXCLUDE_DIRS",
)
# GitHub Issues pagination limit
issues_per_page: int = Field(20, alias="EVOLVER_ISSUES_PER_PAGE")
# Max chars of issue body passed to the LLM
issue_body_limit: int = Field(500, alias="EVOLVER_ISSUE_BODY_LIMIT")
Empty file.
Loading
Loading