chore: capture semantic pipeline baseline
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
"""Cost plan for the residual AI work items, with budget guard (section 18).
|
||||
|
||||
Runs BEFORE any real execution: UNIQUE_AI_WORK_ITEMS, token estimates per task type,
|
||||
estimated cost, and the authorize/refuse verdict against AI_MAX_RUN_COST_USD.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
||||
|
||||
from sqlalchemy import select
|
||||
from central.app.ai.provider import BudgetGuard
|
||||
from central.app.config import settings
|
||||
from central.app.db import SessionLocal
|
||||
from central.app.models import AiWorkItem
|
||||
|
||||
TOKENS_PER_ITEM = { # conservative prompt+schema overhead per single work item
|
||||
"INVALID_NCM": (700, 120),
|
||||
"CEST": (500, 80),
|
||||
"EX_TIPI": (500, 80),
|
||||
"PRODUCT_ROLE": (400, 60),
|
||||
}
|
||||
|
||||
|
||||
def main(output="docs/AI_COST_PLAN_V1.json") -> dict:
|
||||
session = SessionLocal()
|
||||
items = session.scalars(select(AiWorkItem)).all()
|
||||
guard = BudgetGuard(settings.ai_max_run_cost_usd, settings.ai_price_in_per_m, settings.ai_price_out_per_m)
|
||||
per_task = {}
|
||||
in_total = out_total = 0
|
||||
resolved = {"KB_HIT", "KB_EXACT_HIT", "KB_FINGERPRINT_HIT", "HIGH_CONFIDENCE_RETRIEVAL", "SINGLE_OFFICIAL_CANDIDATE", "DONE", "SKIPPED", "CONFLICT"}
|
||||
for item in items:
|
||||
if item.status in resolved:
|
||||
continue # cache/official candidate resolved — no AI call needed
|
||||
tokens_in, tokens_out = TOKENS_PER_ITEM.get(item.task_type, (500, 80))
|
||||
bucket = per_task.setdefault(item.task_type, {"items": 0, "input_tokens": 0, "output_tokens": 0, "cells_covered": 0})
|
||||
bucket["items"] += 1; bucket["input_tokens"] += tokens_in; bucket["output_tokens"] += tokens_out
|
||||
bucket["cells_covered"] += item.cells_covered
|
||||
in_total += tokens_in; out_total += tokens_out
|
||||
plan = guard.estimate(in_total, out_total)
|
||||
report = {
|
||||
"artifact": "AI_COST_PLAN_V1",
|
||||
"unique_ai_work_items": sum(bucket["items"] for bucket in per_task.values()),
|
||||
"per_task_type": per_task,
|
||||
"estimated_input_tokens": plan["input_tokens"],
|
||||
"estimated_output_tokens": plan["output_tokens"],
|
||||
"estimated_cost_usd": plan["estimated_cost"],
|
||||
"ai_max_run_cost_usd": guard.max_run_cost_usd,
|
||||
"budget_authorized": guard.authorize(plan),
|
||||
"provider_configured": settings.ai_provider,
|
||||
"model_configured": settings.ai_model,
|
||||
"ai_enabled": settings.ai_enabled,
|
||||
"max_batch_size": settings.ai_max_batch_size,
|
||||
"min_confidence": settings.ai_min_confidence,
|
||||
}
|
||||
Path(output).write_text(json.dumps(report, indent=2, ensure_ascii=False), encoding="utf-8")
|
||||
session.close()
|
||||
return report
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--output", default="/tmp/ai_cost_plan.json")
|
||||
args = parser.parse_args()
|
||||
print(json.dumps(main(args.output), indent=2))
|
||||
|
||||
Reference in New Issue
Block a user