agentloop-profiler 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of agentloop-profiler might be problematic. Click here for more details.

Files changed (50) hide show
  1. agentloop/__init__.py +68 -0
  2. agentloop/audit.py +34 -0
  3. agentloop/autoinstrument.py +102 -0
  4. agentloop/ci.py +135 -0
  5. agentloop/cli.py +876 -0
  6. agentloop/client.py +170 -0
  7. agentloop/config.py +50 -0
  8. agentloop/costs.py +15 -0
  9. agentloop/decorators.py +160 -0
  10. agentloop/demo.py +283 -0
  11. agentloop/doctor.py +344 -0
  12. agentloop/events.py +49 -0
  13. agentloop/exporters.py +60 -0
  14. agentloop/findings.py +215 -0
  15. agentloop/graph.py +312 -0
  16. agentloop/integrations/__init__.py +1 -0
  17. agentloop/integrations/crewai.py +144 -0
  18. agentloop/integrations/langgraph.py +140 -0
  19. agentloop/integrations/openai.py +369 -0
  20. agentloop/integrations/openai_agents.py +212 -0
  21. agentloop/integrations/sdk.py +82 -0
  22. agentloop/integrations/vercel_ai.py +83 -0
  23. agentloop/issues.py +88 -0
  24. agentloop/markdown.py +102 -0
  25. agentloop/metrics.py +123 -0
  26. agentloop/optimizer.py +323 -0
  27. agentloop/otel.py +302 -0
  28. agentloop/otel_ids.py +81 -0
  29. agentloop/patches.py +583 -0
  30. agentloop/plan_export.py +72 -0
  31. agentloop/quality.py +222 -0
  32. agentloop/replay.py +424 -0
  33. agentloop/runtime.py +244 -0
  34. agentloop/savings.py +135 -0
  35. agentloop/server.py +292 -0
  36. agentloop/store.py +840 -0
  37. agentloop/timing.py +124 -0
  38. agentloop/tracer.py +356 -0
  39. agentloop/value.py +243 -0
  40. agentloop/version.py +3 -0
  41. agentloop_profiler-0.4.0.dist-info/METADATA +598 -0
  42. agentloop_profiler-0.4.0.dist-info/RECORD +50 -0
  43. agentloop_profiler-0.4.0.dist-info/WHEEL +5 -0
  44. agentloop_profiler-0.4.0.dist-info/entry_points.txt +2 -0
  45. agentloop_profiler-0.4.0.dist-info/licenses/LICENSE +201 -0
  46. agentloop_profiler-0.4.0.dist-info/licenses/THIRD_PARTY_LICENSES.md +54 -0
  47. agentloop_profiler-0.4.0.dist-info/top_level.txt +2 -0
  48. dashboard/__init__.py +1 -0
  49. dashboard/app.py +698 -0
  50. dashboard/value_view.py +101 -0
agentloop/value.py ADDED
@@ -0,0 +1,243 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from agentloop.optimizer import build_optimization_plan
6
+
7
+
8
+ def build_value_report(
9
+ trace: Any,
10
+ *,
11
+ runs_per_month: int = 1000,
12
+ engineer_hourly_rate_usd: float = 150.0,
13
+ incident_cost_usd: float = 500.0,
14
+ ) -> dict[str, Any]:
15
+ """Translate an optimization plan into operational value metrics.
16
+
17
+ The report connects a trace to modeled monthly cost, engineering time, latency,
18
+ and reliability impact. Its assumptions remain explicit so teams can use it for
19
+ capacity planning and optimization prioritization without treating estimates as
20
+ observed financial results.
21
+ """
22
+
23
+ if runs_per_month < 0:
24
+ raise ValueError("runs_per_month must be non-negative")
25
+ if engineer_hourly_rate_usd < 0:
26
+ raise ValueError("engineer_hourly_rate_usd must be non-negative")
27
+ if incident_cost_usd < 0:
28
+ raise ValueError("incident_cost_usd must be non-negative")
29
+
30
+ plan = build_optimization_plan(trace)
31
+ current = plan["current"]
32
+ estimated_after = plan["estimated_after"]
33
+ cards = plan.get("optimization_cards", [])
34
+
35
+ current_cost_per_run = float(current.get("estimated_cost_usd", 0.0))
36
+ optimized_cost_per_run = float(estimated_after.get("estimated_cost_usd", current_cost_per_run))
37
+ cost_savings_per_run = max(0.0, current_cost_per_run - optimized_cost_per_run)
38
+
39
+ current_runtime_ms = float(current.get("runtime_ms", 0.0))
40
+ optimized_runtime_ms = float(estimated_after.get("runtime_ms", current_runtime_ms))
41
+ latency_savings_ms_per_run = max(0.0, current_runtime_ms - optimized_runtime_ms)
42
+
43
+ retry_count = int(current.get("retry_count", 0) or 0)
44
+ reliability_risk_score = _risk_score(current=current, cards=cards)
45
+ avoided_incident_value = _avoided_incident_value(
46
+ retry_count=retry_count,
47
+ reliability_risk_score=reliability_risk_score,
48
+ incident_cost_usd=incident_cost_usd,
49
+ runs_per_month=runs_per_month,
50
+ )
51
+
52
+ engineering_hours_saved_monthly = _engineering_hours_saved(cards, runs_per_month)
53
+ engineering_value_monthly = engineering_hours_saved_monthly * engineer_hourly_rate_usd
54
+ direct_model_cost_savings_monthly = cost_savings_per_run * runs_per_month
55
+ latency_hours_saved_monthly = (latency_savings_ms_per_run * runs_per_month) / 3_600_000
56
+ total_value_monthly = (
57
+ direct_model_cost_savings_monthly + engineering_value_monthly + avoided_incident_value
58
+ )
59
+ pricing = _pricing_scenario(
60
+ monthly_value=total_value_monthly,
61
+ runs_per_month=runs_per_month,
62
+ reliability_risk_score=reliability_risk_score,
63
+ cards=cards,
64
+ )
65
+
66
+ return {
67
+ "run_id": plan.get("run_id"),
68
+ "name": plan.get("name"),
69
+ "assumptions": {
70
+ "runs_per_month": runs_per_month,
71
+ "engineer_hourly_rate_usd": engineer_hourly_rate_usd,
72
+ "incident_cost_usd": incident_cost_usd,
73
+ },
74
+ "current": current,
75
+ "estimated_after": estimated_after,
76
+ "per_run": {
77
+ "cost_savings_usd": round(cost_savings_per_run, 6),
78
+ "latency_savings_ms": round(latency_savings_ms_per_run, 3),
79
+ "latency_reduction_pct": estimated_after.get("latency_reduction_pct", 0.0),
80
+ "cost_reduction_pct": estimated_after.get("cost_reduction_pct", 0.0),
81
+ },
82
+ "monthly_value": {
83
+ "direct_model_cost_savings_usd": round(direct_model_cost_savings_monthly, 2),
84
+ "engineering_hours_saved": round(engineering_hours_saved_monthly, 2),
85
+ "engineering_value_usd": round(engineering_value_monthly, 2),
86
+ "latency_hours_saved": round(latency_hours_saved_monthly, 2),
87
+ "avoided_incident_value_usd": round(avoided_incident_value, 2),
88
+ "total_value_usd": round(total_value_monthly, 2),
89
+ },
90
+ "pricing": pricing,
91
+ "reliability": {
92
+ "risk_score": reliability_risk_score,
93
+ "retry_count": retry_count,
94
+ "high_confidence_fixes": sum(1 for card in cards if card.get("confidence") == "high"),
95
+ "top_risks": _top_risks(cards),
96
+ },
97
+ "value_summary": _value_summary(
98
+ monthly_value=total_value_monthly,
99
+ latency_savings_ms_per_run=latency_savings_ms_per_run,
100
+ cost_savings_per_run=cost_savings_per_run,
101
+ cards=cards,
102
+ pricing=pricing,
103
+ ),
104
+ "optimization_cards": cards,
105
+ }
106
+
107
+
108
+ def _risk_score(*, current: dict[str, Any], cards: list[dict[str, Any]]) -> int:
109
+ score = 0
110
+ retry_count = int(current.get("retry_count", 0) or 0)
111
+ repeated_context_ratio = float(current.get("repeated_context_ratio", 0.0) or 0.0)
112
+ input_tokens = int(current.get("input_tokens", 0) or 0)
113
+
114
+ score += min(35, retry_count * 12)
115
+ score += min(25, int(repeated_context_ratio * 100))
116
+ score += min(20, input_tokens // 5000)
117
+ score += min(20, len(cards) * 4)
118
+ return max(0, min(100, score))
119
+
120
+
121
+ def _engineering_hours_saved(cards: list[dict[str, Any]], runs_per_month: int) -> float:
122
+ if not cards or runs_per_month == 0:
123
+ return 0.0
124
+
125
+ # Conservative proxy: repeated production inefficiencies create triage and refactor
126
+ # work. Cap it to avoid turning this into a fake precision calculator.
127
+ base_hours = min(12.0, len(cards) * 1.25)
128
+ scale = min(3.0, max(0.25, runs_per_month / 1000))
129
+ high_confidence_bonus = sum(0.5 for card in cards if card.get("confidence") == "high")
130
+ return min(40.0, (base_hours + high_confidence_bonus) * scale)
131
+
132
+
133
+ def _avoided_incident_value(
134
+ *,
135
+ retry_count: int,
136
+ reliability_risk_score: int,
137
+ incident_cost_usd: float,
138
+ runs_per_month: int,
139
+ ) -> float:
140
+ if runs_per_month == 0 or incident_cost_usd == 0:
141
+ return 0.0
142
+ monthly_failure_probability = min(0.25, (retry_count * 0.01) + (reliability_risk_score / 1000))
143
+ volume_multiplier = min(2.0, max(0.25, runs_per_month / 1000))
144
+ return incident_cost_usd * monthly_failure_probability * volume_multiplier
145
+
146
+
147
+ def _pricing_scenario(
148
+ *,
149
+ monthly_value: float,
150
+ runs_per_month: int,
151
+ reliability_risk_score: int,
152
+ cards: list[dict[str, Any]],
153
+ ) -> dict[str, Any]:
154
+ """Build a conservative pricing scenario from modeled operational value.
155
+
156
+ This is not a billing system or price quote. It provides a configurable tier,
157
+ monthly amount, and value-to-price ratio for planning comparisons.
158
+ """
159
+
160
+ if runs_per_month == 0 or monthly_value <= 0 or not cards:
161
+ suggested_plan = "free"
162
+ suggested_monthly_price_usd = 0
163
+ rationale = "No meaningful optimization value was detected for this trace."
164
+ elif monthly_value < 750 and runs_per_month < 1000:
165
+ suggested_plan = "pro"
166
+ suggested_monthly_price_usd = 49
167
+ rationale = "Low-volume workload with measurable optimization value."
168
+ elif monthly_value < 5000 and reliability_risk_score < 60:
169
+ suggested_plan = "team"
170
+ suggested_monthly_price_usd = 499
171
+ rationale = "Mid-volume workload with shared tracing and optimization needs."
172
+ elif monthly_value < 25000:
173
+ suggested_plan = "growth"
174
+ suggested_monthly_price_usd = 1500
175
+ rationale = "Higher-volume workload with material reliability and latency impact."
176
+ else:
177
+ suggested_plan = "enterprise"
178
+ suggested_monthly_price_usd = 5000
179
+ rationale = (
180
+ "Large modeled value; review deployment, retention, support, and usage requirements."
181
+ )
182
+
183
+ value_to_price_ratio = None
184
+ if suggested_monthly_price_usd > 0:
185
+ value_to_price_ratio = round(monthly_value / suggested_monthly_price_usd, 2)
186
+
187
+ return {
188
+ "suggested_plan": suggested_plan,
189
+ "suggested_monthly_price_usd": suggested_monthly_price_usd,
190
+ "estimated_monthly_value_usd": round(monthly_value, 2),
191
+ "value_to_price_ratio": value_to_price_ratio,
192
+ "rationale": rationale,
193
+ "scenario_notes": _scenario_notes(suggested_plan),
194
+ }
195
+
196
+
197
+ def _scenario_notes(plan: str) -> list[str]:
198
+ if plan == "free":
199
+ return ["Local traces", "CLI reports", "Manual optimization plan export"]
200
+ if plan == "pro":
201
+ return ["Local + API trace upload", "Value reports", "Single project workspace"]
202
+ if plan == "team":
203
+ return ["Shared dashboard", "API keys", "Shared projects", "Optimization reports"]
204
+ if plan == "growth":
205
+ return [
206
+ "Higher usage limits",
207
+ "Postgres backend",
208
+ "Extended retention",
209
+ "Operational value review",
210
+ ]
211
+ return ["Private deployment", "Custom retention", "Security review", "Custom integrations"]
212
+
213
+
214
+ def _top_risks(cards: list[dict[str, Any]]) -> list[str]:
215
+ risks = []
216
+ for card in cards[:3]:
217
+ title = str(card.get("title", "Optimization opportunity"))
218
+ confidence = str(card.get("confidence", "unknown"))
219
+ risks.append(f"{title} ({confidence} confidence)")
220
+ return risks
221
+
222
+
223
+ def _value_summary(
224
+ *,
225
+ monthly_value: float,
226
+ latency_savings_ms_per_run: float,
227
+ cost_savings_per_run: float,
228
+ cards: list[dict[str, Any]],
229
+ pricing: dict[str, Any],
230
+ ) -> str:
231
+ strongest_fix = cards[0]["title"] if cards else "No major bottleneck detected"
232
+ price = pricing.get("suggested_monthly_price_usd", 0)
233
+ plan = pricing.get("suggested_plan", "free")
234
+ price_line = "free local usage" if price == 0 else f"the {plan} plan at ${price:,.0f}/month"
235
+ return (
236
+ f"AgentLoop found {len(cards)} optimization opportunities. "
237
+ f"The strongest immediate fix is: {strongest_fix}. "
238
+ f"At the provided usage assumptions, this trace represents about "
239
+ f"${monthly_value:,.0f}/month in modeled value, with "
240
+ f"{latency_savings_ms_per_run / 1000:.2f}s latency saved and "
241
+ f"${cost_savings_per_run:.4f} model cost saved per run. "
242
+ f"A modeled pricing scenario is {price_line}."
243
+ )
agentloop/version.py ADDED
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+
3
+ __version__ = "0.4.0"