agentwrangler 0.1.0 → 0.1.1-next.2f6c1df
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.
- package/README.md +82 -94
- package/dist/apply/jobs.js +6 -2
- package/dist/daemon/index.js +9 -3
- package/dist/daemon/readiness.js +26 -1
- package/dist/daemon/router.js +4 -2
- package/dist/db/migrations/016_ingest_offset_file_version.sql +8 -0
- package/dist/db/migrations/017_ingest_metric_events.sql +22 -0
- package/dist/detector/detectors/d10_catalog_footprint.js +2 -2
- package/dist/detector/detectors/d1_ctx_always_loaded.js +9 -9
- package/dist/detector/detectors/d2_session_long_full_context.js +2 -2
- package/dist/detector/detectors/d4_model_mismatch.js +3 -3
- package/dist/detector/detectors/d6_tool_result_bloat.js +1 -1
- package/dist/detector/detectors/d7_loop_retry_waste.js +1 -1
- package/dist/detector/detectors/d8_cache_write_churn.js +2 -2
- package/dist/detector/detectors/d9_idle_background_session.js +1 -1
- package/dist/detector/measurement.js +3 -2
- package/dist/hook/precompact-checkpoint-hook.mjs +74 -25
- package/dist/ingest/ingestor.js +151 -62
- package/dist/ingest/pricing.js +15 -0
- package/dist/ingest/tail.js +55 -11
- package/dist/query/api/cost-per-success.js +13 -1
- package/dist/query/api/delivery.js +25 -3
- package/dist/query/api/effectiveness.js +30 -5
- package/dist/query/api/efficiency-headroom.js +12 -14
- package/dist/query/api/outcomes.js +2 -1
- package/dist/query/api/overview.js +90 -6
- package/dist/query/settings-store.js +2 -0
- package/dist/query/spend.js +64 -2
- package/dist/ui/assets/BarChart-BC-ciS9d.js +3 -0
- package/dist/ui/assets/BriefsPage-Dls6npt7.js +2 -0
- package/dist/ui/assets/CacheWriteSpikesChart-ncVwVoud.js +1 -0
- package/dist/ui/assets/CartesianChart-CRV6h2et.js +84 -0
- package/dist/ui/assets/Chip-EizRm13x.js +1 -0
- package/dist/ui/assets/ComposedChart-CrOxp6Ym.js +1 -0
- package/dist/ui/assets/EmptyState-9kcoimjj.js +1 -0
- package/dist/ui/assets/FlavorDecomposition-DRZxH0vQ.js +1 -0
- package/dist/ui/assets/FrictionCell-BGYB9UKh.js +2 -0
- package/dist/ui/assets/GlossaryPage-CRyQb1Hn.js +1 -0
- package/dist/ui/assets/HotSessionsPage-DfE90Kxi.js +1 -0
- package/dist/ui/assets/InfoTip-CmcYFNQt.js +1 -0
- package/dist/ui/assets/Legend-BCXsSaEM.js +5 -0
- package/dist/ui/assets/Line-2rUzs15v.js +1 -0
- package/dist/ui/assets/OverviewPage-Bm5KvXqa.js +2 -0
- package/dist/ui/assets/RecommendationsPage-CvSl3lzp.js +2 -0
- package/dist/ui/assets/Scatter-DpIZt_y5.js +1 -0
- package/dist/ui/assets/SessionDetailPage-w_lSgite.js +1 -0
- package/dist/ui/assets/SettingsPage-CfUoP8lB.js +25 -0
- package/dist/ui/assets/Skeleton-DjuxPm_D.js +1 -0
- package/dist/ui/assets/SpendPercentileChip-DYun7Wzh.js +1 -0
- package/dist/ui/assets/TrendChart-gyhHK9H_.js +1 -0
- package/dist/ui/assets/WorkspaceDetailPage-DacPKaKA.js +1 -0
- package/dist/ui/assets/WorkspacesPage-DiNQaAYG.js +1 -0
- package/dist/ui/assets/chart-theme-DnpNuyRt.js +1 -0
- package/dist/ui/assets/graphicalItemSelectors-CFhpQjLz.js +1 -0
- package/dist/ui/assets/index-D_IJsvkJ.css +1 -0
- package/dist/ui/assets/index-hbaLYHUX.js +41 -0
- package/dist/ui/assets/prompt-templates-CVzMex9L.js +13 -0
- package/dist/ui/assets/rec-sessions-ggz9MYgP.js +1 -0
- package/dist/ui/assets/useExperimentalActions-B7J8gIkb.js +1 -0
- package/dist/ui/assets/workspace-label-CysPJNc0.js +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +21 -5
- package/dist/ui/assets/index-DnRKgc21.css +0 -1
- package/dist/ui/assets/index-h1Q1wWq5.js +0 -168
|
@@ -44,8 +44,20 @@ export function getDeliveryMetrics(db, opts) {
|
|
|
44
44
|
FROM tool_events te
|
|
45
45
|
WHERE te.session_id = iws.session_id
|
|
46
46
|
AND te.commit_sha IS NOT NULL
|
|
47
|
-
) AS is_abandoned_session
|
|
47
|
+
) AND s.state = 'RECONCILED' AS is_abandoned_session,
|
|
48
|
+
s.state = 'LIVE'
|
|
49
|
+
AND EXISTS (
|
|
50
|
+
SELECT 1 FROM tool_events te
|
|
51
|
+
WHERE te.session_id = iws.session_id
|
|
52
|
+
AND te.tool_name IN ('Bash', 'Edit', 'Write', 'NotebookEdit')
|
|
53
|
+
)
|
|
54
|
+
AND NOT EXISTS (
|
|
55
|
+
SELECT 1 FROM tool_events te
|
|
56
|
+
WHERE te.session_id = iws.session_id
|
|
57
|
+
AND te.commit_sha IS NOT NULL
|
|
58
|
+
) AS is_live_session
|
|
48
59
|
FROM in_window_sessions iws
|
|
60
|
+
JOIN sessions s USING (session_id)
|
|
49
61
|
),
|
|
50
62
|
session_spend AS (
|
|
51
63
|
SELECT session_id,
|
|
@@ -67,7 +79,16 @@ export function getDeliveryMetrics(db, opts) {
|
|
|
67
79
|
CASE WHEN COALESCE(SUM(ss.spend_u), 0) = 0 THEN NULL
|
|
68
80
|
ELSE SUM(CASE WHEN sf.is_abandoned_session THEN ss.spend_u ELSE 0 END) * 1.0
|
|
69
81
|
/ SUM(ss.spend_u)
|
|
70
|
-
END AS abandoned_spend_share
|
|
82
|
+
END AS abandoned_spend_share,
|
|
83
|
+
COALESCE(SUM(sf.is_abandoned_session), 0) AS no_commit_activity_session_count,
|
|
84
|
+
COALESCE(SUM(CASE WHEN sf.is_abandoned_session THEN ss.spend_u ELSE 0 END), 0)
|
|
85
|
+
AS no_commit_activity_spend_u,
|
|
86
|
+
CASE WHEN COALESCE(SUM(ss.spend_u), 0) = 0 THEN NULL
|
|
87
|
+
ELSE SUM(CASE WHEN sf.is_abandoned_session THEN ss.spend_u ELSE 0 END) * 1.0
|
|
88
|
+
/ SUM(ss.spend_u)
|
|
89
|
+
END AS no_commit_activity_spend_share,
|
|
90
|
+
COALESCE(SUM(CASE WHEN sf.is_live_session THEN 1 ELSE 0 END), 0)
|
|
91
|
+
AS live_session_excluded_from_no_commit_activity_count
|
|
71
92
|
FROM session_flags sf
|
|
72
93
|
JOIN session_spend ss USING (session_id)`)
|
|
73
94
|
.get(...params);
|
|
@@ -79,13 +100,14 @@ export function getDeliveryMetrics(db, opts) {
|
|
|
79
100
|
};
|
|
80
101
|
return buildResponse(data, {
|
|
81
102
|
claim_kind: "OBS_PROXY",
|
|
103
|
+
metric_definition_version: "esf-1",
|
|
82
104
|
n: data.commit_session_count,
|
|
83
105
|
window: { from: opts.from, to: opts.to },
|
|
84
106
|
qualification: {
|
|
85
107
|
provisional_excluded: true,
|
|
86
108
|
unpriced_turns: 0,
|
|
87
109
|
claim_kinds_count: 1,
|
|
88
|
-
note: "Commit SHA presence is an observed delivery proxy.",
|
|
110
|
+
note: "Commit SHA presence is an observed delivery proxy. No-commit activity means RECONCILED Bash/Edit/Write/NotebookEdit activity without an observed commit; LIVE sessions remain in total spend but are excluded from that activity cohort. Legacy abandoned_* fields are compatibility aliases, not an abandonment finding.",
|
|
89
111
|
},
|
|
90
112
|
...(opts.workspaceId === null ? {} : { drilldown_ids: { workspace_id: opts.workspaceId } }),
|
|
91
113
|
});
|
|
@@ -34,11 +34,17 @@ export function computeSessionDelivery(db, sessionId) {
|
|
|
34
34
|
turns_to_first_commit = countRow.n;
|
|
35
35
|
}
|
|
36
36
|
const sessRow = db
|
|
37
|
-
.prepare(
|
|
37
|
+
.prepare(`SELECT user_turn_count, state,
|
|
38
|
+
EXISTS (SELECT 1 FROM tool_events te WHERE te.session_id = sessions.session_id
|
|
39
|
+
AND te.tool_name IN ('Bash','Write','Edit','NotebookEdit')) AS has_activity
|
|
40
|
+
FROM sessions WHERE session_id = ?`)
|
|
38
41
|
.get(sessionId);
|
|
39
42
|
const user_turn_count = sessRow?.user_turn_count ?? 0;
|
|
40
43
|
const state = sessRow?.state ?? "";
|
|
41
|
-
const deep_abandoned = user_turn_count >= 10 &&
|
|
44
|
+
const deep_abandoned = user_turn_count >= 10 &&
|
|
45
|
+
firstCommitTs === null &&
|
|
46
|
+
state === "RECONCILED" &&
|
|
47
|
+
sessRow?.has_activity === 1;
|
|
42
48
|
return { turns_to_first_commit, deep_abandoned };
|
|
43
49
|
}
|
|
44
50
|
// ---------------------------------------------------------------------------
|
|
@@ -83,8 +89,9 @@ export function getAbandonedSpendSplit(db, opts) {
|
|
|
83
89
|
FROM tool_events te
|
|
84
90
|
WHERE te.session_id = iws.session_id
|
|
85
91
|
AND te.commit_sha IS NOT NULL
|
|
86
|
-
) AS is_abandoned_session
|
|
92
|
+
) AND s.state = 'RECONCILED' AS is_abandoned_session
|
|
87
93
|
FROM in_window_sessions iws
|
|
94
|
+
JOIN sessions s USING (session_id)
|
|
88
95
|
),
|
|
89
96
|
session_spend AS (
|
|
90
97
|
SELECT session_id,
|
|
@@ -145,15 +152,24 @@ export function getClosureProxy(db, opts) {
|
|
|
145
152
|
unresolved_count: 0,
|
|
146
153
|
pending_count: 0,
|
|
147
154
|
resolved_share: null,
|
|
155
|
+
no_later_workspace_session_count: 0,
|
|
156
|
+
later_workspace_session_count: 0,
|
|
157
|
+
no_later_workspace_session_share: null,
|
|
148
158
|
window_hours: windowHours,
|
|
149
159
|
workspace_id: opts.workspaceId,
|
|
150
160
|
});
|
|
151
161
|
if (candidates.length === 0) {
|
|
152
162
|
return buildResponse(emptyProxy(), {
|
|
153
163
|
claim_kind: "EXPERIMENTAL",
|
|
164
|
+
metric_definition_version: "esf-1",
|
|
154
165
|
n: 0,
|
|
155
166
|
window: { from: opts.now, to: opts.now },
|
|
156
|
-
qualification: {
|
|
167
|
+
qualification: {
|
|
168
|
+
provisional_excluded: false,
|
|
169
|
+
unpriced_turns: 0,
|
|
170
|
+
claim_kinds_count: 1,
|
|
171
|
+
note: `${note} No later workspace session is an observation, not task resolution.`,
|
|
172
|
+
},
|
|
157
173
|
...(opts.workspaceId === null ? {} : { drilldown_ids: { workspace_id: opts.workspaceId } }),
|
|
158
174
|
});
|
|
159
175
|
}
|
|
@@ -204,14 +220,23 @@ export function getClosureProxy(db, opts) {
|
|
|
204
220
|
unresolved_count,
|
|
205
221
|
pending_count,
|
|
206
222
|
resolved_share,
|
|
223
|
+
no_later_workspace_session_count: resolved_count,
|
|
224
|
+
later_workspace_session_count: unresolved_count,
|
|
225
|
+
no_later_workspace_session_share: resolved_share,
|
|
207
226
|
window_hours: windowHours,
|
|
208
227
|
workspace_id: opts.workspaceId,
|
|
209
228
|
};
|
|
210
229
|
return buildResponse(proxy, {
|
|
211
230
|
claim_kind: "EXPERIMENTAL",
|
|
231
|
+
metric_definition_version: "esf-1",
|
|
212
232
|
n: no_commit_session_count,
|
|
213
233
|
window: { from: opts.now, to: opts.now },
|
|
214
|
-
qualification: {
|
|
234
|
+
qualification: {
|
|
235
|
+
provisional_excluded: false,
|
|
236
|
+
unpriced_turns: 0,
|
|
237
|
+
claim_kinds_count: 1,
|
|
238
|
+
note: `${note} "Resolved" and "unresolved" are legacy aliases for no later workspace session and a later workspace session; neither establishes task resolution.`,
|
|
239
|
+
},
|
|
215
240
|
...(opts.workspaceId === null ? {} : { drilldown_ids: { workspace_id: opts.workspaceId } }),
|
|
216
241
|
});
|
|
217
242
|
}
|
|
@@ -37,22 +37,19 @@ export function getEfficiencyHeadroom(db, opts) {
|
|
|
37
37
|
FROM turns
|
|
38
38
|
WHERE ts >= ? AND ts < ? AND provisional = 0`)
|
|
39
39
|
.get(from, to);
|
|
40
|
+
const opportunities = db
|
|
41
|
+
.prepare(`SELECT rec_id, modeled_savings_u_per_wk
|
|
42
|
+
FROM recommendations
|
|
43
|
+
WHERE state IN ('PROPOSED', 'ADOPTED') AND modeled_savings_u_per_wk IS NOT NULL
|
|
44
|
+
ORDER BY rec_id`)
|
|
45
|
+
.all();
|
|
40
46
|
const headroom_u_per_wk = recs.sum_u ?? 0;
|
|
41
47
|
const actual_u_per_wk = spend.actual_u;
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
let headroom_pct;
|
|
46
|
-
if (actual_u_per_wk === 0) {
|
|
47
|
-
headroom_pct = null;
|
|
48
|
-
}
|
|
49
|
-
else if (openRecsExist && recs.with_savings === 0) {
|
|
50
|
-
headroom_pct = null;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
headroom_pct = headroom_u_per_wk / actual_u_per_wk;
|
|
54
|
-
}
|
|
48
|
+
// Individual recommendation models overlap and their weekly horizon differs from
|
|
49
|
+
// the trailing spend window, so a combined percentage would be misleading.
|
|
50
|
+
const headroom_pct = null;
|
|
55
51
|
const data = {
|
|
52
|
+
opportunities,
|
|
56
53
|
headroom_u_per_wk,
|
|
57
54
|
actual_u_per_wk,
|
|
58
55
|
headroom_pct,
|
|
@@ -62,13 +59,14 @@ export function getEfficiencyHeadroom(db, opts) {
|
|
|
62
59
|
};
|
|
63
60
|
return buildResponse(data, {
|
|
64
61
|
claim_kind: "EXPERIMENTAL",
|
|
62
|
+
metric_definition_version: "esf-1",
|
|
65
63
|
n: recs.with_savings,
|
|
66
64
|
window: { from, to },
|
|
67
65
|
qualification: {
|
|
68
66
|
provisional_excluded: true,
|
|
69
67
|
unpriced_turns: 0,
|
|
70
68
|
claim_kinds_count: 1,
|
|
71
|
-
note: "
|
|
69
|
+
note: "Individual modeled weekly opportunities are not summed: recommendations can overlap and their weekly horizon differs from the trailing spend window.",
|
|
72
70
|
},
|
|
73
71
|
});
|
|
74
72
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* SQL references: Data Model v2 §2 lines 261-275 / 303-314 / 329-334.
|
|
13
13
|
*/
|
|
14
|
+
import { PREMIUM_MODEL_SQL } from "../../ingest/pricing.js";
|
|
14
15
|
import { getQueryDb } from "../db-context.js";
|
|
15
16
|
import { buildResponse } from "../envelope.js";
|
|
16
17
|
// ---------------------------------------------------------------------------
|
|
@@ -136,7 +137,7 @@ export function listWorkspaceOutcomes() {
|
|
|
136
137
|
const lrByWs = new Map(lrRows.map((r) => [r.workspace_id, r.linkage_rate]));
|
|
137
138
|
const adherenceRows = db
|
|
138
139
|
.prepare(`SELECT workspace_id, COUNT(*) AS n,
|
|
139
|
-
AVG(CASE WHEN
|
|
140
|
+
AVG(CASE WHEN ${PREMIUM_MODEL_SQL} THEN 1.0 ELSE 0.0 END) AS premium_share
|
|
140
141
|
FROM turns
|
|
141
142
|
WHERE is_sidechain = 0 AND provisional = 0
|
|
142
143
|
GROUP BY workspace_id`)
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* windows/cutoffs, maps rows to the frozen DTOs, and attaches the envelope.
|
|
11
11
|
*/
|
|
12
12
|
import { loadConfig } from "../../daemon/config.js";
|
|
13
|
+
import { PREMIUM_MODEL_SQL, modelInputListPrice } from "../../ingest/pricing.js";
|
|
13
14
|
import { getQueryDb } from "../db-context.js";
|
|
14
15
|
import { forecastFromDb } from "../forecast.js";
|
|
15
16
|
import { contextPerTurnByModel, globalSpend, hasStaleClaim, liveSessionCount, liveSessions, spendByWorkspace, } from "../spend.js";
|
|
@@ -108,7 +109,7 @@ function makeResponse(data, o) {
|
|
|
108
109
|
note: "",
|
|
109
110
|
...o.qualification,
|
|
110
111
|
},
|
|
111
|
-
metric_definition_version: "observe-1",
|
|
112
|
+
metric_definition_version: o.metric_definition_version ?? "observe-1",
|
|
112
113
|
claim_kind: o.claim_kind,
|
|
113
114
|
drilldown_ids: o.drilldown_ids ?? {},
|
|
114
115
|
},
|
|
@@ -167,14 +168,20 @@ export function getGlobalOverview(filters) {
|
|
|
167
168
|
// counts sum to `turns_total`, NOT the reconciled `turns`. This is the
|
|
168
169
|
// deliberate spend-vs-context difference (Data Model §2/§3) — a consumer must
|
|
169
170
|
// not expect model_mix turns to reconcile with the reconciled `turns` figure.
|
|
170
|
-
|
|
171
|
+
// Display order: most-expensive tier first (then turns, then name) — the
|
|
172
|
+
// premium models matter most per turn, and a price-stable order keeps the
|
|
173
|
+
// index-keyed card colors from shuffling as usage volume shifts.
|
|
174
|
+
const ctxSorted = [...ctx].sort((a, b) => modelInputListPrice(b.model) - modelInputListPrice(a.model) ||
|
|
175
|
+
b.n - a.n ||
|
|
176
|
+
a.model.localeCompare(b.model));
|
|
177
|
+
const context_per_turn = ctxSorted.map((r) => ({
|
|
171
178
|
model: r.model,
|
|
172
179
|
n: r.n,
|
|
173
180
|
avg_context_per_turn: r.avg_context_per_turn,
|
|
174
181
|
avg_output_per_turn: r.avg_output_per_turn,
|
|
175
182
|
usd_per_turn: r.usd_per_turn,
|
|
176
183
|
}));
|
|
177
|
-
const model_mix =
|
|
184
|
+
const model_mix = ctxSorted.map((r) => ({ model: r.model, turns: r.n }));
|
|
178
185
|
const data = {
|
|
179
186
|
cost_equiv_u: g.cost_equiv_u,
|
|
180
187
|
turns: g.turns,
|
|
@@ -224,7 +231,9 @@ export function listWorkspaces(filters) {
|
|
|
224
231
|
+ cache_write_5m + cache_write_1h + cache_write_other)
|
|
225
232
|
ELSE NULL END AS cache_write_pct,
|
|
226
233
|
CAST(SUM(CASE WHEN model LIKE '%opus%' THEN 1 ELSE 0 END) AS REAL)
|
|
227
|
-
/ NULLIF(COUNT(*), 0) AS opus_pct
|
|
234
|
+
/ NULLIF(COUNT(*), 0) AS opus_pct,
|
|
235
|
+
CAST(SUM(CASE WHEN ${PREMIUM_MODEL_SQL} THEN 1 ELSE 0 END) AS REAL)
|
|
236
|
+
/ NULLIF(COUNT(*), 0) AS premium_pct
|
|
228
237
|
FROM turns WHERE ts >= ? AND ts < ?
|
|
229
238
|
GROUP BY workspace_id`)
|
|
230
239
|
.all(from, to));
|
|
@@ -245,6 +254,7 @@ export function listWorkspaces(filters) {
|
|
|
245
254
|
avg_context_per_turn: agg?.avg_context_per_turn ?? null,
|
|
246
255
|
cache_write_pct: agg?.cache_write_pct ?? null,
|
|
247
256
|
opus_pct: agg?.opus_pct ?? null,
|
|
257
|
+
premium_pct: agg?.premium_pct ?? null,
|
|
248
258
|
};
|
|
249
259
|
});
|
|
250
260
|
return makeResponse({ items, next_cursor: null }, {
|
|
@@ -342,7 +352,30 @@ export function listSessions(workspace_id, filters, cursor) {
|
|
|
342
352
|
(SELECT COUNT(*) FROM tool_events te
|
|
343
353
|
WHERE te.session_id = s.session_id AND te.exit_class = 'ERROR') AS tool_error_count,
|
|
344
354
|
(SELECT COUNT(*) FROM tool_events te
|
|
345
|
-
WHERE te.session_id = s.session_id AND te.
|
|
355
|
+
WHERE te.session_id = s.session_id AND te.result_bytes IS NOT NULL) AS tool_completed_count,
|
|
356
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
357
|
+
WHERE te.session_id = s.session_id AND te.exit_class = 'ERROR'
|
|
358
|
+
AND te.result_bytes IS NOT NULL) AS tool_completed_error_count,
|
|
359
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
360
|
+
WHERE te.session_id = s.session_id AND te.exit_class = 'TEST_FAIL'
|
|
361
|
+
AND EXISTS (SELECT 1 FROM tool_event_metadata metadata
|
|
362
|
+
WHERE metadata.event_id = te.event_id AND metadata.is_test_command = 1)) AS test_fail_count,
|
|
363
|
+
(SELECT COUNT(*) FROM tool_events te JOIN tool_event_metadata metadata ON metadata.event_id = te.event_id
|
|
364
|
+
WHERE te.session_id = s.session_id AND metadata.is_test_command = 1 AND te.result_bytes IS NOT NULL) AS test_completed_count,
|
|
365
|
+
(SELECT COUNT(*) FROM tool_events te JOIN tool_event_metadata metadata ON metadata.event_id = te.event_id
|
|
366
|
+
WHERE te.session_id = s.session_id AND metadata.is_test_command = 1 AND te.exit_class = 'OK' AND te.result_bytes IS NOT NULL) AS test_pass_count,
|
|
367
|
+
CASE WHEN NOT EXISTS (SELECT 1 FROM tool_events observed JOIN tool_event_metadata observed_metadata ON observed_metadata.event_id = observed.event_id
|
|
368
|
+
WHERE observed.session_id = s.session_id AND observed_metadata.is_test_command = 1 AND observed.result_bytes IS NOT NULL)
|
|
369
|
+
THEN 'NO_TEST_OUTCOMES'
|
|
370
|
+
WHEN NOT EXISTS (SELECT 1 FROM tool_events failed JOIN tool_event_metadata failed_metadata ON failed_metadata.event_id = failed.event_id
|
|
371
|
+
WHERE failed.session_id = s.session_id AND failed_metadata.is_test_command = 1 AND failed.exit_class = 'TEST_FAIL' AND failed.result_bytes IS NOT NULL)
|
|
372
|
+
THEN 'NO_FAILURES_OBSERVED'
|
|
373
|
+
WHEN EXISTS (SELECT 1 FROM tool_events passed JOIN tool_event_metadata passed_metadata ON passed_metadata.event_id = passed.event_id
|
|
374
|
+
WHERE passed.session_id = s.session_id AND passed_metadata.is_test_command = 1 AND passed.exit_class = 'OK' AND passed.result_bytes IS NOT NULL
|
|
375
|
+
AND EXISTS (SELECT 1 FROM tool_events failed_before JOIN tool_event_metadata failed_before_metadata ON failed_before_metadata.event_id = failed_before.event_id
|
|
376
|
+
WHERE failed_before.session_id = s.session_id AND failed_before_metadata.is_test_command = 1
|
|
377
|
+
AND failed_before.exit_class = 'TEST_FAIL' AND failed_before.result_bytes IS NOT NULL AND failed_before.ts < passed.ts))
|
|
378
|
+
THEN 'FAILED_THEN_PASSED' ELSE 'FAILURES_OBSERVED' END AS test_outcome,
|
|
346
379
|
s.gap_median_s, s.gap_p90_s, s.long_gap_count, s.gap_n,
|
|
347
380
|
CASE WHEN EXISTS (
|
|
348
381
|
SELECT 1 FROM tool_events te
|
|
@@ -357,6 +390,11 @@ export function listSessions(workspace_id, filters, cursor) {
|
|
|
357
390
|
)
|
|
358
391
|
) ELSE NULL END AS turns_to_first_commit,
|
|
359
392
|
CASE WHEN s.state = 'RECONCILED' AND s.user_turn_count >= 10
|
|
393
|
+
AND EXISTS (
|
|
394
|
+
SELECT 1 FROM tool_events te
|
|
395
|
+
WHERE te.session_id = s.session_id
|
|
396
|
+
AND te.tool_name IN ('Bash', 'Write', 'Edit', 'NotebookEdit')
|
|
397
|
+
)
|
|
360
398
|
AND NOT EXISTS (
|
|
361
399
|
SELECT 1 FROM tool_events te
|
|
362
400
|
WHERE te.session_id = s.session_id AND te.commit_sha IS NOT NULL
|
|
@@ -382,9 +420,18 @@ export function listSessions(workspace_id, filters, cursor) {
|
|
|
382
420
|
compaction_count: r.compaction_count,
|
|
383
421
|
api_error_count: r.api_error_count,
|
|
384
422
|
interrupt_count: r.interrupt_count,
|
|
423
|
+
interrupts_supported: false,
|
|
424
|
+
api_error_eligible_request_count: null,
|
|
425
|
+
api_error_rate: null,
|
|
385
426
|
user_turn_count: r.user_turn_count,
|
|
386
427
|
tool_error_count: r.tool_error_count,
|
|
428
|
+
tool_completed_count: r.tool_completed_count,
|
|
429
|
+
tool_completed_error_count: r.tool_completed_error_count,
|
|
430
|
+
tool_error_rate: r.tool_completed_count > 0 ? r.tool_completed_error_count / r.tool_completed_count : null,
|
|
387
431
|
test_fail_count: r.test_fail_count,
|
|
432
|
+
test_completed_count: r.test_completed_count,
|
|
433
|
+
test_pass_count: r.test_pass_count,
|
|
434
|
+
test_outcome: r.test_outcome,
|
|
388
435
|
gap_median_s: r.gap_median_s,
|
|
389
436
|
gap_p90_s: r.gap_p90_s,
|
|
390
437
|
long_gap_count: r.long_gap_count,
|
|
@@ -393,6 +440,7 @@ export function listSessions(workspace_id, filters, cursor) {
|
|
|
393
440
|
deep_abandoned: r.deep_abandoned_int !== 0,
|
|
394
441
|
}));
|
|
395
442
|
return makeResponse({ items, next_cursor: nextCursor(offset, limit, total) }, {
|
|
443
|
+
metric_definition_version: "esf-1",
|
|
396
444
|
n: items.length,
|
|
397
445
|
window,
|
|
398
446
|
claim_kind: "LIST_EQUIV",
|
|
@@ -410,7 +458,30 @@ export function getSession(id) {
|
|
|
410
458
|
(SELECT COUNT(*) FROM tool_events te
|
|
411
459
|
WHERE te.session_id = s.session_id AND te.exit_class = 'ERROR') AS tool_error_count,
|
|
412
460
|
(SELECT COUNT(*) FROM tool_events te
|
|
413
|
-
WHERE te.session_id = s.session_id AND te.
|
|
461
|
+
WHERE te.session_id = s.session_id AND te.result_bytes IS NOT NULL) AS tool_completed_count,
|
|
462
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
463
|
+
WHERE te.session_id = s.session_id AND te.exit_class = 'ERROR'
|
|
464
|
+
AND te.result_bytes IS NOT NULL) AS tool_completed_error_count,
|
|
465
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
466
|
+
WHERE te.session_id = s.session_id AND te.exit_class = 'TEST_FAIL'
|
|
467
|
+
AND EXISTS (SELECT 1 FROM tool_event_metadata metadata
|
|
468
|
+
WHERE metadata.event_id = te.event_id AND metadata.is_test_command = 1)) AS test_fail_count,
|
|
469
|
+
(SELECT COUNT(*) FROM tool_events te JOIN tool_event_metadata metadata ON metadata.event_id = te.event_id
|
|
470
|
+
WHERE te.session_id = s.session_id AND metadata.is_test_command = 1 AND te.result_bytes IS NOT NULL) AS test_completed_count,
|
|
471
|
+
(SELECT COUNT(*) FROM tool_events te JOIN tool_event_metadata metadata ON metadata.event_id = te.event_id
|
|
472
|
+
WHERE te.session_id = s.session_id AND metadata.is_test_command = 1 AND te.exit_class = 'OK' AND te.result_bytes IS NOT NULL) AS test_pass_count,
|
|
473
|
+
CASE WHEN NOT EXISTS (SELECT 1 FROM tool_events observed JOIN tool_event_metadata observed_metadata ON observed_metadata.event_id = observed.event_id
|
|
474
|
+
WHERE observed.session_id = s.session_id AND observed_metadata.is_test_command = 1 AND observed.result_bytes IS NOT NULL)
|
|
475
|
+
THEN 'NO_TEST_OUTCOMES'
|
|
476
|
+
WHEN NOT EXISTS (SELECT 1 FROM tool_events failed JOIN tool_event_metadata failed_metadata ON failed_metadata.event_id = failed.event_id
|
|
477
|
+
WHERE failed.session_id = s.session_id AND failed_metadata.is_test_command = 1 AND failed.exit_class = 'TEST_FAIL' AND failed.result_bytes IS NOT NULL)
|
|
478
|
+
THEN 'NO_FAILURES_OBSERVED'
|
|
479
|
+
WHEN EXISTS (SELECT 1 FROM tool_events passed JOIN tool_event_metadata passed_metadata ON passed_metadata.event_id = passed.event_id
|
|
480
|
+
WHERE passed.session_id = s.session_id AND passed_metadata.is_test_command = 1 AND passed.exit_class = 'OK' AND passed.result_bytes IS NOT NULL
|
|
481
|
+
AND EXISTS (SELECT 1 FROM tool_events failed_before JOIN tool_event_metadata failed_before_metadata ON failed_before_metadata.event_id = failed_before.event_id
|
|
482
|
+
WHERE failed_before.session_id = s.session_id AND failed_before_metadata.is_test_command = 1
|
|
483
|
+
AND failed_before.exit_class = 'TEST_FAIL' AND failed_before.result_bytes IS NOT NULL AND failed_before.ts < passed.ts))
|
|
484
|
+
THEN 'FAILED_THEN_PASSED' ELSE 'FAILURES_OBSERVED' END AS test_outcome,
|
|
414
485
|
s.gap_median_s, s.gap_p90_s, s.long_gap_count, s.gap_n
|
|
415
486
|
FROM sessions s JOIN workspaces w USING (workspace_id)
|
|
416
487
|
WHERE s.session_id = ?`)
|
|
@@ -418,6 +489,7 @@ export function getSession(id) {
|
|
|
418
489
|
const window = resolveWindow({});
|
|
419
490
|
if (row === undefined) {
|
|
420
491
|
return makeResponse(null, {
|
|
492
|
+
metric_definition_version: "esf-1",
|
|
421
493
|
n: 0,
|
|
422
494
|
window,
|
|
423
495
|
claim_kind: "N_A",
|
|
@@ -441,9 +513,20 @@ export function getSession(id) {
|
|
|
441
513
|
compaction_count: row.compaction_count,
|
|
442
514
|
api_error_count: row.api_error_count,
|
|
443
515
|
interrupt_count: row.interrupt_count,
|
|
516
|
+
interrupts_supported: false,
|
|
517
|
+
api_error_eligible_request_count: null,
|
|
518
|
+
api_error_rate: null,
|
|
444
519
|
user_turn_count: row.user_turn_count,
|
|
445
520
|
tool_error_count: row.tool_error_count,
|
|
521
|
+
tool_completed_count: row.tool_completed_count,
|
|
522
|
+
tool_completed_error_count: row.tool_completed_error_count,
|
|
523
|
+
tool_error_rate: row.tool_completed_count > 0
|
|
524
|
+
? row.tool_completed_error_count / row.tool_completed_count
|
|
525
|
+
: null,
|
|
446
526
|
test_fail_count: row.test_fail_count,
|
|
527
|
+
test_completed_count: row.test_completed_count,
|
|
528
|
+
test_pass_count: row.test_pass_count,
|
|
529
|
+
test_outcome: row.test_outcome,
|
|
447
530
|
gap_median_s: row.gap_median_s,
|
|
448
531
|
gap_p90_s: row.gap_p90_s,
|
|
449
532
|
long_gap_count: row.long_gap_count,
|
|
@@ -451,6 +534,7 @@ export function getSession(id) {
|
|
|
451
534
|
...delivery,
|
|
452
535
|
};
|
|
453
536
|
return makeResponse(data, {
|
|
537
|
+
metric_definition_version: "esf-1",
|
|
454
538
|
n: 1,
|
|
455
539
|
window,
|
|
456
540
|
claim_kind: "LIST_EQUIV",
|
package/dist/query/spend.js
CHANGED
|
@@ -156,7 +156,61 @@ export function hotSessionsByCost(db, limit = 20, window) {
|
|
|
156
156
|
AND te.exit_class = 'ERROR') AS tool_error_count,
|
|
157
157
|
(SELECT COUNT(*) FROM tool_events te
|
|
158
158
|
WHERE te.session_id = s.session_id
|
|
159
|
-
AND te.exit_class = '
|
|
159
|
+
AND te.exit_class = 'ERROR'
|
|
160
|
+
AND te.result_bytes IS NOT NULL) AS tool_completed_error_count,
|
|
161
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
162
|
+
WHERE te.session_id = s.session_id
|
|
163
|
+
AND te.result_bytes IS NOT NULL) AS tool_completed_count,
|
|
164
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
165
|
+
WHERE te.session_id = s.session_id
|
|
166
|
+
AND te.exit_class = 'TEST_FAIL'
|
|
167
|
+
AND EXISTS (
|
|
168
|
+
SELECT 1 FROM tool_event_metadata metadata
|
|
169
|
+
WHERE metadata.event_id = te.event_id AND metadata.is_test_command = 1
|
|
170
|
+
)) AS test_fail_count,
|
|
171
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
172
|
+
JOIN tool_event_metadata metadata ON metadata.event_id = te.event_id
|
|
173
|
+
WHERE te.session_id = s.session_id
|
|
174
|
+
AND metadata.is_test_command = 1
|
|
175
|
+
AND te.result_bytes IS NOT NULL) AS test_completed_count,
|
|
176
|
+
(SELECT COUNT(*) FROM tool_events te
|
|
177
|
+
JOIN tool_event_metadata metadata ON metadata.event_id = te.event_id
|
|
178
|
+
WHERE te.session_id = s.session_id
|
|
179
|
+
AND metadata.is_test_command = 1
|
|
180
|
+
AND te.exit_class = 'OK'
|
|
181
|
+
AND te.result_bytes IS NOT NULL) AS test_pass_count,
|
|
182
|
+
CASE WHEN NOT EXISTS (
|
|
183
|
+
SELECT 1 FROM tool_events observed
|
|
184
|
+
JOIN tool_event_metadata observed_metadata ON observed_metadata.event_id = observed.event_id
|
|
185
|
+
WHERE observed.session_id = s.session_id
|
|
186
|
+
AND observed_metadata.is_test_command = 1
|
|
187
|
+
AND observed.result_bytes IS NOT NULL
|
|
188
|
+
) THEN 'NO_TEST_OUTCOMES'
|
|
189
|
+
WHEN NOT EXISTS (
|
|
190
|
+
SELECT 1 FROM tool_events failed
|
|
191
|
+
JOIN tool_event_metadata failed_metadata ON failed_metadata.event_id = failed.event_id
|
|
192
|
+
WHERE failed.session_id = s.session_id
|
|
193
|
+
AND failed_metadata.is_test_command = 1
|
|
194
|
+
AND failed.exit_class = 'TEST_FAIL'
|
|
195
|
+
AND failed.result_bytes IS NOT NULL
|
|
196
|
+
) THEN 'NO_FAILURES_OBSERVED'
|
|
197
|
+
WHEN EXISTS (
|
|
198
|
+
SELECT 1 FROM tool_events passed
|
|
199
|
+
JOIN tool_event_metadata passed_metadata ON passed_metadata.event_id = passed.event_id
|
|
200
|
+
WHERE passed.session_id = s.session_id
|
|
201
|
+
AND passed_metadata.is_test_command = 1
|
|
202
|
+
AND passed.exit_class = 'OK'
|
|
203
|
+
AND passed.result_bytes IS NOT NULL
|
|
204
|
+
AND EXISTS (
|
|
205
|
+
SELECT 1 FROM tool_events failed_before
|
|
206
|
+
JOIN tool_event_metadata failed_before_metadata ON failed_before_metadata.event_id = failed_before.event_id
|
|
207
|
+
WHERE failed_before.session_id = s.session_id
|
|
208
|
+
AND failed_before_metadata.is_test_command = 1
|
|
209
|
+
AND failed_before.exit_class = 'TEST_FAIL'
|
|
210
|
+
AND failed_before.result_bytes IS NOT NULL
|
|
211
|
+
AND failed_before.ts < passed.ts
|
|
212
|
+
)
|
|
213
|
+
) THEN 'FAILED_THEN_PASSED' ELSE 'FAILURES_OBSERVED' END AS test_outcome,
|
|
160
214
|
s.gap_median_s AS gap_median_s,
|
|
161
215
|
s.gap_p90_s AS gap_p90_s,
|
|
162
216
|
s.long_gap_count AS long_gap_count,
|
|
@@ -167,5 +221,13 @@ export function hotSessionsByCost(db, limit = 20, window) {
|
|
|
167
221
|
ORDER BY cost_equiv_u DESC, s.session_id ASC
|
|
168
222
|
LIMIT @limit`)
|
|
169
223
|
.all(window === undefined ? { limit } : { limit, from: window.from, to: window.to });
|
|
170
|
-
return rows
|
|
224
|
+
return rows.map((row) => ({
|
|
225
|
+
...row,
|
|
226
|
+
api_error_eligible_request_count: null,
|
|
227
|
+
api_error_rate: null,
|
|
228
|
+
interrupts_supported: false,
|
|
229
|
+
tool_error_rate: row.tool_completed_count > 0
|
|
230
|
+
? row.tool_completed_error_count / row.tool_completed_count
|
|
231
|
+
: null,
|
|
232
|
+
}));
|
|
171
233
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{r as u}from"./index-hbaLYHUX.js";import{aX as Le,a2 as V,aY as q,n as J,g as Te,aZ as Re,o as se,a1 as Fe,c as j,a_ as Ne,a$ as $e,s as F,a as We,d as T,e as R,f as ge,h as be,b0 as Ae,b1 as _e,b2 as Ge,k as ue,b3 as Ue,b4 as ce,x as Ve,L as _,p as Ze,r as Xe,D as ee,aN as Ye,t as Ie,v as He,S as qe,w as Je,Z as ae,y as O,z as Pe,A as Qe,B as ea,G as aa,E as ta,aO as ra,H as G,a9 as na,aP as ia,N as ke,J as oa,M as la,b5 as sa,b6 as ua,b7 as de,ay as Be,aR as Ee,aS as Se,aT as Oe,aA as ca,aa as we,U as da,W as va,_ as fa,$ as ma,l as pa,b8 as ha,a3 as ya,b9 as ve,a4 as xa,a5 as ga}from"./CartesianChart-CRV6h2et.js";import{s as K,a as z}from"./graphicalItemSelectors-CFhpQjLz.js";function ba(e,a){return ka(e)||Pa(e,a)||Ia(e,a)||Aa()}function Aa(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
2
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Ia(e,a){if(e){if(typeof e=="string")return fe(e,a);var t={}.toString.call(e).slice(8,-1);return t==="Object"&&e.constructor&&(t=e.constructor.name),t==="Map"||t==="Set"?Array.from(e):t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?fe(e,a):void 0}}function fe(e,a){(a==null||a>e.length)&&(a=e.length);for(var t=0,r=Array(a);t<a;t++)r[t]=e[t];return r}function Pa(e,a){var t=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(t!=null){var r,n,i,o,s=[],c=!0,l=!1;try{if(i=(t=t.call(e)).next,a!==0)for(;!(c=(r=i.call(t)).done)&&(s.push(r.value),s.length!==a);c=!0);}catch(d){l=!0,n=d}finally{try{if(!c&&t.return!=null&&(o=t.return(),Object(o)!==o))return}finally{if(l)throw n}}return s}}function ka(e){if(Array.isArray(e))return e}var me=(e,a,t)=>{var r=t??e;if(!V(r))return q(r,a,0)},Ba=(e,a,t)=>{var r={},n=e.filter(Le),i=e.filter(l=>l.stackId==null),o=n.reduce((l,d)=>{var v=l[d.stackId];return v==null&&(v=[]),v.push(d),l[d.stackId]=v,l},r),s=Object.entries(o).map(l=>{var d,v=ba(l,2),f=v[0],y=v[1],m=y.map(h=>h.dataKey),x=me(a,t,(d=y[0])===null||d===void 0?void 0:d.barSize);return{stackId:f,dataKeys:m,barSize:x}}),c=i.map(l=>{var d=[l.dataKey].filter(f=>f!=null),v=me(a,t,l.barSize);return{stackId:void 0,dataKeys:d,barSize:v}});return[...s,...c]};function pe(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);a&&(r=r.filter(function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable})),t.push.apply(t,r)}return t}function W(e){for(var a=1;a<arguments.length;a++){var t=arguments[a]!=null?arguments[a]:{};a%2?pe(Object(t),!0).forEach(function(r){Ea(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):pe(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}function Ea(e,a,t){return(a=Sa(a))in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function Sa(e){var a=Oa(e,"string");return typeof a=="symbol"?a:a+""}function Oa(e,a){if(typeof e!="object"||!e)return e;var t=e[Symbol.toPrimitive];if(t!==void 0){var r=t.call(e,a);if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(a==="string"?String:Number)(e)}function wa(e,a,t,r,n){var i,o=r.length;if(!(o<1)){var s=q(e,t,0,!0),c,l=[];if(J((i=r[0])===null||i===void 0?void 0:i.barSize)){var d=!1,v=t/o,f=r.reduce((g,I)=>g+(I.barSize||0),0);f+=(o-1)*s,f>=t&&(f-=(o-1)*s,s=0),f>=t&&v>0&&(d=!0,v*=.9,f=o*v);var y=Math.round((t-f)/2),m={offset:y-s,size:0};c=r.reduce((g,I)=>{var p,k={stackId:I.stackId,dataKeys:I.dataKeys,position:{offset:m.offset+m.size+s,size:d?v:(p=I.barSize)!==null&&p!==void 0?p:0}},B=[...g,k];return m=k.position,B},l)}else{var x=q(a,t,0,!0);t-2*x-(o-1)*s<=0&&(s=0);var h=(t-2*x-(o-1)*s)/o;h>1&&(h=Math.round(h));var b=J(n)?Math.min(h,n):h;c=r.reduce((g,I,p)=>[...g,{stackId:I.stackId,dataKeys:I.dataKeys,position:{offset:x+o*(h-b)/2+(b+s)*p,size:b}}],l)}return c}}var Ca=(e,a,t,r,n,i,o)=>{var s=V(o)?a:o,c=wa(t,r,n!==i?n:i,e,s);return n!==i&&c!=null&&(c=c.map(l=>W(W({},l),{},{position:W(W({},l.position),{},{offset:l.position.offset-n/2})}))),c},Da=(e,a)=>{var t=Te(a);if(!(!e||t==null||a==null)){var r=a.stackId;if(r!=null){var n=e[r];if(n){var i=n.stackedData;if(i)return i.find(o=>o.key===t)}}}},ja=(e,a)=>{if(!(e==null||a==null)){var t=e.find(r=>r.stackId===a.stackId&&a.dataKey!=null&&r.dataKeys.includes(a.dataKey));if(t!=null)return t.position}};function Ma(e,a){return e&&typeof e=="object"&&"zIndex"in e&&typeof e.zIndex=="number"&&J(e.zIndex)?e.zIndex:a}var Ka="Invariant failed";function za(e,a){throw new Error(Ka)}var La=["option"];function Ta(e,a){if(e==null)return{};var t,r,n=Ra(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],a.indexOf(t)===-1&&{}.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}function Ra(e,a){if(e==null)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(a.indexOf(r)!==-1)continue;t[r]=e[r]}return t}var te=Re;function re(e){var a=e.option,t=Ta(e,La);return u.createElement(Fe,{option:a,DefaultShape:te,shapeProps:t,activeClassName:"recharts-active-bar",inActiveClassName:"recharts-inactive-bar"})}var Fa=function(a){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return(r,n)=>{if(se(a))return a;var i=se(r)||V(r);return i?a(r,n):(i||za(),t)}},Na=(e,a,t)=>t,$a=(e,a)=>a,$=j([be,$a],(e,a)=>e.filter(t=>t.type==="bar").find(t=>t.id===a)),Wa=j([$],e=>e==null?void 0:e.maxBarSize),_a=(e,a,t,r)=>r,Ga=j([F,be,K,z,Na],(e,a,t,r,n)=>a.filter(i=>e==="horizontal"?i.xAxisId===t:i.yAxisId===r).filter(i=>i.isPanorama===n).filter(i=>i.hide===!1).filter(i=>i.type==="bar")),Ua=(e,a,t)=>{var r=F(e),n=K(e,a),i=z(e,a);if(!(n==null||i==null))return r==="horizontal"?ue(e,"yAxis",i,t):ue(e,"xAxis",n,t)},Va=(e,a)=>{var t=F(e),r=K(e,a),n=z(e,a);if(!(r==null||n==null))return t==="horizontal"?ce(e,"xAxis",r):ce(e,"yAxis",n)},Za=j([Ga,Ue,Va],Ba),Xa=(e,a,t)=>{var r,n,i=$(e,a);if(i==null)return 0;var o=K(e,a),s=z(e,a);if(o==null||s==null)return 0;var c=F(e),l=Ae(e),d=i.maxBarSize,v=V(d)?l:d,f,y;return c==="horizontal"?(f=T(e,"xAxis",o,t),y=R(e,"xAxis",o,t)):(f=T(e,"yAxis",s,t),y=R(e,"yAxis",s,t)),(r=(n=ge(f,y,!0))!==null&&n!==void 0?n:v)!==null&&r!==void 0?r:0},Ce=(e,a,t)=>{var r=F(e),n=K(e,a),i=z(e,a);if(!(n==null||i==null)){var o,s;return r==="horizontal"?(o=T(e,"xAxis",n,t),s=R(e,"xAxis",n,t)):(o=T(e,"yAxis",i,t),s=R(e,"yAxis",i,t)),ge(o,s)}},Ya=j([Za,Ae,_e,Ge,Xa,Ce,Wa],Ca),Ha=(e,a,t)=>{var r=K(e,a);if(r!=null)return T(e,"xAxis",r,t)},qa=(e,a,t)=>{var r=z(e,a);if(r!=null)return T(e,"yAxis",r,t)},Ja=(e,a,t)=>{var r=K(e,a);if(r!=null)return R(e,"xAxis",r,t)},Qa=(e,a,t)=>{var r=z(e,a);if(r!=null)return R(e,"yAxis",r,t)},et=j([Ya,$],ja),at=j([Ua,$],Da),tt=j([Ne,$e,Ha,qa,Ja,Qa,et,F,We,Ce,at,$,_a],(e,a,t,r,n,i,o,s,c,l,d,v,f)=>{var y=c.chartData,m=c.dataStartIndex,x=c.dataEndIndex;if(!(v==null||o==null||a==null||s!=="horizontal"&&s!=="vertical"||t==null||r==null||n==null||i==null||l==null)){var h=v.data,b;if(h!=null&&h.length>0?b=h:b=y==null?void 0:y.slice(m,x+1),b!=null)return zt({layout:s,barSettings:v,pos:o,parentViewBox:a,bandSize:l,xAxis:t,yAxis:r,xAxisTicks:n,yAxisTicks:i,stackedData:d,displayedData:b,offset:e,cells:f,dataStartIndex:m})}}),rt=["index"];function Q(){return Q=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var t=arguments[a];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Q.apply(null,arguments)}function nt(e,a){if(e==null)return{};var t,r,n=it(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],a.indexOf(t)===-1&&{}.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}function it(e,a){if(e==null)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(a.indexOf(r)!==-1)continue;t[r]=e[r]}return t}var De=u.createContext(void 0),ot=e=>{var a=u.useContext(De);if(a!=null)return a.stackId;if(e!=null)return Ve(e)},lt=(e,a)=>"recharts-bar-stack-clip-path-".concat(e,"-").concat(a),st=e=>{var a=u.useContext(De);if(a!=null){var t=a.stackId;return"url(#".concat(lt(t,e),")")}},je=e=>{var a=e.index,t=nt(e,rt),r=st(a);return u.createElement(_,Q({className:"recharts-bar-stack-layer",clipPath:r},t))},ut=["onMouseEnter","onMouseLeave","onClick"],ct=["value","background","tooltipPosition"],dt=["id"],vt=["onMouseEnter","onClick","onMouseLeave"];function he(e,a){return ht(e)||pt(e,a)||mt(e,a)||ft()}function ft(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
3
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function mt(e,a){if(e){if(typeof e=="string")return ye(e,a);var t={}.toString.call(e).slice(8,-1);return t==="Object"&&e.constructor&&(t=e.constructor.name),t==="Map"||t==="Set"?Array.from(e):t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?ye(e,a):void 0}}function ye(e,a){(a==null||a>e.length)&&(a=e.length);for(var t=0,r=Array(a);t<a;t++)r[t]=e[t];return r}function pt(e,a){var t=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(t!=null){var r,n,i,o,s=[],c=!0,l=!1;try{if(i=(t=t.call(e)).next,a!==0)for(;!(c=(r=i.call(t)).done)&&(s.push(r.value),s.length!==a);c=!0);}catch(d){l=!0,n=d}finally{try{if(!c&&t.return!=null&&(o=t.return(),Object(o)!==o))return}finally{if(l)throw n}}return s}}function ht(e){if(Array.isArray(e))return e}function D(){return D=Object.assign?Object.assign.bind():function(e){for(var a=1;a<arguments.length;a++){var t=arguments[a];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},D.apply(null,arguments)}function xe(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);a&&(r=r.filter(function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable})),t.push.apply(t,r)}return t}function A(e){for(var a=1;a<arguments.length;a++){var t=arguments[a]!=null?arguments[a]:{};a%2?xe(Object(t),!0).forEach(function(r){yt(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):xe(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}function yt(e,a,t){return(a=xt(a))in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function xt(e){var a=gt(e,"string");return typeof a=="symbol"?a:a+""}function gt(e,a){if(typeof e!="object"||!e)return e;var t=e[Symbol.toPrimitive];if(t!==void 0){var r=t.call(e,a);if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(a==="string"?String:Number)(e)}function U(e,a){if(e==null)return{};var t,r,n=bt(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],a.indexOf(t)===-1&&{}.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}function bt(e,a){if(e==null)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(a.indexOf(r)!==-1)continue;t[r]=e[r]}return t}var At=e=>{var a=e.dataKey,t=e.name,r=e.fill,n=e.legendType,i=e.hide;return[{inactive:i,dataKey:a,type:n,color:r,value:Pe(t,a),payload:e}]},It=u.memo(e=>{var a=e.dataKey,t=e.stroke,r=e.strokeWidth,n=e.fill,i=e.name,o=e.hide,s=e.unit,c=e.formatter,l=e.tooltipType,d=e.id,v={dataDefinedOnItem:void 0,getPosition:ea,settings:{stroke:t,strokeWidth:r,fill:n,dataKey:a,nameKey:void 0,name:Pe(i,a),hide:o,type:l,color:n,unit:s,formatter:c,graphicalItemId:d}};return u.createElement(Qe,{tooltipEntrySettings:v})});function Pt(e){var a=G(Be),t=e.data,r=e.dataKey,n=e.background,i=e.allOtherBarProps,o=i.onMouseEnter,s=i.onMouseLeave,c=i.onClick,l=U(i,ut),d=Ee(o,r,i.id),v=Se(s),f=Oe(c,r,i.id);if(!n||t==null)return null;var y=ca(n);return u.createElement(ae,{zIndex:Ma(n,ee.barBackground)},t.map((m,x)=>{m.value;var h=m.background;m.tooltipPosition;var b=U(m,ct);if(!h)return null;var g=d(m,m.originalDataIndex),I=v(m,m.originalDataIndex),p=f(m,m.originalDataIndex),k=A(A(A(A(A({option:n,isActive:String(m.originalDataIndex)===a},b),{},{fill:"#eee"},h),y),we(l,m,x)),{},{onMouseEnter:g,onMouseLeave:I,onClick:p,dataKey:r,index:x,className:"recharts-bar-background-rectangle"});return u.createElement(re,D({key:"background-bar-".concat(x)},k))}))}function kt(e){var a=e.showLabels,t=e.children,r=e.rects,n=r==null?void 0:r.map(i=>{var o={x:i.x,y:i.y,width:i.width,lowerWidth:i.width,upperWidth:i.width,height:i.height};return A(A({},o),{},{value:i.value,payload:i.payload,parentViewBox:i.parentViewBox,viewBox:o,fill:i.fill})});return u.createElement(ma,{value:a?n:void 0},t)}function Bt(e){var a=e.shape,t=e.activeBar,r=e.baseProps,n=e.entry,i=e.index,o=e.dataKey,s=G(Be),c=G(ha),l=t&&String(n.originalDataIndex)===s&&(c==null||o===c),d=s!=null&&(String(n.originalDataIndex)!==s||c!=null&&o!==c),v=u.useState(!1),f=he(v,2),y=f[0],m=f[1],x=u.useState(!1),h=he(x,2),b=h[0],g=h[1];u.useEffect(()=>{var P;return l?(m(!0),P=requestAnimationFrame(()=>{g(!0)})):(g(!1),d&&m(!1)),()=>{cancelAnimationFrame(P)}},[l,d]);var I=u.useCallback(()=>{l||m(!1)},[l]),p=l&&b,k=l||y,B;l?t===!0?B=a:B=t:B=a;var w=u.createElement(re,D({},r,{name:String(r.name)},n,{isActive:p,option:B,index:i,dataKey:o,animationElapsedTime:e.animationElapsedTime,isAnimating:e.isAnimating,isEntrance:e.isEntrance,onTransitionEnd:I}));return k?u.createElement(ae,{zIndex:ee.activeBar},u.createElement(je,{index:n.originalDataIndex},w)):w}function Et(e){var a=e.shape,t=e.baseProps,r=e.entry,n=e.index,i=e.dataKey;return u.createElement(re,D({},t,{name:String(t.name)},r,{isActive:!1,option:a,index:n,dataKey:i,animationElapsedTime:e.animationElapsedTime,isAnimating:e.isAnimating,isEntrance:e.isEntrance}))}function St(e){var a,t=e.data,r=e.props,n=e.animationElapsedTime,i=e.isAnimating,o=e.isEntrance,s=(a=pa(r))!==null&&a!==void 0?a:{},c=s.id,l=U(s,dt),d=r.shape,v=r.dataKey,f=r.activeBar,y=r.onMouseEnter,m=r.onClick,x=r.onMouseLeave,h=U(r,vt),b=Ee(y,v,c),g=Se(x),I=Oe(m,v,c);return t?u.createElement(u.Fragment,null,t.map((p,k)=>u.createElement(je,D({index:p.originalDataIndex,key:"rectangle-".concat(p==null?void 0:p.x,"-").concat(p==null?void 0:p.y,"-").concat(p==null?void 0:p.value,"-").concat(k),className:"recharts-bar-rectangle"},we(h,p,k),{onMouseEnter:b(p,p.originalDataIndex),onMouseLeave:g(p,p.originalDataIndex),onClick:I(p,p.originalDataIndex)}),f?u.createElement(Bt,{shape:d,activeBar:f,baseProps:l,entry:p,index:k,dataKey:v,animationElapsedTime:n,isAnimating:i,isEntrance:o}):u.createElement(Et,{shape:d,baseProps:l,entry:p,index:k,dataKey:v,animationElapsedTime:n,isAnimating:i,isEntrance:o})))):null}var Ot=(e,a,t)=>e==null?[]:a===1?e.flatMap(r=>r.status==="removed"?[]:[r.next]):e.flatMap(r=>{if(r.status==="removed")return t==="horizontal"?[A(A({},r.prev),{},{height:O(r.prev.height,0,a),y:O(r.prev.y,r.prev.y+r.prev.height,a)})]:[A(A({},r.prev),{},{width:O(r.prev.width,0,a)})];if(r.status==="matched")return[A(A({},r.next),{},{x:O(r.prev.x,r.next.x,a),y:O(r.prev.y,r.next.y,a),width:O(r.prev.width,r.next.width,a),height:O(r.prev.height,r.next.height,a)})];var n=r.next;return t==="horizontal"?[A(A({},n),{},{height:O(0,n.height,a),y:O(n.stackedBarStart,n.y,a)})]:[A(A({},n),{},{width:O(0,n.width,a),x:O(n.stackedBarStart,n.x,a)})]});function wt(e){var a=e.props,t=e.previousRectanglesRef,r=a.data,n=a.isAnimationActive,i=a.animationBegin,o=a.animationDuration,s=a.animationEasing,c=a.animationInterpolateFn,l=a.layout,d=da(a.onAnimationStart,a.onAnimationEnd),v=d.isAnimating,f=d.handleAnimationStart,y=d.handleAnimationEnd;return u.createElement(kt,{showLabels:!v,rects:r},u.createElement(va,{animationInput:r,animationIdPrefix:"recharts-bar-",items:r,previousItemsRef:t,isAnimationActive:n,animationBegin:i,animationDuration:o,animationEasing:s,onAnimationStart:f,onAnimationEnd:y,animationInterpolateFn:c,animationMatchBy:a.animationMatchBy,layout:l},(m,x,h)=>u.createElement(_,null,u.createElement(St,{props:a,data:m,animationElapsedTime:x,isAnimating:v||x<1,isEntrance:h}))),u.createElement(fa,{label:a.label}),a.children)}function Ct(e){var a=u.useRef(null);return u.createElement(wt,{previousRectanglesRef:a,props:e})}var Me=0,Dt=(e,a)=>{var t=Array.isArray(e.value)?e.value[1]:e.value;return{x:e.x,y:e.y,value:t,errorVal:ke(e,a)}};class jt extends u.PureComponent{render(){var a=this.props,t=a.hide,r=a.data,n=a.dataKey,i=a.className,o=a.xAxisId,s=a.yAxisId,c=a.needClip,l=a.background,d=a.id;if(t||r==null)return null;var v=oa("recharts-bar",i),f=d;return u.createElement(_,{className:v,id:d},c&&u.createElement("defs",null,u.createElement(la,{clipPathId:f,xAxisId:o,yAxisId:s})),u.createElement(_,{className:"recharts-bar-rectangles",clipPath:c?"url(#clipPath-".concat(f,")"):void 0},u.createElement(Pt,{data:r,dataKey:n,background:l,allOtherBarProps:this.props}),u.createElement(Ct,this.props)))}}var Mt={activeBar:!1,animationBegin:0,animationDuration:400,animationEasing:"ease",animationInterpolateFn:Ot,animationMatchBy:Ye,background:!1,hide:!1,isAnimationActive:"auto",label:!1,legendType:"rect",minPointSize:Me,shape:te,xAxisId:0,yAxisId:0,zIndex:ee.bar};function Kt(e){var a=e.xAxisId,t=e.yAxisId,r=e.hide,n=e.legendType,i=e.minPointSize,o=e.activeBar,s=e.animationBegin,c=e.animationDuration,l=e.animationEasing,d=e.isAnimationActive,v=aa(a,t),f=v.needClip,y=ta(),m=Ie(),x=ra(e.children,ia),h=G(I=>tt(I,e.id,m,x));if(y!=="vertical"&&y!=="horizontal")return null;var b,g=h==null?void 0:h[0];return g==null||g.height==null||g.width==null?b=0:b=y==="vertical"?g.height/2:g.width/2,u.createElement(na,{xAxisId:a,yAxisId:t,data:h,dataPointFormatter:Dt,errorBarOffset:b},u.createElement(jt,D({},e,{layout:y,needClip:f,data:h,xAxisId:a,yAxisId:t,hide:r,legendType:n,minPointSize:i,activeBar:o,animationBegin:s,animationDuration:c,animationEasing:l,isAnimationActive:d})))}function zt(e){var a=e.layout,t=e.barSettings,r=t.dataKey,n=t.minPointSize,i=t.hasCustomShape,o=e.pos,s=e.bandSize,c=e.xAxis,l=e.yAxis,d=e.xAxisTicks,v=e.yAxisTicks,f=e.stackedData,y=e.displayedData,m=e.offset,x=e.cells,h=e.parentViewBox,b=e.dataStartIndex,g=a==="horizontal"?l:c,I=f?g.scale.domain():null,p=sa({numericAxis:g}),k=g.scale.map(p);return y.map((B,w)=>{var P,L,M,E,S,Z;if(f){var ne=f[w+b];if(ne==null)return null;P=ua(ne,I)}else P=ke(B,r),Array.isArray(P)||(P=[p,P]);var C=Fa(n,Me)(P[1],w);if(a==="horizontal"){var X,Y=l.scale.map(P[0]),N=l.scale.map(P[1]);if(Y==null||N==null)return null;L=de({axis:c,ticks:d,bandSize:s,offset:o.offset,entry:B,index:w}),M=(X=N??Y)!==null&&X!==void 0?X:void 0,E=o.size;var ie=Y-N;if(S=ya(ie)?0:ie,Z={x:L,y:m.top,width:E,height:m.height},Math.abs(C)>0&&Math.abs(S)<Math.abs(C)){var oe=ve(S||C)*(Math.abs(C)-Math.abs(S));M-=oe,S+=oe}}else{var H=c.scale.map(P[0]),le=c.scale.map(P[1]);if(H==null||le==null)return null;if(L=H,M=de({axis:l,ticks:v,bandSize:s,offset:o.offset,entry:B,index:w}),E=le-H,S=o.size,Z={x:m.left,y:M,width:m.width,height:S},Math.abs(C)>0&&Math.abs(E)<Math.abs(C)){var Ke=ve(E||C)*(Math.abs(C)-Math.abs(E));E+=Ke}}if(L==null||M==null||E==null||S==null||!i&&(E===0||S===0))return null;var ze=A(A({},B),{},{stackedBarStart:k,x:L,y:M,width:E,height:S,value:f?P:P[1],payload:B,background:Z,tooltipPosition:{x:L+E/2,y:M+S/2},parentViewBox:h,originalDataIndex:w},x&&x[w]&&x[w].props);return ze}).filter(Boolean)}function Lt(e){var a=Xe(e,Mt),t=ot(a.stackId),r=Ie();return u.createElement(He,{id:a.id,type:"bar"},n=>u.createElement(u.Fragment,null,u.createElement(qe,{legendPayload:At(a)}),u.createElement(It,{dataKey:a.dataKey,stroke:a.stroke,strokeWidth:a.strokeWidth,fill:a.fill,name:a.name,hide:a.hide,unit:a.unit,formatter:a.formatter,tooltipType:a.tooltipType,id:n}),u.createElement(Je,{type:"bar",id:n,data:void 0,xAxisId:a.xAxisId,yAxisId:a.yAxisId,zAxisId:0,dataKey:a.dataKey,stackId:t,hide:a.hide,barSize:a.barSize,minPointSize:a.minPointSize,maxBarSize:a.maxBarSize,isPanorama:r,hasCustomShape:a.shape!=null&&a.shape!==te}),u.createElement(ae,{zIndex:a.zIndex},u.createElement(Kt,D({},a,{id:n})))))}var Tt=u.memo(Lt,Ze);Tt.displayName="Bar";var Rt=["axis","item"],Wt=u.forwardRef((e,a)=>u.createElement(xa,{chartName:"BarChart",defaultTooltipEventType:"axis",validateTooltipEventTypes:Rt,tooltipPayloadSearcher:ga,categoricalChartProps:e,ref:a}));export{Wt as B,Tt as a};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as p,f as D,a as B,b as y,c as R,d as I,j as s}from"./index-hbaLYHUX.js";import{w as F}from"./workspace-label-CysPJNc0.js";import{I as k}from"./InfoTip-CmcYFNQt.js";import{b as Y}from"./prompt-templates-CVzMex9L.js";import{s as V}from"./rec-sessions-ggz9MYgP.js";import{f as G}from"./FrictionCell-BGYB9UKh.js";import"./Chip-EizRm13x.js";const K=1e6,X=5,z=3;function c(e){return Number.isFinite(e)?e:0}function m(e){return c(e)/K}function W(e){let r=0,t=0;for(const u of e.buckets)r+=c(u.cache_creation_tokens),t+=c(u.cache_read_tokens);const i=r+t;return i===0?0:r/i}function E(e,r){return e.filter(t=>r===null||t.workspace_id===r)}const M={LOW:0,ELEVATED:1,HIGH:2};function J(e){if(e.length===0)return null;let r="LOW";for(const t of e){const i=G({api_error_count:t.api_error_count,tool_error_count:t.tool_error_count,test_fail_count:t.test_fail_count,compaction_count:t.compaction_count,interrupt_count:t.interrupt_count,user_turn_count:t.user_turn_count,turn_count:t.turns});M[i]>M[r]&&(r=i)}return r}function g(e,r){return{current:e,prior:r,delta:r===null?null:e-r}}function Q(e,r){return c(r.cost_equiv_u)-c(e.cost_equiv_u)||e.session_id.localeCompare(r.session_id)}function Z(e,r){const t=+(e.flavor!=="TURNKEY")-+(r.flavor!=="TURNKEY"),i=e.modeled_savings_usd_per_wk??Number.NEGATIVE_INFINITY,u=r.modeled_savings_usd_per_wk??Number.NEGATIVE_INFINITY;return t||u-i||e.detector_id.localeCompare(r.detector_id)||e.id.localeCompare(r.id)}function ee(e){const r=e.hotSessions.filter(n=>e.scopeWorkspaceId===null||n.workspace_id===e.scopeWorkspaceId).slice().sort(Q).slice(0,X).map(n=>({session_id:n.session_id,usd:m(n.cost_equiv_u),turns:c(n.turns),avg_context_tokens:c(n.avg_context_tokens),model:n.model}));let t=0,i=0,u=0;for(const n of e.cacheTrend.buckets)t+=c(n.cache_creation_tokens),i+=c(n.cache_read_tokens),u+=c(n.turns);const x=t+i,j=e.recs.map(n=>{const f=Y(n);return f===null?null:{id:n.rec_id,detector_id:n.detector_id,lever:n.lever,title:n.title??n.lever,workspace_id:n.scope_workspace_id,session_ids:V(n),file_ref:n.file_ref,tokens_per_turn:typeof n.evidence.delta_context_tokens=="number"&&Number.isFinite(n.evidence.delta_context_tokens)&&n.evidence.delta_context_tokens>0?n.evidence.delta_context_tokens:null,flavor:f.flavor,modeled_savings_usd_per_wk:n.modeled_savings_u_per_wk===null||n.detector_id==="D4"?null:m(n.modeled_savings_u_per_wk),prompt:f.text}}).filter(n=>n!==null).sort(Z),_=E(e.hotSessions,e.scopeWorkspaceId),l=e.prior!==void 0&&c(e.prior.overview.turns_total)>0?e.prior:null;return{scope:{label:e.scopeLabel,workspace_id:e.scopeWorkspaceId},verdict:{cost_usd:m(e.overview.cost_equiv_u),hot_session_count:_.length,peak_friction:J(_)},deltas:{spend_usd:g(m(e.overview.cost_equiv_u),l===null?null:m(l.overview.cost_equiv_u)),cache_write_share:g(W(e.cacheTrend),l===null?null:W(l.cacheTrend)),hot_session_count:g(_.length,l===null?null:E(l.hotSessions,e.scopeWorkspaceId).length)},actions:j.slice(0,z),overview:{cost_usd:m(e.overview.cost_equiv_u),turns:c(e.overview.turns),turns_total:c(e.overview.turns_total)},attribution:{hot_sessions:r,context_per_turn:e.overview.context_per_turn.map(n=>({model:n.model,turns:c(n.n),avg_context_per_turn:c(n.avg_context_per_turn),avg_output_per_turn:c(n.avg_output_per_turn),usd_per_turn:n.usd_per_turn===null?null:c(n.usd_per_turn)})),model_mix:e.overview.model_mix.map(n=>({model:n.model,turns:c(n.turns)})),cache_mix:{bucket_count:e.cacheTrend.buckets.length,spike_bucket_count:e.cacheTrend.spike_buckets.length,cache_write_tokens:t,cache_read_tokens:i,cache_read_share:x===0?0:i/x,turns:u}}}}function a(e){return c(e).toLocaleString(void 0,{maximumFractionDigits:6})}function w(e){const r=e.prior===null?"—":a(e.prior),t=e.delta===null?"—":a(e.delta);return`${a(e.current)} (prior ${r}, delta ${t})`}function se(e){const r=[`# Brief: ${e.scope.label}`,"","## Verdict",`- Cost equivalent USD: ${a(e.verdict.cost_usd)}`,`- Hot sessions: ${a(e.verdict.hot_session_count)}`,`- Peak friction: ${e.verdict.peak_friction??"none"}`,"","## Change vs prior 7 days",`- Spend equivalent USD: ${w(e.deltas.spend_usd)}`,`- Cache-write share: ${w(e.deltas.cache_write_share)}`,`- Hot sessions: ${w(e.deltas.hot_session_count)}`,"","## Do these three things",`- Actions: ${a(e.actions.length)}`];return e.actions.forEach((t,i)=>{r.push(`### ${i+1}. ${t.detector_id}: ${t.id}`),r.push(`- Lever: ${t.lever}`),r.push(`- Mode: ${t.flavor}`),r.push(`- Modeled savings USD/week: ${t.modeled_savings_usd_per_wk===null?"unavailable":a(t.modeled_savings_usd_per_wk)}`),r.push("- Prompt artifact:"),r.push(t.prompt)}),r.push("","<details>","","## Attribution",`- Hot sessions: ${a(e.attribution.hot_sessions.length)}`,...e.attribution.hot_sessions.map(t=>`- Session ${t.session_id}: USD ${a(t.usd)}, turns ${a(t.turns)}, context ${a(t.avg_context_tokens)}, model ${t.model}`),`- Context models: ${a(e.attribution.context_per_turn.length)}`,...e.attribution.context_per_turn.map(t=>{const i=t.usd_per_turn===null?"unpriced 0":`USD/turn ${a(t.usd_per_turn)}`;return`- Model ${t.model}: turns ${a(t.turns)}, context/turn ${a(t.avg_context_per_turn)}, output/turn ${a(t.avg_output_per_turn)}, ${i}`}),`- Model mix entries: ${a(e.attribution.model_mix.length)}`,...e.attribution.model_mix.map(t=>`- Model mix ${t.model}: turns ${a(t.turns)}`),`- Cache mix: ${a(e.attribution.cache_mix.bucket_count)} buckets, ${a(e.attribution.cache_mix.spike_bucket_count)} spikes, ${a(e.attribution.cache_mix.cache_write_tokens)} write tokens, ${a(e.attribution.cache_mix.cache_read_tokens)} read tokens, ${a(e.attribution.cache_mix.cache_read_share)} read share, ${a(e.attribution.cache_mix.turns)} turns`,"","</details>"),r.join(`
|
|
2
|
+
`)}const A=7,L=1440*60*1e3;function te(e=new Date){const r=e.getTime(),t=r-A*L,i=t-A*L;return{current:{from:new Date(t).toISOString(),to:new Date(r).toISOString()},prior:{from:new Date(i).toISOString(),to:new Date(t).toISOString()},label:`${new Date(t).toLocaleDateString()} – ${new Date(r).toLocaleDateString()}`}}function d(e){return e.toLocaleString(void 0,{maximumFractionDigits:2})}function v(e){return`$${d(e)}`}function O(e){return`${(e*100).toLocaleString(void 0,{maximumFractionDigits:1})}%`}function U(e,r){if(r===null)return"Global";const t=e.find(i=>i.workspace_id===r);return t===void 0?r:F(t)}function ne({delta:e,format:r}){if(e.delta===null)return s.jsx("span",{className:"brief-tile-delta brief-tile-delta-none",title:"No prior-week data to compare",children:"— vs prior week"});const t=e.delta>0?"up":e.delta<0?"down":"flat",i=t==="up"?"▲":t==="down"?"▼":"▬",u=e.delta>0?"+":"";return s.jsxs("span",{className:"brief-tile-delta brief-tile-delta-flat",children:[i," ",u,r(e.delta)," vs prior week"]})}function N({label:e,value:r,delta:t,format:i}){return s.jsxs("div",{className:"brief-tile",children:[s.jsx("div",{className:"brief-tile-label",children:e}),s.jsx("div",{className:"brief-tile-value",children:r}),s.jsx(ne,{delta:t,format:i})]})}function re({brief:e}){const{cache_mix:r,hot_sessions:t}=e.attribution;return s.jsxs("details",{className:"briefs-details",children:[s.jsx("summary",{children:"Usage breakdown and sessions"}),s.jsx("div",{className:"table-wrap",children:s.jsxs("table",{children:[s.jsx("thead",{children:s.jsxs("tr",{children:[s.jsx("th",{scope:"col",children:"Measure"}),s.jsx("th",{scope:"col",children:"Value"})]})}),s.jsxs("tbody",{children:[s.jsxs("tr",{children:[s.jsx("td",{children:"Cost equivalent"}),s.jsx("td",{children:v(e.overview.cost_usd)})]}),s.jsxs("tr",{children:[s.jsx("td",{children:"Turns with confirmed usage"}),s.jsx("td",{children:d(e.overview.turns)})]}),s.jsxs("tr",{children:[s.jsx("td",{children:"Total turns"}),s.jsx("td",{children:d(e.overview.turns_total)})]}),s.jsxs("tr",{children:[s.jsx("td",{children:"Cache write tokens"}),s.jsx("td",{children:d(r.cache_write_tokens)})]}),s.jsxs("tr",{children:[s.jsx("td",{children:"Cache read tokens"}),s.jsx("td",{children:d(r.cache_read_tokens)})]}),s.jsxs("tr",{children:[s.jsx("td",{children:"Hot sessions"}),s.jsx("td",{children:d(t.length)})]})]})]})}),t.length>0&&s.jsx("div",{className:"table-wrap",children:s.jsxs("table",{children:[s.jsx("thead",{children:s.jsxs("tr",{children:[s.jsx("th",{scope:"col",children:"Session"}),s.jsx("th",{scope:"col",children:"Cost"}),s.jsx("th",{scope:"col",children:"Turns"}),s.jsx("th",{scope:"col",children:"Context / turn"}),s.jsx("th",{scope:"col",children:"Model"})]})}),s.jsx("tbody",{children:t.map(i=>s.jsxs("tr",{children:[s.jsx("td",{children:i.session_id}),s.jsx("td",{children:v(i.usd)}),s.jsx("td",{children:d(i.turns)}),s.jsx("td",{children:d(i.avg_context_tokens)}),s.jsx("td",{children:i.model})]},i.session_id))})]})})]})}function he(){const[e,r]=p.useState({status:"loading"}),[t,i]=p.useState(null),[u,x]=p.useState(!1),[j,_]=p.useState(null),l=p.useMemo(()=>te(),[]);p.useEffect(()=>{let o=!1;return Promise.all([D(l.current),B(l.current),y(l.current),R(),I(l.current),D(l.prior),y(l.prior),I(l.prior)]).then(([h,b,S,$,H,T,C,q])=>{if(!o){if(h.data===null||b.data===null||S.data===null||$.data===null||T.data===null||C.data===null)throw new Error("Brief data was unavailable");r({status:"ok",overview:h.data,workspaces:b.data.items,cacheTrend:S.data,recs:$.data,hotSessions:H,priorOverview:T.data,priorCacheTrend:C.data,priorHotSessions:q})}}).catch(h=>{o||r({status:"error",message:String(h)})}),()=>{o=!0}},[l]);const n=e.status==="ok"?ee({scopeLabel:U(e.workspaces,t),scopeWorkspaceId:t,overview:e.overview,hotSessions:e.hotSessions,cacheTrend:e.cacheTrend,recs:e.recs.active.filter(o=>t===null||o.scope_workspace_id===null||o.scope_workspace_id===t),prior:{overview:e.priorOverview,hotSessions:e.priorHotSessions,cacheTrend:e.priorCacheTrend}}):null;async function f(){n!==null&&(await navigator.clipboard.writeText(se(n)),x(!0),window.setTimeout(()=>x(!1),2e3))}async function P(o,h){await navigator.clipboard.writeText(h),_(o),window.setTimeout(()=>_(b=>b===o?null:b),2e3)}return s.jsxs("div",{className:"briefs-page",children:[s.jsx("div",{className:"page-top",children:s.jsxs("div",{className:"page-title",children:[s.jsx("h1",{children:"Briefs"}),s.jsx("p",{className:"page-sub",children:"Your last seven days: token use, changes, and next steps"})]})}),e.status==="loading"&&s.jsx("div",{className:"card","aria-busy":"true",children:"Loading brief data..."}),e.status==="error"&&s.jsxs("div",{className:"banner banner-error",role:"alert",children:["Could not load brief: ",e.message]}),e.status==="ok"&&n!==null&&s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"briefs-controls",children:[s.jsxs("label",{className:"briefs-scope",htmlFor:"briefs-scope",children:["Scope",s.jsxs("select",{id:"briefs-scope",value:t??"",onChange:o=>i(o.target.value||null),children:[s.jsx("option",{value:"",children:"Global"}),e.workspaces.map(o=>s.jsx("option",{value:o.workspace_id,children:F(o)},o.workspace_id))]})]}),s.jsx("span",{className:"briefs-window",title:"Rolling seven-day window",children:l.label}),s.jsx("button",{type:"button",className:"btn-primary",onClick:()=>void f(),children:u?"Copied":"Copy as markdown"})]}),s.jsx("section",{className:"card briefs-verdict","aria-labelledby":"briefs-verdict-heading",children:s.jsxs("h2",{id:"briefs-verdict-heading",className:"briefs-verdict-line",children:[s.jsx("strong",{children:v(n.verdict.cost_usd)})," ",s.jsx(k,{label:"What list-price estimate means",content:"Estimated value at public per-token prices, not your subscription bill or remaining allowance. Check the usage bars on Overview for your current limits.",children:"list-price estimate"}),s.jsx("span",{className:"briefs-verdict-sep",children:" · "}),s.jsxs(k,{label:"What hot sessions means",content:"Sessions with the highest estimated token value in this selection. The brief lists up to five; this is not a count of wasteful sessions.",children:[d(n.verdict.hot_session_count)," hot sessions"]}),s.jsx("span",{className:"briefs-verdict-sep",children:" · "}),n.verdict.peak_friction===null?s.jsx("span",{className:"briefs-friction",children:"no friction signal"}):s.jsxs("span",{className:`briefs-friction briefs-friction-${n.verdict.peak_friction}`,children:[s.jsx(k,{label:"What peak friction means",content:"The highest level of errors, failed tests, and interruptions among these sessions. These events can be part of normal work; review the session before deciding what to change.",children:"peak friction"})," ",n.verdict.peak_friction]})]})}),s.jsxs("div",{className:"brief-tiles-head",children:[s.jsx("span",{className:"brief-tiles-heading",children:"Week-over-week changes"}),s.jsx(k,{label:"What the delta tiles show",content:"Compared with the previous seven days. Cache-write share is the proportion of cached tokens written rather than reused; lower usage alone does not prove better efficiency, and hot sessions is a capped list count."})]}),s.jsxs("div",{className:"brief-tiles",children:[s.jsx(N,{label:"Spend equivalent",value:v(n.deltas.spend_usd.current),delta:n.deltas.spend_usd,format:v}),s.jsx(N,{label:"Cache-write share",value:O(n.deltas.cache_write_share.current),delta:n.deltas.cache_write_share,format:O}),s.jsx(N,{label:"Hot sessions",value:d(n.deltas.hot_session_count.current),delta:n.deltas.hot_session_count,format:d})]}),s.jsxs("section",{className:"card briefs-actions","aria-labelledby":"briefs-actions-heading",children:[s.jsx("div",{className:"section-head",children:s.jsx("h2",{id:"briefs-actions-heading",children:"Top three next steps"})}),n.actions.length===0?s.jsx("p",{className:"kpi-off-hint",children:"No suggestions for this selection yet."}):s.jsx("ol",{className:"briefs-action-list",children:n.actions.map(o=>s.jsxs("li",{className:"briefs-action",children:[s.jsxs("div",{className:"briefs-action-main",children:[s.jsx("strong",{children:o.title}),o.title!==o.lever&&s.jsx("p",{children:o.lever}),s.jsxs("p",{className:"brief-action-scope",children:[s.jsx("strong",{children:"Where:"})," ",U(e.workspaces,o.workspace_id),o.file_ref!==null&&s.jsxs(s.Fragment,{children:[" ","· ",s.jsx("code",{children:o.file_ref})]})]}),s.jsxs("p",{children:[o.session_ids.length>0?`Based on ${o.session_ids.length} affected session${o.session_ids.length===1?"":"s"}.`:"No individual sessions are linked to this suggestion.",o.tokens_per_turn!==null&&s.jsxs(s.Fragment,{children:[" ","Possible reduction: ",d(o.tokens_per_turn)," context tokens per turn (text sent to the model)."]})]}),o.session_ids.length>0&&s.jsxs("details",{children:[s.jsx("summary",{children:"View affected sessions"}),s.jsx("ul",{children:o.session_ids.map(h=>s.jsx("li",{children:s.jsx("a",{href:`#/sessions/${encodeURIComponent(h)}`,children:h})},h))})]}),s.jsx("p",{className:"kpi-off-hint",children:o.modeled_savings_usd_per_wk===null?"No reliable savings estimate is available.":`Possible reduction: ${v(o.modeled_savings_usd_per_wk)} / week at list prices. This is an estimate, not achieved savings.`}),s.jsx("a",{href:`#/recommendations?focus=${encodeURIComponent(o.id)}`,children:"Review evidence and track this change"}),s.jsx("p",{children:o.flavor==="TURNKEY"?"Paste this prompt into Claude Code in the workspace above and review the proposed edits.":"Paste this prompt into Claude Code to review the recorded usage and decide what to change."}),s.jsx("textarea",{className:"prompt-code","aria-label":`Prompt for ${o.title}`,readOnly:!0,value:o.prompt})]}),s.jsx("button",{type:"button",className:"btn-secondary briefs-action-copy",onClick:()=>void P(o.id,o.prompt),children:j===o.id?"Copied":"Copy prompt"})]},o.id))})]}),s.jsx(re,{brief:n})]})]})}export{he as default};
|