narcolepticchicken commited on
Commit
10dd564
·
verified ·
1 Parent(s): f17c0fd

Upload aco/cli.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. aco/cli.py +98 -108
aco/cli.py CHANGED
@@ -1,123 +1,113 @@
1
- """CLI for Agent Cost Optimizer."""
2
-
3
- import argparse
4
- import json
5
- import sys
6
- from pathlib import Path
7
-
8
- from aco.optimizer import AgentCostOptimizer
9
  from aco.config import ACOConfig
10
- from aco.benchmarks.benchmark_suite import BenchmarkSuite
11
-
12
 
13
  def main():
14
- parser = argparse.ArgumentParser(description="Agent Cost Optimizer")
15
- subparsers = parser.add_subparsers(dest="command", help="Command to run")
16
-
17
- # Optimize command
18
- opt_parser = subparsers.add_parser("optimize", help="Optimize an agent request")
19
- opt_parser.add_argument("--config", "-c", default="config.yaml", help="Config file path")
20
- opt_parser.add_argument("--request", "-r", required=True, help="User request text")
21
- opt_parser.add_argument("--output", "-o", default="-", help="Output file (default: stdout)")
22
-
23
- # Benchmark command
24
- bench_parser = subparsers.add_parser("benchmark", help="Run benchmark suite")
25
- bench_parser.add_argument("--config", "-c", default="config.yaml", help="Config file path")
26
- bench_parser.add_argument("--tasks", "-n", type=int, default=1000, help="Number of tasks")
27
- bench_parser.add_argument("--output", "-o", default="benchmark_results.json", help="Output path")
28
- bench_parser.add_argument("--ablations", action="store_true", help="Run ablation study")
29
-
30
- # Report command
31
- report_parser = subparsers.add_parser("report", help="Generate report from benchmark results")
32
- report_parser.add_argument("--input", "-i", required=True, help="Benchmark results JSON")
33
- report_parser.add_argument("--output", "-o", default="-", help="Output file")
34
-
 
 
 
 
 
 
 
 
35
  args = parser.parse_args()
36
-
37
- if args.command == "optimize":
38
- _cmd_optimize(args)
39
- elif args.command == "benchmark":
40
- _cmd_benchmark(args)
41
- elif args.command == "report":
42
- _cmd_report(args)
43
- else:
44
  parser.print_help()
45
- sys.exit(1)
 
 
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
- def _cmd_optimize(args):
49
- config = ACOConfig.from_yaml(args.config) if Path(args.config).exists() else ACOConfig()
50
- optimizer = AgentCostOptimizer(config)
51
- result = optimizer.optimize(args.request)
52
-
53
- output = {
54
- "trace_id": result.trace_id,
55
- "model": result.routing_decision.model_id,
56
- "tier": result.routing_decision.tier,
57
- "estimated_cost": result.estimated_cost,
58
- "estimated_latency_ms": result.estimated_latency_ms,
59
- "confidence": result.confidence,
60
- "reasoning": result.reasoning,
61
- "tool_decisions": [
62
- {"tool": d.tool_name, "decision": d.decision.value, "cost": d.estimated_cost}
63
- for d in result.tool_decisions
64
- ],
65
- "verifier": result.verifier_decision.decision.value if result.verifier_decision else None,
66
- "doom_score": result.doom_assessment.confidence if result.doom_assessment else None,
67
- "meta_tool_match": result.meta_tool_match is not None,
68
- }
69
-
70
- json_str = json.dumps(output, indent=2)
71
- if args.output == "-":
72
- print(json_str)
73
- else:
74
- with open(args.output, "w") as f:
75
- f.write(json_str)
76
 
 
 
 
 
 
 
 
 
 
77
 
78
- def _cmd_benchmark(args):
79
- config = ACOConfig.from_yaml(args.config) if Path(args.config).exists() else ACOConfig()
80
- suite = BenchmarkSuite(config)
81
-
82
- print(f"Generating {args.tasks} synthetic traces...")
83
- traces = suite.generate_benchmark_data(args.tasks)
84
-
85
- print("Running baselines...")
86
- results = suite.run_all_baselines(traces)
87
-
88
- if args.ablations:
89
- print("Running ablations...")
90
- ablation_results = suite.run_ablations(traces)
91
- results.update(ablation_results)
92
-
93
- suite.export(results, args.output)
94
-
95
- # Print report
96
- report = suite.report(results)
97
- print(report)
98
-
99
- print(f"\nResults saved to {args.output}")
100
 
 
 
 
 
 
 
 
 
101
 
102
- def _cmd_report(args):
103
- with open(args.input, "r") as f:
104
- data = json.load(f)
105
-
106
- # Reconstruct BenchmarkResults for reporting
107
- from aco.benchmarks.benchmark_suite import BenchmarkResult
108
- results = {}
109
- for name, d in data.items():
110
- results[name] = BenchmarkResult(**d)
111
-
112
- suite = BenchmarkSuite()
113
- report = suite.report(results)
114
-
115
- if args.output == "-":
116
- print(report)
117
- else:
118
- with open(args.output, "w") as f:
119
- f.write(report)
120
 
 
 
121
 
122
  if __name__ == "__main__":
123
  main()
 
1
+ """ACO CLI: Command-line interface for the Agent Cost Optimizer."""
2
+ import argparse, json, sys
3
+ sys.path.insert(0, "/app")
4
+ from aco.optimizer import ACOOptimizer
 
 
 
 
5
  from aco.config import ACOConfig
6
+ from aco.trace_schema import AgentTrace
 
7
 
8
  def main():
9
+ parser = argparse.ArgumentParser(description="ACO: Agent Cost Optimizer")
10
+ sub = parser.add_subparsers(dest="command")
11
+ # Route
12
+ rp = sub.add_parser("route", help="Route a request to the optimal model")
13
+ rp.add_argument("request", help="The request text")
14
+ rp.add_argument("--task-type", default=None, help="Override task type")
15
+ rp.add_argument("--difficulty", type=int, default=None, help="Override difficulty")
16
+ # Budget
17
+ bp = sub.add_parser("budget", help="Compute context budget for a task")
18
+ bp.add_argument("request", help="The request text")
19
+ # Gate
20
+ gp = sub.add_parser("gate", help="Check if a tool call is worth it")
21
+ gp.add_argument("tool", help="Tool name")
22
+ gp.add_argument("--task-type", default="coding")
23
+ # Verify
24
+ vp = sub.add_parser("verify", help="Check if verification is needed")
25
+ vp.add_argument("--risk", default="medium", choices=["low","medium","high","critical"])
26
+ vp.add_argument("--confidence", type=float, default=0.8)
27
+ # Doom
28
+ dp = sub.add_parser("doom", help="Assess if a run is doomed")
29
+ dp.add_argument("--cost", type=float, default=0.0)
30
+ # Stats
31
+ sp = sub.add_parser("stats", help="Show optimizer statistics")
32
+ # Eval
33
+ ep = sub.add_parser("eval", help="Run benchmark evaluation")
34
+ ep.add_argument("--n", type=int, default=2000, help="Number of traces")
35
+ # Version
36
+ sub.add_parser("version", help="Show version")
37
+
38
  args = parser.parse_args()
39
+ if args.command is None:
 
 
 
 
 
 
 
40
  parser.print_help()
41
+ return
42
+
43
+ opt = ACOOptimizer()
44
 
45
+ if args.command == "route":
46
+ prediction = opt.classifier.classify(args.request)
47
+ tt = args.task_type or prediction["task_type"]
48
+ diff = args.difficulty or prediction["difficulty"]
49
+ routing = opt.router.route(args.request, tt, diff, prediction)
50
+ print(json.dumps({
51
+ "request": args.request[:80],
52
+ "task_type": tt,
53
+ "difficulty": diff,
54
+ "model_id": routing.model_id,
55
+ "tier": routing.tier,
56
+ "confidence": round(routing.confidence, 3),
57
+ "cost_estimate": routing.cost_estimate,
58
+ "escalated": routing.escalated,
59
+ "downgraded": routing.downgraded,
60
+ "reasoning": routing.reasoning,
61
+ }, indent=2))
62
 
63
+ elif args.command == "budget":
64
+ prediction = opt.classifier.classify(args.request)
65
+ budget = opt.context_budgeter.budget(
66
+ prediction["task_type"], prediction["difficulty"],
67
+ prediction["needs_retrieval"], prediction["needs_tools"])
68
+ print(json.dumps({
69
+ "total_tokens": budget.total_tokens,
70
+ "keep_exact": budget.keep_exact,
71
+ "summarize": budget.summarize,
72
+ "omit": budget.omit,
73
+ "retrieve_on_demand": budget.retrieve_on_demand,
74
+ "cache_prefix": budget.cache_prefix,
75
+ }, indent=2))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
+ elif args.command == "gate":
78
+ decision = opt.tool_gate.gate(args.tool, {}, args.task_type, 1, 5, 0.5)
79
+ print(json.dumps({
80
+ "tool": args.tool,
81
+ "action": decision.action,
82
+ "confidence": decision.confidence,
83
+ "reasoning": decision.reasoning,
84
+ "estimated_cost": decision.estimated_cost,
85
+ }, indent=2))
86
 
87
+ elif args.command == "verify":
88
+ decision = opt.verifier_budgeter.should_verify(
89
+ "coding", args.risk, args.confidence)
90
+ print(json.dumps({
91
+ "should_verify": decision.should_verify,
92
+ "verifier_type": decision.verifier_type,
93
+ "reasoning": decision.reasoning,
94
+ "estimated_cost": decision.estimated_cost,
95
+ }, indent=2))
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ elif args.command == "doom":
98
+ assessment = opt.check_doom(args.cost)
99
+ print(json.dumps({
100
+ "doomed": assessment.doomed,
101
+ "severity": assessment.severity,
102
+ "action": assessment.recommended_action,
103
+ "reasoning": assessment.reasoning,
104
+ }, indent=2))
105
 
106
+ elif args.command == "stats":
107
+ print(json.dumps(opt.get_stats(), indent=2))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ elif args.command == "version":
110
+ print("ACO v8.0 - Agent Cost Optimizer")
111
 
112
  if __name__ == "__main__":
113
  main()