Skip to content
60 linesCodeBlameRaw
1/**
2 * Effort and suggestions, as the pages say them (components/effort.tsx).
3 * Pure, so it is tested on its own. Every cost
4 * shown comes from the agents service's measured sessions; a level an
5 * agent has not run at says so instead of a number.
6 */
7import type { AgentEffort, AgentEffortCosts, AgentRecommendation, AgentRecommendations, EffortCost, EffortLevel } from "@g1t/contracts";
8
9import { money } from "./money.ts";
10
11export const EFFORT_OPTIONS: { key: AgentEffort; label: string; about: string }[] = [
12 { key: "auto", label: "Auto", about: "Picks per piece of work: medium, and high on a session someone has had to steer." },
13 { key: "low", label: "Low", about: "The fast tier, light reasoning, up to 5 steps a session. For routine work." },
14 { key: "medium", label: "Medium", about: "Starts where the work would, moderate reasoning, up to 8 steps a session." },
15 { key: "high", label: "High", about: "The standard tier or above, deep reasoning, up to 10 steps a session." },
16 { key: "max", label: "Max", about: "The most capable tier, the most reasoning, up to 12 steps a session." },
17];
18
19export function effortLabel(effort: AgentEffort | null | undefined): string {
20 return EFFORT_OPTIONS.find((o) => o.key === effort)?.label ?? "Auto";
21}
22
23/** An agent's setting from its routing; none is Auto. */
24export function effortSetting(routing: { effort?: AgentEffort } | null | undefined): AgentEffort {
25 const value = routing?.effort;
26 return EFFORT_OPTIONS.some((o) => o.key === value) ? (value as AgentEffort) : "auto";
27}
28
29/** One level's measured cost, or null when the agent has not run at it. */
30export function costAt(costs: AgentEffortCosts | null, level: EffortLevel): EffortCost | null {
31 const found = costs?.levels.find((l) => l.effort === level);
32 return found && found.sessions > 0 && found.typical_micros != null ? found : null;
33}
34
35/** What a setting has cost per typical task: "$0.42 a typical task, from 14 sessions", or why there is no figure. */
36export function costLine(costs: AgentEffortCosts | null, effort: AgentEffort): string {
37 if (!costs) return "Costs couldn't be read right now.";
38 // Auto runs as medium, and high once steered: its figure is medium's.
39 const level: EffortLevel = effort === "auto" ? "medium" : effort;
40 const at = costAt(costs, level);
41 const days = `in the last ${costs.window_days} days`;
42 if (!at) return effort === "auto" ? `No sessions at Medium ${days}, so no figure yet.` : `No sessions at ${effortLabel(effort)} ${days}, so no figure yet.`;
43 const sessions = `${at.sessions.toLocaleString("en-US")} session${at.sessions === 1 ? "" : "s"}`;
44 return `${money(at.typical_micros!, { precise: true })} a typical task${effort === "auto" ? " at Medium" : ""}, from ${sessions} ${days}`;
45}
46
47/** "92%" of sessions finished with nobody stepping in, or empty. */
48export function acceptedLabel(cost: EffortCost | null): string {
49 return cost?.accepted_share != null ? `${Math.round(cost.accepted_share * 100)}%` : "";
50}
51
52/** What the open suggestions together would save a month. */
53export function totalSaving(recs: AgentRecommendations | null): number {
54 return (recs?.open ?? []).reduce((n, r) => n + (r.saving_month_micros ?? 0), 0);
55}
56
57/** "About $31 a month" from a suggestion's measured saving. */
58export function savingLabel(rec: Pick<AgentRecommendation, "saving_month_micros">): string {
59 return rec.saving_month_micros != null && rec.saving_month_micros > 0 ? `About ${money(rec.saving_month_micros)} a month` : "";
60}