Add scoped Agent-mode pipeline as experimental Classic fork.
Wire specialist waves, Brain consolidation, and Classic-compatible reports so Agent mode can run end-to-end via OpenRouter without changing the default Classic path. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
"""Scoped code/accessibility review agents."""
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
from backend import config
|
||||
from backend.agents.base import AgentResult, AgentScope, AgentUsage, failure
|
||||
from backend.llm import call_json
|
||||
from backend.pipeline import code_refs
|
||||
from backend.pipeline._serialize import dumps, slim_sheets
|
||||
from backend.pipeline._stage import collect_list, validate_issue
|
||||
from backend.pipeline.jurisdiction import active_review_paths
|
||||
from backend.prompts import CODE_REVIEW_SYSTEM_PROMPT, CODE_REVIEW_USER_INSTRUCTION
|
||||
|
||||
|
||||
def build_code_scopes(
|
||||
sheets: List[Dict], jurisdiction: Dict, sheet_index: Dict
|
||||
) -> List[AgentScope]:
|
||||
cap = max(1, config.AGENT_CODE_BATCH_SIZE)
|
||||
fragments: List[Dict] = []
|
||||
for sheet in sheets:
|
||||
assertions = sheet.get("assertions") or []
|
||||
if not assertions:
|
||||
continue
|
||||
for offset in range(0, len(assertions), cap):
|
||||
fragments.append({
|
||||
**sheet,
|
||||
"assertions": assertions[offset:offset + cap],
|
||||
})
|
||||
batches: List[List[Dict]] = []
|
||||
current: List[Dict] = []
|
||||
count = 0
|
||||
for fragment in fragments:
|
||||
size = len(fragment["assertions"])
|
||||
if current and count + size > cap:
|
||||
batches.append(current)
|
||||
current, count = [], 0
|
||||
current.append(fragment)
|
||||
count += size
|
||||
if current:
|
||||
batches.append(current)
|
||||
return [
|
||||
AgentScope(
|
||||
scope_id=f"code:{index + 1}",
|
||||
payload={
|
||||
"sheets": batch,
|
||||
"jurisdiction": jurisdiction,
|
||||
"sheet_index": sheet_index,
|
||||
},
|
||||
)
|
||||
for index, batch in enumerate(batches)
|
||||
]
|
||||
|
||||
|
||||
class CodeAgent:
|
||||
name = "code_reviewer"
|
||||
|
||||
def __init__(self, usage: AgentUsage) -> None:
|
||||
self.usage = usage
|
||||
|
||||
def run(self, scope: AgentScope) -> AgentResult:
|
||||
try:
|
||||
sheets = scope.payload.get("sheets") or []
|
||||
jurisdiction = scope.payload.get("jurisdiction") or {}
|
||||
sheet_index = scope.payload.get("sheet_index") or {}
|
||||
assertions = [
|
||||
assertion for sheet in sheets
|
||||
for assertion in sheet.get("assertions", [])
|
||||
]
|
||||
excerpts = code_refs.retrieve(
|
||||
active_review_paths(jurisdiction), assertions
|
||||
)
|
||||
instruction = CODE_REVIEW_USER_INSTRUCTION
|
||||
for key, value in {
|
||||
"jurisdiction": dumps(jurisdiction),
|
||||
"sheet_index": dumps(sheet_index),
|
||||
"assertions": dumps(slim_sheets(sheets)),
|
||||
"code_references": code_refs.format_excerpts(excerpts),
|
||||
}.items():
|
||||
instruction = instruction.replace("{" + key + "}", value)
|
||||
parsed = call_json(
|
||||
system_prompt=CODE_REVIEW_SYSTEM_PROMPT,
|
||||
user_text=instruction,
|
||||
max_tokens=config.CODE_MAX_TOKENS,
|
||||
model=config.AGENT_CODE_MODEL,
|
||||
usage_tracker=self.usage,
|
||||
usage_stage="agent.code",
|
||||
)
|
||||
findings = collect_list(
|
||||
parsed, "issues", lambda item: validate_issue(item, "code")
|
||||
)
|
||||
for finding in findings:
|
||||
finding.update(agent=self.name, scope_id=scope.scope_id)
|
||||
return AgentResult(scope_id=scope.scope_id, artifacts=findings)
|
||||
except Exception as exc:
|
||||
return failure(scope, exc)
|
||||
Reference in New Issue
Block a user