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:
+26
-11
@@ -19,11 +19,13 @@ import threading
|
||||
from typing import Dict, Optional
|
||||
|
||||
from backend import config
|
||||
from backend.agents.runner import run_agent_pipeline
|
||||
from backend.pipeline.runner import run_pipeline
|
||||
from backend.email_sender import send_conflict_report
|
||||
|
||||
_jobs: Dict[str, Dict] = {}
|
||||
_lock = threading.Lock()
|
||||
PIPELINE_MODES = {"classic", "agent"}
|
||||
|
||||
|
||||
def _set(job_id: str, **fields) -> None:
|
||||
@@ -32,8 +34,14 @@ def _set(job_id: str, **fields) -> None:
|
||||
|
||||
|
||||
def create_job(pdf_path: str, source_filename: str, email: Optional[str] = None,
|
||||
project_input: Optional[Dict] = None, text_local: bool = False) -> str:
|
||||
project_input: Optional[Dict] = None, text_local: bool = False,
|
||||
pipeline_mode: str = "classic") -> str:
|
||||
"""Register a job and kick off its background thread. Returns the job_id."""
|
||||
pipeline_mode = pipeline_mode.strip().lower()
|
||||
if pipeline_mode not in PIPELINE_MODES:
|
||||
raise ValueError(f"Unsupported pipeline mode: {pipeline_mode!r}")
|
||||
# Agent mode v1 is OpenRouter-only.
|
||||
text_local = bool(text_local and pipeline_mode == "classic")
|
||||
job_id = uuid.uuid4().hex[:12]
|
||||
with _lock:
|
||||
_jobs[job_id] = {
|
||||
@@ -43,33 +51,39 @@ def create_job(pdf_path: str, source_filename: str, email: Optional[str] = None,
|
||||
"email": email or None,
|
||||
"project_input": project_input or {},
|
||||
"text_local": text_local,
|
||||
"pipeline_mode": pipeline_mode,
|
||||
"stage": None,
|
||||
"created_at": time.time(),
|
||||
"finished_at": None,
|
||||
"report": None,
|
||||
"error": None,
|
||||
}
|
||||
threading.Thread(target=_run, args=(job_id, pdf_path, project_input, text_local),
|
||||
threading.Thread(target=_run, args=(
|
||||
job_id, pdf_path, project_input, text_local, pipeline_mode,
|
||||
),
|
||||
daemon=True).start()
|
||||
return job_id
|
||||
|
||||
|
||||
def _run(job_id: str, pdf_path: str, project_input: Optional[Dict] = None,
|
||||
text_local: bool = False) -> None:
|
||||
text_local: bool = False, pipeline_mode: str = "classic") -> None:
|
||||
out_dir = os.path.join(config.OUTPUT_DIR, job_id)
|
||||
try:
|
||||
_set(job_id, status="running")
|
||||
# Keep a copy of the source PDF so its sheets can be viewed later.
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
shutil.copy2(pdf_path, os.path.join(out_dir, "source.pdf"))
|
||||
report = run_pipeline(
|
||||
pdf_path,
|
||||
out_dir=out_dir,
|
||||
on_stage=lambda name: _set(job_id, stage=name),
|
||||
project_input=project_input,
|
||||
source_name=_jobs[job_id].get("source"),
|
||||
text_local=text_local,
|
||||
)
|
||||
runner = run_agent_pipeline if pipeline_mode == "agent" else run_pipeline
|
||||
runner_kwargs = {
|
||||
"out_dir": out_dir,
|
||||
"on_stage": lambda name: _set(job_id, stage=name),
|
||||
"project_input": project_input,
|
||||
"source_name": _jobs[job_id].get("source"),
|
||||
}
|
||||
if pipeline_mode == "classic":
|
||||
runner_kwargs["text_local"] = text_local
|
||||
report = runner(pdf_path, **runner_kwargs)
|
||||
report.setdefault("summary", {})["pipeline_mode"] = pipeline_mode
|
||||
_set(job_id, status="done", report=report, finished_at=time.time(), stage=None)
|
||||
_notify(job_id, report, out_dir)
|
||||
except Exception as e:
|
||||
@@ -155,6 +169,7 @@ def get_job(job_id: str) -> Optional[Dict]:
|
||||
"email": None,
|
||||
"project_input": report.get("project_input", {}),
|
||||
"text_local": report.get("summary", {}).get("text_backend") == "local",
|
||||
"pipeline_mode": report.get("summary", {}).get("pipeline_mode", "classic"),
|
||||
"stage": None,
|
||||
"created_at": os.path.getmtime(source_pdf) if os.path.isfile(source_pdf) else None,
|
||||
"finished_at": os.path.getmtime(report_path),
|
||||
|
||||
Reference in New Issue
Block a user