Skip to content
Open
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
33 changes: 32 additions & 1 deletion backend/app/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,18 @@ async def init_db():
created_at TEXT DEFAULT (datetime('now'))
)
""")

await db.execute("""
CREATE TABLE IF NOT EXISTS patch_outcomes (
id TEXT PRIMARY KEY,
job_id TEXT NOT NULL,
finding_id TEXT NOT NULL,
model TEXT NOT NULL,
passed INTEGER,
prompt_tokens INTEGER,
created_at TEXT DEFAULT (datetime('now')),
verified_at TEXT
)
""")
db.row_factory = aiosqlite.Row
cursor = await db.execute("PRAGMA table_info(findings)")
columns = [row["name"] for row in await cursor.fetchall()]
Expand Down Expand Up @@ -299,3 +310,23 @@ async def upsert_contributor_stat(
(username, findings, fixes, prs),
)
await db.commit()

async def insert_patch_outcome(patch_id: str, job_id: str, finding_id: str, model: str, prompt_tokens: int = None):
"""Inserts a new patch record when an LLM generates a fix."""
async with aiosqlite.connect(DB_PATH) as db:
await db.execute(
"INSERT INTO patch_outcomes (id, job_id, finding_id, model, passed, prompt_tokens) VALUES (?, ?, ?, ?, NULL, ?)",
(patch_id, job_id, finding_id, model, prompt_tokens)
)
await db.commit()


async def update_patch_verification(patch_id: str, passed: bool):
"""Updates the verification status and timestamp of an existing patch."""
passed_int = 1 if passed else 0
async with aiosqlite.connect(DB_PATH) as db:
await db.execute(
"UPDATE patch_outcomes SET passed = ?, verified_at = datetime('now') WHERE id = ?",
(passed_int, patch_id)
)
await db.commit()
24 changes: 23 additions & 1 deletion backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ async def _record_fixes_to_db(job_id: str, fixes: List[Fix]):


@app.post("/fix", response_model=FixResponse)
def fix(req: FixRequest, background_tasks: BackgroundTasks):
async def fix(req: FixRequest, background_tasks: BackgroundTasks):
job_dir = WORK_ROOT / req.job_id
repo_dir = job_dir / "repo"
if not repo_dir.exists():
Expand All @@ -760,6 +760,22 @@ def fix(req: FixRequest, background_tasks: BackgroundTasks):
repo_dir = _maybe_use_single_top_folder(repo_dir)
fixes = propose_fixes(repo_dir, req.finding_ids)

import uuid
from app.db import insert_patch_outcome

for f_id in req.finding_ids:
patch_id = str(uuid.uuid4())
model_name = getattr(req, "model", "Ollama-Local")
tokens = getattr(req, "prompt_tokens", None)

await insert_patch_outcome(
patch_id=patch_id,
job_id=req.job_id,
finding_id=f_id,
model=model_name,
prompt_tokens=tokens
)

background_tasks.add_task(_record_fixes_to_db, req.job_id, fixes)

return FixResponse(job_id=req.job_id, fixes=fixes)
Expand Down Expand Up @@ -846,6 +862,12 @@ async def verify(
),
)
await db.commit()

# --- UPDATE THE PATCH OUTCOMES TRACKING TABLE ---
from app.db import update_patch_verification
await update_patch_verification(patch_id=job_id, passed=bool(passed))
# ------------------------------------------------

finally:
await db.close()
except Exception:
Expand Down
Loading