Compare commits

..

1 Commits

Author SHA1 Message Date
5dd8622539 Implement Fallback Portfolio wiring in tasks.py 2026-04-06 17:56:14 +00:00

View File

@@ -2127,32 +2127,26 @@ def cross_review_prs():
return {"reviews": len(results), "details": results}
@huey.periodic_task(crontab(hour="*/12"))
def decomposition_tick():
"""Force Multiplier 12: Automated Issue Decomposition (Epic Splitting).
def get_model_for_task(task_class, agent_name=None):
"""Implement the Fallback Portfolio doctrine (docs/fallback-portfolios.md).
Identifies large issues (EPICs) and flags them for decomposition into sub-tasks.
Reads fallback-portfolios.yaml and returns the primary model for the given task class.
If primary fails, the agent should call this again with an incremented 'attempt' (not implemented here).
"""
gitea = get_gitea_client()
repos = ["Timmy_Foundation/timmy-config", "Timmy_Foundation/timmy-home", "Timmy_Foundation/the-nexus"]
for repo in repos:
issues = gitea.get_open_issues(repo)
for issue in issues:
labels = [l['name'] for l in issue.get('labels', [])]
body = issue.get('body', '')
# Identify EPICs or large task lists
is_epic = "EPIC" in labels or "EPIC" in issue['title']
has_large_tasklist = body.count("- [ ]") > 5
if (is_epic or has_large_tasklist) and "needs-decomposition" not in labels:
audit_log("decomposition_flagged", "system", {"repo": repo, "issue": issue['number']}, confidence="High")
gitea.add_label(repo, issue['number'], "needs-decomposition")
# Add comment suggesting decomposition
msg = "### Automated Decomposition Suggestion\n"
msg += "This issue has been flagged as an **EPIC** or contains a large task list. "
msg += "To improve velocity and reduce cycle time, I recommend splitting this into smaller, atomic issues.\n\n"
msg += "I will attempt to generate a decomposition plan in the next cycle."
gitea.create_issue_comment(repo, issue['number'], msg)
import yaml
portfolio_path = Path(__file__).parent / "fallback-portfolios.yaml"
if not portfolio_path.exists():
return "gemini-1.5-flash" # Default fallback
with open(portfolio_path, "r") as f:
portfolios = yaml.safe_load(f)
# 1. Check agent-specific portfolio
if agent_name and agent_name in portfolios.get("agents", {}):
return portfolios["agents"][agent_name]["primary"]["model"]
# 2. Check task-class portfolio
if task_class in portfolios.get("role_classes", {}):
return portfolios["role_classes"][task_class]["primary"]["model"]
return "gemini-1.5-flash"