58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""CLI wrapper for target_revenue.effort_calculator (WP-0010-T02).
|
||
|
|
|
||
|
|
Prints a proposed `phase.target_basis` estimate for a repo, with full
|
||
|
|
derivation and warnings, as JSON. Token counts are caller-supplied (e.g.
|
||
|
|
pulled from the state hub's `get_token_summary` beforehand) rather than
|
||
|
|
fetched here — this script has no MCP client of its own, matching the
|
||
|
|
offline-first design of the rest of this library.
|
||
|
|
|
||
|
|
Does not select a Target Multiple and does not register anything with
|
||
|
|
the hosted Trust Service — this is an estimation aid, not a Phase
|
||
|
|
declaration tool (that remains `scripts/trf_onboard.py`).
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import argparse
|
||
|
|
import dataclasses
|
||
|
|
import json
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||
|
|
sys.path.insert(0, str(REPO_ROOT / "src"))
|
||
|
|
|
||
|
|
from target_revenue import effort_calculator as ec # noqa: E402
|
||
|
|
|
||
|
|
|
||
|
|
def main(argv: list[str] | None = None) -> None:
|
||
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
||
|
|
parser.add_argument("repo_path", help="path to the repo to estimate effort for")
|
||
|
|
parser.add_argument("--daily-rate", type=float, required=True)
|
||
|
|
parser.add_argument("--tokens-in", type=int, default=0)
|
||
|
|
parser.add_argument("--tokens-out", type=int, default=0)
|
||
|
|
parser.add_argument("--model", default="default")
|
||
|
|
parser.add_argument("--session-gap-hours", type=float, default=ec.DEFAULT_SESSION_GAP_HOURS)
|
||
|
|
parser.add_argument("--hours-per-day", type=float, default=ec.DEFAULT_HOURS_PER_DAY)
|
||
|
|
args = parser.parse_args(argv)
|
||
|
|
|
||
|
|
result = ec.calculate_target_basis(
|
||
|
|
args.repo_path,
|
||
|
|
daily_rate=args.daily_rate,
|
||
|
|
tokens_in=args.tokens_in,
|
||
|
|
tokens_out=args.tokens_out,
|
||
|
|
model=args.model,
|
||
|
|
session_gap_hours=args.session_gap_hours,
|
||
|
|
hours_per_day=args.hours_per_day,
|
||
|
|
)
|
||
|
|
|
||
|
|
output = dataclasses.asdict(result)
|
||
|
|
print(json.dumps(output, indent=2))
|
||
|
|
if result.warnings:
|
||
|
|
print(f"\n{len(result.warnings)} warning(s) — see 'warnings' above.", file=sys.stderr)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|