-
Couldn't load subscription status.
- Fork 2.9k
Description
#!/usr/bin/env python3
"""
meta_agent.py
Safe meta-algorithm agent that:
- Computes or suggests improvements (example: new AlgorithmBlueprint JSON entry)
- Creates a new branch
- Commits suggested changes to that branch
- Opens a draft pull request for human review
Important safety notes:
- DO NOT hardcode API tokens. This script reads a token from the environment:
GITHUB_TOKEN (recommended, provided by GitHub Actions) - The script avoids modifying its own source file; it writes proposals to the "proposals/" folder.
- The script opens a DRAFT PR for review rather than merging automatically.
"""
import os
import json
import datetime
import hashlib
from typing import Dict, Any
from github import Github, InputGitTreeElement
REPO_FULL = os.getenv("GITHUB_REPOSITORY") # e.g. "owner/repo"
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
if not REPO_FULL or not GITHUB_TOKEN:
raise SystemExit("GITHUB_REPOSITORY and GITHUB_TOKEN must be set in the environment (use GitHub Actions).")
g = Github(GITHUB_TOKEN)
repo = g.get_repo(REPO_FULL)
def now_iso():
return datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
def generate_proposal_payload(step_index: int) -> Dict[str, Any]:
"""
Example of a generated proposal: a new AlgorithmBlueprint-like JSON object.
Replace this logic with your actual meta-algorithm's suggestion generation.
"""
seed = f"{now_iso()}-{step_index}"
unique_id = hashlib.sha1(seed.encode()).hexdigest()[:10]
blueprint = {
"id": f"proposal-{unique_id}",
"domain": "example_domain",
"architecture": {"type": "meta-net", "layers": 3, "units": 128},
"learning_rules": {"lr": 0.001},
"meta_properties": {"exploration": 1.0},
"generated_at": now_iso(),
"note": "This is a proposed blueprint generated for human review."
}
return blueprint
def create_branch_and_commit(file_path: str, content: str, base_branch: str = "main") -> str:
"""
Create a branch from base_branch, add a single file commit, and push it via the GitHub API.
Returns the branch name.
"""
base = repo.get_branch(base_branch)
timestamp = datetime.datetime.utcnow().strftime("%Y%m%d%H%M%S")
branch_name = f"meta-proposal/{timestamp}"
# Create branch reference
ref = f"refs/heads/{branch_name}"
repo.create_git_ref(ref, base.commit.sha)
# Prepare blob and tree
element = InputGitTreeElement(path=file_path, mode="100644", type="blob", content=content)
base_tree = repo.get_git_tree(base.commit.sha)
new_tree = repo.create_git_tree([element], base_tree)
parent = repo.get_git_commit(base.commit.sha)
commit_message = f"meta-agent: add proposal {file_path} ({now_iso()})"
new_commit = repo.create_git_commit(commit_message, new_tree, [parent])
# Update ref to point to new commit
repo.get_git_ref(ref.replace("refs/", "")).edit(new_commit.sha)
return branch_name
def open_draft_pr(branch_name: str, title: str, body: str, base_branch: str = "main"):
"""
Open a draft pull request for human review.
"""
pr = repo.create_pull(title=title, body=body, head=branch_name, base=base_branch, draft=True)
return pr
def main():
# Example: generate a small batch of proposals (this is safe and non-destructive)
proposals = []
for i in range(1): # change to more iterations as needed, but avoid runaway loops
p = generate_proposal_payload(i)
proposals.append(p)
# Persist proposals under proposals/<timestamp>-n.json
filename = f"proposals/proposal-{datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S')}.json"
content = json.dumps({"proposals": proposals}, indent=2)
branch = create_branch_and_commit(filename, content, base_branch="main")
pr_title = f"[meta-agent] Proposed algorithm updates ({now_iso()})"
pr_body = (
"This draft PR was created by the repository meta-agent. It contains proposed algorithm blueprints\n"
"for human review. The agent does NOT merge automatically; please review the proposals and run tests\n"
"before merging.\n\n"
"Proposals added:\n\n"
f"- {filename}\n\n"
"If you want the agent to iterate more or to propose changes to other files, modify the agent and re-run.\n"
)
pr = open_draft_pr(branch, pr_title, pr_body, base_branch="main")
print(f"Opened draft PR #{pr.number}: {pr.html_url}")
if name == "main":
main() && modelcontextprotocol/servers@4d598ce