@sanity/ailf-studio 0.1.10 → 0.1.12
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 +5 -4
- package/dist/index.d.ts +43 -2
- package/dist/index.js +507 -232
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -68,6 +68,314 @@ var GraduateToNativeAction = (props) => {
|
|
|
68
68
|
};
|
|
69
69
|
GraduateToNativeAction.displayName = "GraduateToNativeAction";
|
|
70
70
|
|
|
71
|
+
// src/actions/RunTaskEvaluationAction.tsx
|
|
72
|
+
import { PlayIcon } from "@sanity/icons";
|
|
73
|
+
import { useToast } from "@sanity/ui";
|
|
74
|
+
import { useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
|
|
75
|
+
import {
|
|
76
|
+
useClient as useClient2,
|
|
77
|
+
useCurrentUser,
|
|
78
|
+
useDataset,
|
|
79
|
+
useProjectId
|
|
80
|
+
} from "sanity";
|
|
81
|
+
|
|
82
|
+
// ../shared/dist/score-grades.js
|
|
83
|
+
var GRADE_BOUNDARIES = {
|
|
84
|
+
good: 80,
|
|
85
|
+
warning: 70,
|
|
86
|
+
critical: 50
|
|
87
|
+
};
|
|
88
|
+
function scoreGrade(score) {
|
|
89
|
+
if (score >= GRADE_BOUNDARIES.good)
|
|
90
|
+
return "good";
|
|
91
|
+
if (score >= GRADE_BOUNDARIES.warning)
|
|
92
|
+
return "warning";
|
|
93
|
+
if (score >= GRADE_BOUNDARIES.critical)
|
|
94
|
+
return "needs-work";
|
|
95
|
+
return "critical";
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ../shared/dist/noise-threshold.js
|
|
99
|
+
var NOISE_THRESHOLD = 2;
|
|
100
|
+
|
|
101
|
+
// ../shared/dist/dimension-names.js
|
|
102
|
+
var DIMENSION_LABELS_KEBAB = {
|
|
103
|
+
"code-correctness": "Code Correctness",
|
|
104
|
+
"doc-coverage": "Doc Coverage",
|
|
105
|
+
"task-completion": "Task Completion"
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// src/types.ts
|
|
109
|
+
function formatPercent(n) {
|
|
110
|
+
if (n == null) return "\u2014";
|
|
111
|
+
return `${(n * 100).toFixed(0)}%`;
|
|
112
|
+
}
|
|
113
|
+
function formatRelativeTime(iso) {
|
|
114
|
+
const diff = Date.now() - new Date(iso).getTime();
|
|
115
|
+
const minutes = Math.floor(diff / 6e4);
|
|
116
|
+
if (minutes < 1) return "just now";
|
|
117
|
+
if (minutes === 1) return "1 minute ago";
|
|
118
|
+
if (minutes < 60) return `${minutes} minutes ago`;
|
|
119
|
+
const hours = Math.floor(minutes / 60);
|
|
120
|
+
if (hours === 1) return "1 hour ago";
|
|
121
|
+
if (hours < 24) return `${hours} hours ago`;
|
|
122
|
+
const days = Math.floor(hours / 24);
|
|
123
|
+
if (days === 1) return "yesterday";
|
|
124
|
+
if (days < 7) return `${days} days ago`;
|
|
125
|
+
const weeks = Math.floor(days / 7);
|
|
126
|
+
if (weeks === 1) return "1 week ago";
|
|
127
|
+
if (weeks < 5) return `${weeks} weeks ago`;
|
|
128
|
+
const months = Math.floor(days / 30);
|
|
129
|
+
if (months === 1) return "1 month ago";
|
|
130
|
+
if (months < 12) return `${months} months ago`;
|
|
131
|
+
const years = Math.floor(days / 365);
|
|
132
|
+
if (years === 1) return "1 year ago";
|
|
133
|
+
return `${years} years ago`;
|
|
134
|
+
}
|
|
135
|
+
function formatDelta(n) {
|
|
136
|
+
if (n > 0) return `+${n.toFixed(1)}`;
|
|
137
|
+
if (n < 0) return n.toFixed(1);
|
|
138
|
+
return "0";
|
|
139
|
+
}
|
|
140
|
+
function formatDuration(ms) {
|
|
141
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
142
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
143
|
+
const min = Math.floor(ms / 6e4);
|
|
144
|
+
const sec = Math.round(ms % 6e4 / 1e3);
|
|
145
|
+
return `${min}m ${sec}s`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/actions/RunTaskEvaluationAction.tsx
|
|
149
|
+
var EVAL_REQUEST_TYPE = "ailf.evalRequest";
|
|
150
|
+
var POLL_INTERVAL_MS = 15e3;
|
|
151
|
+
var MAX_POLL_MS = 30 * 60 * 1e3;
|
|
152
|
+
var EVAL_REQUEST_STATUS_QUERY = (
|
|
153
|
+
/* groq */
|
|
154
|
+
`
|
|
155
|
+
*[_type == "${EVAL_REQUEST_TYPE}" && _id == $id][0] {
|
|
156
|
+
status,
|
|
157
|
+
error,
|
|
158
|
+
reportId
|
|
159
|
+
}
|
|
160
|
+
`
|
|
161
|
+
);
|
|
162
|
+
var TASK_REPORT_QUERY = (
|
|
163
|
+
/* groq */
|
|
164
|
+
`
|
|
165
|
+
*[_type == "ailf.report"
|
|
166
|
+
&& $taskId in provenance.taskIds
|
|
167
|
+
] | order(completedAt desc) [0] {
|
|
168
|
+
reportId,
|
|
169
|
+
completedAt,
|
|
170
|
+
"overall": summary.overall.avgScore,
|
|
171
|
+
"taskScore": summary.scores[feature == $area][0].totalScore
|
|
172
|
+
}
|
|
173
|
+
`
|
|
174
|
+
);
|
|
175
|
+
function slugify(s) {
|
|
176
|
+
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
177
|
+
}
|
|
178
|
+
function dateStamp() {
|
|
179
|
+
const d = /* @__PURE__ */ new Date();
|
|
180
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
181
|
+
}
|
|
182
|
+
var RunTaskEvaluationAction = (props) => {
|
|
183
|
+
const { type, draft, published } = props;
|
|
184
|
+
const client = useClient2({ apiVersion: API_VERSION });
|
|
185
|
+
const dataset = useDataset();
|
|
186
|
+
const projectId = useProjectId();
|
|
187
|
+
const currentUser = useCurrentUser();
|
|
188
|
+
const toast = useToast();
|
|
189
|
+
const [state, setState] = useState2({ status: "idle" });
|
|
190
|
+
const requestedAtRef = useRef(null);
|
|
191
|
+
const doc = draft ?? published;
|
|
192
|
+
const taskIdSlug = doc?.id;
|
|
193
|
+
const taskId = taskIdSlug?.current;
|
|
194
|
+
const featureAreaRef = doc?.featureArea;
|
|
195
|
+
const taskDescription = doc?.description ?? taskId ?? "this task";
|
|
196
|
+
const [areaId, setAreaId] = useState2(null);
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
if (!featureAreaRef?._ref) return;
|
|
199
|
+
let cancelled = false;
|
|
200
|
+
client.fetch(`*[_id == $id][0].areaId`, {
|
|
201
|
+
id: featureAreaRef._ref
|
|
202
|
+
}).then((result) => {
|
|
203
|
+
if (!cancelled && result?.current) {
|
|
204
|
+
setAreaId(result.current);
|
|
205
|
+
}
|
|
206
|
+
}).catch(() => {
|
|
207
|
+
});
|
|
208
|
+
return () => {
|
|
209
|
+
cancelled = true;
|
|
210
|
+
};
|
|
211
|
+
}, [client, featureAreaRef?._ref]);
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
if (!taskId || !areaId) return;
|
|
214
|
+
let cancelled = false;
|
|
215
|
+
client.fetch(TASK_REPORT_QUERY, {
|
|
216
|
+
taskId,
|
|
217
|
+
area: areaId
|
|
218
|
+
}).then((result) => {
|
|
219
|
+
if (cancelled || !result) return;
|
|
220
|
+
const score = result.taskScore ?? Math.round(result.overall);
|
|
221
|
+
setState({
|
|
222
|
+
completedAt: result.completedAt,
|
|
223
|
+
reportId: result.reportId,
|
|
224
|
+
score: Math.round(score),
|
|
225
|
+
status: "ready"
|
|
226
|
+
});
|
|
227
|
+
}).catch(() => {
|
|
228
|
+
});
|
|
229
|
+
return () => {
|
|
230
|
+
cancelled = true;
|
|
231
|
+
};
|
|
232
|
+
}, [client, taskId, areaId]);
|
|
233
|
+
useEffect(() => {
|
|
234
|
+
if (state.status !== "requested" && state.status !== "polling") return;
|
|
235
|
+
const { requestId, startedAt } = state;
|
|
236
|
+
if (state.status === "requested") {
|
|
237
|
+
setState({ requestId, startedAt, status: "polling" });
|
|
238
|
+
}
|
|
239
|
+
const interval = setInterval(async () => {
|
|
240
|
+
if (Date.now() - startedAt > MAX_POLL_MS) {
|
|
241
|
+
clearInterval(interval);
|
|
242
|
+
setState({
|
|
243
|
+
message: "Evaluation is still running. Check the AI Literacy dashboard for results.",
|
|
244
|
+
status: "error"
|
|
245
|
+
});
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
const reqStatus = await client.fetch(EVAL_REQUEST_STATUS_QUERY, {
|
|
250
|
+
id: requestId
|
|
251
|
+
});
|
|
252
|
+
if (reqStatus?.status === "failed") {
|
|
253
|
+
clearInterval(interval);
|
|
254
|
+
setState({
|
|
255
|
+
message: reqStatus.error ?? "Evaluation dispatch failed.",
|
|
256
|
+
status: "error"
|
|
257
|
+
});
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (!taskId) return;
|
|
261
|
+
const result = await client.fetch(TASK_REPORT_QUERY, {
|
|
262
|
+
taskId,
|
|
263
|
+
area: areaId ?? ""
|
|
264
|
+
});
|
|
265
|
+
if (result) {
|
|
266
|
+
const reportTime = new Date(result.completedAt).getTime();
|
|
267
|
+
if (reportTime > startedAt) {
|
|
268
|
+
clearInterval(interval);
|
|
269
|
+
const score = result.taskScore ?? Math.round(result.overall);
|
|
270
|
+
setState({
|
|
271
|
+
completedAt: result.completedAt,
|
|
272
|
+
reportId: result.reportId,
|
|
273
|
+
score: Math.round(score),
|
|
274
|
+
status: "ready"
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
}, POLL_INTERVAL_MS);
|
|
281
|
+
return () => clearInterval(interval);
|
|
282
|
+
}, [client, taskId, areaId, state]);
|
|
283
|
+
useEffect(() => {
|
|
284
|
+
if (state.status !== "error") return;
|
|
285
|
+
const timer = setTimeout(() => {
|
|
286
|
+
setState({ status: "idle" });
|
|
287
|
+
}, 15e3);
|
|
288
|
+
return () => clearTimeout(timer);
|
|
289
|
+
}, [state]);
|
|
290
|
+
const handleRequest = useCallback2(async () => {
|
|
291
|
+
if (!taskId) return;
|
|
292
|
+
const tag = `task-${slugify(taskId)}-${dateStamp()}`;
|
|
293
|
+
const now = Date.now();
|
|
294
|
+
try {
|
|
295
|
+
const evalRequest = await client.create({
|
|
296
|
+
_type: EVAL_REQUEST_TYPE,
|
|
297
|
+
dataset,
|
|
298
|
+
mode: "full",
|
|
299
|
+
projectId,
|
|
300
|
+
requestedAt: new Date(now).toISOString(),
|
|
301
|
+
requestedBy: currentUser?.id ?? "unknown",
|
|
302
|
+
status: "pending",
|
|
303
|
+
tag,
|
|
304
|
+
tasks: [taskId],
|
|
305
|
+
...areaId ? { areas: [areaId] } : {}
|
|
306
|
+
});
|
|
307
|
+
requestedAtRef.current = now;
|
|
308
|
+
setState({
|
|
309
|
+
requestId: evalRequest._id,
|
|
310
|
+
startedAt: now,
|
|
311
|
+
status: "requested"
|
|
312
|
+
});
|
|
313
|
+
toast.push({
|
|
314
|
+
closable: true,
|
|
315
|
+
description: `Evaluating "${taskDescription}". Results will appear here when the pipeline completes.`,
|
|
316
|
+
status: "info",
|
|
317
|
+
title: "Task evaluation started"
|
|
318
|
+
});
|
|
319
|
+
} catch (err) {
|
|
320
|
+
const message = err instanceof Error ? err.message : "Failed to create evaluation request";
|
|
321
|
+
setState({ message, status: "error" });
|
|
322
|
+
toast.push({
|
|
323
|
+
closable: true,
|
|
324
|
+
description: message,
|
|
325
|
+
status: "error",
|
|
326
|
+
title: "Task evaluation failed"
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}, [
|
|
330
|
+
client,
|
|
331
|
+
currentUser?.id,
|
|
332
|
+
dataset,
|
|
333
|
+
projectId,
|
|
334
|
+
taskId,
|
|
335
|
+
taskDescription,
|
|
336
|
+
areaId
|
|
337
|
+
]);
|
|
338
|
+
if (type !== "ailf.task" || !taskId) return null;
|
|
339
|
+
return {
|
|
340
|
+
disabled: state.status === "requested" || state.status === "polling",
|
|
341
|
+
icon: PlayIcon,
|
|
342
|
+
label: getLabel(state),
|
|
343
|
+
onHandle: handleRequest,
|
|
344
|
+
title: getTitle(state, taskId)
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
RunTaskEvaluationAction.displayName = "RunTaskEvaluationAction";
|
|
348
|
+
function getLabel(state) {
|
|
349
|
+
switch (state.status) {
|
|
350
|
+
case "idle":
|
|
351
|
+
return "Run Task Eval";
|
|
352
|
+
case "requested":
|
|
353
|
+
return "Requesting\u2026";
|
|
354
|
+
case "polling":
|
|
355
|
+
return "Evaluating\u2026";
|
|
356
|
+
case "ready":
|
|
357
|
+
return `Score: ${state.score}`;
|
|
358
|
+
case "error":
|
|
359
|
+
return "Eval Failed";
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function getTitle(state, taskId) {
|
|
363
|
+
switch (state.status) {
|
|
364
|
+
case "idle":
|
|
365
|
+
return `Run an AI Literacy evaluation for this task (${taskId}). Runs all test cases against the current documentation.`;
|
|
366
|
+
case "requested":
|
|
367
|
+
return "Creating evaluation request\u2026";
|
|
368
|
+
case "polling":
|
|
369
|
+
return "Evaluation is running. The score will appear here when complete. You can navigate away \u2014 the result will show next time you open this task.";
|
|
370
|
+
case "ready": {
|
|
371
|
+
const when = formatRelativeTime(state.completedAt);
|
|
372
|
+
return `Task Score: ${state.score}/100 (evaluated ${when}). Click to re-run.`;
|
|
373
|
+
}
|
|
374
|
+
case "error":
|
|
375
|
+
return `${state.message} Click to try again.`;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
71
379
|
// src/schema/eval-request.ts
|
|
72
380
|
import { ALL_FIELDS_GROUP, defineField, defineType } from "sanity";
|
|
73
381
|
var evalRequestSchema = defineType({
|
|
@@ -128,13 +436,38 @@ var evalRequestSchema = defineType({
|
|
|
128
436
|
type: "string"
|
|
129
437
|
}),
|
|
130
438
|
defineField({
|
|
131
|
-
description: "Content release perspective ID",
|
|
439
|
+
description: "Content release perspective ID (required for release evals)",
|
|
132
440
|
group: ["main", "all-fields"],
|
|
133
441
|
name: "perspective",
|
|
134
442
|
readOnly: true,
|
|
135
443
|
title: "Perspective",
|
|
136
|
-
type: "string"
|
|
137
|
-
|
|
444
|
+
type: "string"
|
|
445
|
+
}),
|
|
446
|
+
defineField({
|
|
447
|
+
description: "Specific task IDs to evaluate (for task-scoped evals). When set, the pipeline only runs these tasks instead of the full suite.",
|
|
448
|
+
group: ["optional", "all-fields"],
|
|
449
|
+
name: "tasks",
|
|
450
|
+
of: [{ type: "string" }],
|
|
451
|
+
readOnly: true,
|
|
452
|
+
title: "Tasks",
|
|
453
|
+
type: "array"
|
|
454
|
+
}),
|
|
455
|
+
defineField({
|
|
456
|
+
description: "Feature areas to scope the evaluation. When set together with tasks, provides additional context for the pipeline.",
|
|
457
|
+
group: ["optional", "all-fields"],
|
|
458
|
+
name: "areas",
|
|
459
|
+
of: [{ type: "string" }],
|
|
460
|
+
readOnly: true,
|
|
461
|
+
title: "Areas",
|
|
462
|
+
type: "array"
|
|
463
|
+
}),
|
|
464
|
+
defineField({
|
|
465
|
+
description: "Run in debug mode (limits to a subset of test cases for fast feedback).",
|
|
466
|
+
group: ["optional", "all-fields"],
|
|
467
|
+
name: "debug",
|
|
468
|
+
readOnly: true,
|
|
469
|
+
title: "Debug",
|
|
470
|
+
type: "boolean"
|
|
138
471
|
}),
|
|
139
472
|
defineField({
|
|
140
473
|
description: "Sanity project ID",
|
|
@@ -199,15 +532,22 @@ var evalRequestSchema = defineType({
|
|
|
199
532
|
],
|
|
200
533
|
name: "ailf.evalRequest",
|
|
201
534
|
preview: {
|
|
202
|
-
prepare({ perspective, status }) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
535
|
+
prepare({ perspective, status, tasks }) {
|
|
536
|
+
const statusStr = typeof status === "string" ? status : "unknown";
|
|
537
|
+
let title;
|
|
538
|
+
if (typeof perspective === "string") {
|
|
539
|
+
title = perspective;
|
|
540
|
+
} else if (Array.isArray(tasks) && tasks.length > 0) {
|
|
541
|
+
title = tasks.length === 1 ? `Task: ${tasks[0]}` : `Tasks: ${tasks.slice(0, 3).join(", ")}${tasks.length > 3 ? "\u2026" : ""}`;
|
|
542
|
+
} else {
|
|
543
|
+
title = "Evaluation Request";
|
|
544
|
+
}
|
|
545
|
+
return { subtitle: statusStr, title };
|
|
207
546
|
},
|
|
208
547
|
select: {
|
|
209
548
|
perspective: "perspective",
|
|
210
|
-
status: "status"
|
|
549
|
+
status: "status",
|
|
550
|
+
tasks: "tasks"
|
|
211
551
|
}
|
|
212
552
|
},
|
|
213
553
|
title: "AILF Evaluation Request",
|
|
@@ -1218,7 +1558,7 @@ import { ALL_FIELDS_GROUP as ALL_FIELDS_GROUP5, defineField as defineField5, def
|
|
|
1218
1558
|
// src/components/AssertionInput.tsx
|
|
1219
1559
|
import { HelpCircleIcon } from "@sanity/icons";
|
|
1220
1560
|
import { Box as Box2, Card, Flex, Stack as Stack2, Text as Text2 } from "@sanity/ui";
|
|
1221
|
-
import { useCallback as
|
|
1561
|
+
import { useCallback as useCallback3 } from "react";
|
|
1222
1562
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1223
1563
|
var TYPE_HELP = {
|
|
1224
1564
|
"llm-rubric": {
|
|
@@ -1372,7 +1712,7 @@ function AssertionInput(props) {
|
|
|
1372
1712
|
const templateHelp = selectedTemplate ? TEMPLATE_HELP[selectedTemplate] : null;
|
|
1373
1713
|
const isMonospace = selectedType ? MONOSPACE_TYPES.has(selectedType) : false;
|
|
1374
1714
|
const { renderField: parentRenderField } = props;
|
|
1375
|
-
const renderField =
|
|
1715
|
+
const renderField = useCallback3(
|
|
1376
1716
|
(fieldProps) => {
|
|
1377
1717
|
const rendered = parentRenderField(fieldProps);
|
|
1378
1718
|
if (fieldProps.name === "type" && typeHelp) {
|
|
@@ -1400,7 +1740,7 @@ function AssertionInput(props) {
|
|
|
1400
1740
|
// src/components/CanonicalDocInput.tsx
|
|
1401
1741
|
import { HelpCircleIcon as HelpCircleIcon2 } from "@sanity/icons";
|
|
1402
1742
|
import { Box as Box3, Card as Card2, Flex as Flex2, Stack as Stack3, Text as Text3 } from "@sanity/ui";
|
|
1403
|
-
import { useCallback as
|
|
1743
|
+
import { useCallback as useCallback4 } from "react";
|
|
1404
1744
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1405
1745
|
var REF_TYPE_HELP = {
|
|
1406
1746
|
slug: {
|
|
@@ -1423,7 +1763,7 @@ function CanonicalDocInput(props) {
|
|
|
1423
1763
|
const selectedType = typeof value?.refType === "string" ? value.refType : null;
|
|
1424
1764
|
const help = selectedType ? REF_TYPE_HELP[selectedType] : null;
|
|
1425
1765
|
const { renderField: parentRenderField } = props;
|
|
1426
|
-
const renderField =
|
|
1766
|
+
const renderField = useCallback4(
|
|
1427
1767
|
(fieldProps) => {
|
|
1428
1768
|
const rendered = parentRenderField(fieldProps);
|
|
1429
1769
|
if (fieldProps.name === "refType" && help) {
|
|
@@ -1616,7 +1956,7 @@ function OriginInput(props) {
|
|
|
1616
1956
|
// src/components/ReleasePicker.tsx
|
|
1617
1957
|
import { SearchIcon } from "@sanity/icons";
|
|
1618
1958
|
import { Autocomplete, Badge as Badge2, Card as Card4, Flex as Flex5, Stack as Stack6, Text as Text7 } from "@sanity/ui";
|
|
1619
|
-
import { useCallback as
|
|
1959
|
+
import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
1620
1960
|
import {
|
|
1621
1961
|
getReleaseIdFromReleaseDocumentId as getReleaseIdFromReleaseDocumentId2,
|
|
1622
1962
|
PatchEvent,
|
|
@@ -1662,8 +2002,8 @@ function ReleasePicker(props) {
|
|
|
1662
2002
|
});
|
|
1663
2003
|
return result;
|
|
1664
2004
|
}, [activeReleases, archivedReleases]);
|
|
1665
|
-
const hasSynced =
|
|
1666
|
-
|
|
2005
|
+
const hasSynced = useRef2(false);
|
|
2006
|
+
useEffect2(() => {
|
|
1667
2007
|
if (hasSynced.current || !value || options.length === 0) return;
|
|
1668
2008
|
const match = options.find((o) => o.value === value);
|
|
1669
2009
|
if (match && match.payload.title !== value) {
|
|
@@ -1671,7 +2011,7 @@ function ReleasePicker(props) {
|
|
|
1671
2011
|
formOnChange(PatchEvent.from(set(match.payload.title, titlePath)));
|
|
1672
2012
|
}
|
|
1673
2013
|
}, [value, options, formOnChange, titlePath]);
|
|
1674
|
-
const handleChange =
|
|
2014
|
+
const handleChange = useCallback5(
|
|
1675
2015
|
(newValue) => {
|
|
1676
2016
|
if (newValue) {
|
|
1677
2017
|
onChange(set(newValue));
|
|
@@ -2116,7 +2456,7 @@ var taskSchema = defineType5({
|
|
|
2116
2456
|
// Execution controls
|
|
2117
2457
|
// -----------------------------------------------------------------------
|
|
2118
2458
|
defineField5({
|
|
2119
|
-
description: "Controls when and how this task runs in the pipeline. Tasks without execution controls use defaults: enabled, blocking, no filters, no threshold.",
|
|
2459
|
+
description: "Controls when and how this task runs in the pipeline. Tasks without execution controls use defaults: enabled, non-blocking, no filters, no threshold.",
|
|
2120
2460
|
group: ["optional", "all-fields"],
|
|
2121
2461
|
fields: [
|
|
2122
2462
|
defineField5({
|
|
@@ -2127,8 +2467,8 @@ var taskSchema = defineType5({
|
|
|
2127
2467
|
type: "boolean"
|
|
2128
2468
|
}),
|
|
2129
2469
|
defineField5({
|
|
2130
|
-
description: "Block PR merge on failure (default:
|
|
2131
|
-
initialValue:
|
|
2470
|
+
description: "Block PR merge on failure (default: false). Note: not currently enforced \u2014 the PR check workflow reports scores but does not gate merges based on this flag.",
|
|
2471
|
+
initialValue: false,
|
|
2132
2472
|
name: "blocking",
|
|
2133
2473
|
title: "Blocking",
|
|
2134
2474
|
type: "boolean"
|
|
@@ -2448,8 +2788,8 @@ import {
|
|
|
2448
2788
|
TabPanel as TabPanel2,
|
|
2449
2789
|
Text as Text34
|
|
2450
2790
|
} from "@sanity/ui";
|
|
2451
|
-
import { useCallback as
|
|
2452
|
-
import { useClient as
|
|
2791
|
+
import { useCallback as useCallback15, useEffect as useEffect10, useState as useState12 } from "react";
|
|
2792
|
+
import { useClient as useClient9 } from "sanity";
|
|
2453
2793
|
import { useRouter } from "sanity/router";
|
|
2454
2794
|
|
|
2455
2795
|
// src/queries.ts
|
|
@@ -2694,8 +3034,8 @@ function filterSourceClause(param) {
|
|
|
2694
3034
|
|
|
2695
3035
|
// src/components/ComparisonView.tsx
|
|
2696
3036
|
import { Badge as Badge3, Box as Box7, Card as Card6, Flex as Flex7, Grid, Select, Stack as Stack8, Text as Text11 } from "@sanity/ui";
|
|
2697
|
-
import { useCallback as
|
|
2698
|
-
import { useClient as
|
|
3037
|
+
import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
3038
|
+
import { useClient as useClient3 } from "sanity";
|
|
2699
3039
|
|
|
2700
3040
|
// src/glossary.ts
|
|
2701
3041
|
var GLOSSARY = {
|
|
@@ -2753,32 +3093,6 @@ var GLOSSARY = {
|
|
|
2753
3093
|
dimDocCoverage: "Change in doc coverage between runs. Positive means the docs are providing more useful information."
|
|
2754
3094
|
};
|
|
2755
3095
|
|
|
2756
|
-
// ../shared/dist/score-grades.js
|
|
2757
|
-
var GRADE_BOUNDARIES = {
|
|
2758
|
-
good: 80,
|
|
2759
|
-
warning: 70,
|
|
2760
|
-
critical: 50
|
|
2761
|
-
};
|
|
2762
|
-
function scoreGrade(score) {
|
|
2763
|
-
if (score >= GRADE_BOUNDARIES.good)
|
|
2764
|
-
return "good";
|
|
2765
|
-
if (score >= GRADE_BOUNDARIES.warning)
|
|
2766
|
-
return "warning";
|
|
2767
|
-
if (score >= GRADE_BOUNDARIES.critical)
|
|
2768
|
-
return "needs-work";
|
|
2769
|
-
return "critical";
|
|
2770
|
-
}
|
|
2771
|
-
|
|
2772
|
-
// ../shared/dist/noise-threshold.js
|
|
2773
|
-
var NOISE_THRESHOLD = 2;
|
|
2774
|
-
|
|
2775
|
-
// ../shared/dist/dimension-names.js
|
|
2776
|
-
var DIMENSION_LABELS_KEBAB = {
|
|
2777
|
-
"code-correctness": "Code Correctness",
|
|
2778
|
-
"doc-coverage": "Doc Coverage",
|
|
2779
|
-
"task-completion": "Task Completion"
|
|
2780
|
-
};
|
|
2781
|
-
|
|
2782
3096
|
// src/lib/comparison.ts
|
|
2783
3097
|
function scoreMap(summary) {
|
|
2784
3098
|
return new Map(summary.scores.map((s) => [s.feature, s]));
|
|
@@ -2857,46 +3171,6 @@ function computeDimensionDeltas(baseline, experiment) {
|
|
|
2857
3171
|
});
|
|
2858
3172
|
}
|
|
2859
3173
|
|
|
2860
|
-
// src/types.ts
|
|
2861
|
-
function formatPercent(n) {
|
|
2862
|
-
if (n == null) return "\u2014";
|
|
2863
|
-
return `${(n * 100).toFixed(0)}%`;
|
|
2864
|
-
}
|
|
2865
|
-
function formatRelativeTime(iso) {
|
|
2866
|
-
const diff = Date.now() - new Date(iso).getTime();
|
|
2867
|
-
const minutes = Math.floor(diff / 6e4);
|
|
2868
|
-
if (minutes < 1) return "just now";
|
|
2869
|
-
if (minutes === 1) return "1 minute ago";
|
|
2870
|
-
if (minutes < 60) return `${minutes} minutes ago`;
|
|
2871
|
-
const hours = Math.floor(minutes / 60);
|
|
2872
|
-
if (hours === 1) return "1 hour ago";
|
|
2873
|
-
if (hours < 24) return `${hours} hours ago`;
|
|
2874
|
-
const days = Math.floor(hours / 24);
|
|
2875
|
-
if (days === 1) return "yesterday";
|
|
2876
|
-
if (days < 7) return `${days} days ago`;
|
|
2877
|
-
const weeks = Math.floor(days / 7);
|
|
2878
|
-
if (weeks === 1) return "1 week ago";
|
|
2879
|
-
if (weeks < 5) return `${weeks} weeks ago`;
|
|
2880
|
-
const months = Math.floor(days / 30);
|
|
2881
|
-
if (months === 1) return "1 month ago";
|
|
2882
|
-
if (months < 12) return `${months} months ago`;
|
|
2883
|
-
const years = Math.floor(days / 365);
|
|
2884
|
-
if (years === 1) return "1 year ago";
|
|
2885
|
-
return `${years} years ago`;
|
|
2886
|
-
}
|
|
2887
|
-
function formatDelta(n) {
|
|
2888
|
-
if (n > 0) return `+${n.toFixed(1)}`;
|
|
2889
|
-
if (n < 0) return n.toFixed(1);
|
|
2890
|
-
return "0";
|
|
2891
|
-
}
|
|
2892
|
-
function formatDuration(ms) {
|
|
2893
|
-
if (ms < 1e3) return `${ms}ms`;
|
|
2894
|
-
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
2895
|
-
const min = Math.floor(ms / 6e4);
|
|
2896
|
-
const sec = Math.round(ms % 6e4 / 1e3);
|
|
2897
|
-
return `${min}m ${sec}s`;
|
|
2898
|
-
}
|
|
2899
|
-
|
|
2900
3174
|
// src/components/PageBlurb.tsx
|
|
2901
3175
|
import { Card as Card5, Stack as Stack7, Text as Text8 } from "@sanity/ui";
|
|
2902
3176
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
@@ -2949,23 +3223,23 @@ function LoadingState({ message = "Loading\u2026" }) {
|
|
|
2949
3223
|
// src/components/ComparisonView.tsx
|
|
2950
3224
|
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2951
3225
|
function ComparisonView() {
|
|
2952
|
-
const client =
|
|
2953
|
-
const [baselineId, setBaselineId] =
|
|
2954
|
-
const [baselineSummary, setBaselineSummary] =
|
|
3226
|
+
const client = useClient3({ apiVersion: API_VERSION });
|
|
3227
|
+
const [baselineId, setBaselineId] = useState3(null);
|
|
3228
|
+
const [baselineSummary, setBaselineSummary] = useState3(
|
|
2955
3229
|
null
|
|
2956
3230
|
);
|
|
2957
|
-
const [experimentId, setExperimentId] =
|
|
2958
|
-
const [experimentSummary, setExperimentSummary] =
|
|
2959
|
-
const [loading, setLoading] =
|
|
2960
|
-
const [reports, setReports] =
|
|
2961
|
-
|
|
3231
|
+
const [experimentId, setExperimentId] = useState3(null);
|
|
3232
|
+
const [experimentSummary, setExperimentSummary] = useState3(null);
|
|
3233
|
+
const [loading, setLoading] = useState3(false);
|
|
3234
|
+
const [reports, setReports] = useState3([]);
|
|
3235
|
+
useEffect3(() => {
|
|
2962
3236
|
client.fetch(latestReportsQuery, {
|
|
2963
3237
|
limit: 50,
|
|
2964
3238
|
mode: null,
|
|
2965
3239
|
source: null
|
|
2966
3240
|
}).then((data) => setReports(data ?? [])).catch(() => setReports([]));
|
|
2967
3241
|
}, [client]);
|
|
2968
|
-
|
|
3242
|
+
useEffect3(() => {
|
|
2969
3243
|
if (!baselineId || !experimentId) {
|
|
2970
3244
|
setBaselineSummary(null);
|
|
2971
3245
|
setExperimentSummary(null);
|
|
@@ -3015,11 +3289,11 @@ function ComparisonView() {
|
|
|
3015
3289
|
const e = experimentSummary.overall.avgScore;
|
|
3016
3290
|
return { baseline: b, delta: e - b, experiment: e };
|
|
3017
3291
|
}, [baselineSummary, experimentSummary]);
|
|
3018
|
-
const onBaseline =
|
|
3292
|
+
const onBaseline = useCallback6(
|
|
3019
3293
|
(e) => setBaselineId(e.currentTarget.value || null),
|
|
3020
3294
|
[]
|
|
3021
3295
|
);
|
|
3022
|
-
const onExperiment =
|
|
3296
|
+
const onExperiment = useCallback6(
|
|
3023
3297
|
(e) => setExperimentId(e.currentTarget.value || null),
|
|
3024
3298
|
[]
|
|
3025
3299
|
);
|
|
@@ -3192,14 +3466,14 @@ import {
|
|
|
3192
3466
|
Stack as Stack13,
|
|
3193
3467
|
Text as Text21
|
|
3194
3468
|
} from "@sanity/ui";
|
|
3195
|
-
import { useCallback as
|
|
3196
|
-
import { useClient as
|
|
3469
|
+
import { useCallback as useCallback12, useEffect as useEffect7, useMemo as useMemo5, useState as useState7 } from "react";
|
|
3470
|
+
import { useClient as useClient6 } from "sanity";
|
|
3197
3471
|
|
|
3198
3472
|
// src/components/content-filters/DocumentFilter.tsx
|
|
3199
3473
|
import { SearchIcon as SearchIcon2 } from "@sanity/icons";
|
|
3200
3474
|
import { Autocomplete as Autocomplete2, Badge as Badge4, Card as Card7, Flex as Flex8, Stack as Stack9, Text as Text12 } from "@sanity/ui";
|
|
3201
|
-
import { useCallback as
|
|
3202
|
-
import { useClient as
|
|
3475
|
+
import { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
|
|
3476
|
+
import { useClient as useClient4 } from "sanity";
|
|
3203
3477
|
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3204
3478
|
var SEARCH_DEBOUNCE_MS = 300;
|
|
3205
3479
|
function DocumentFilter({
|
|
@@ -3207,16 +3481,16 @@ function DocumentFilter({
|
|
|
3207
3481
|
onChange,
|
|
3208
3482
|
onPerspectiveHint
|
|
3209
3483
|
}) {
|
|
3210
|
-
const client =
|
|
3211
|
-
const [options, setOptions] =
|
|
3212
|
-
const [loading, setLoading] =
|
|
3213
|
-
const timer =
|
|
3214
|
-
|
|
3484
|
+
const client = useClient4({ apiVersion: API_VERSION });
|
|
3485
|
+
const [options, setOptions] = useState4([]);
|
|
3486
|
+
const [loading, setLoading] = useState4(false);
|
|
3487
|
+
const timer = useRef3(null);
|
|
3488
|
+
useEffect4(() => {
|
|
3215
3489
|
return () => {
|
|
3216
3490
|
if (timer.current) clearTimeout(timer.current);
|
|
3217
3491
|
};
|
|
3218
3492
|
}, []);
|
|
3219
|
-
const handleQueryChange =
|
|
3493
|
+
const handleQueryChange = useCallback7(
|
|
3220
3494
|
(query) => {
|
|
3221
3495
|
if (timer.current) clearTimeout(timer.current);
|
|
3222
3496
|
const trimmed = (query ?? "").trim();
|
|
@@ -3260,7 +3534,7 @@ function DocumentFilter({
|
|
|
3260
3534
|
},
|
|
3261
3535
|
[client]
|
|
3262
3536
|
);
|
|
3263
|
-
const handleSelect =
|
|
3537
|
+
const handleSelect = useCallback7(
|
|
3264
3538
|
(selected) => {
|
|
3265
3539
|
const option = options.find((o) => o.value === selected);
|
|
3266
3540
|
const slug = option?.payload.slug ?? selected;
|
|
@@ -3271,7 +3545,7 @@ function DocumentFilter({
|
|
|
3271
3545
|
},
|
|
3272
3546
|
[options, onChange, onPerspectiveHint]
|
|
3273
3547
|
);
|
|
3274
|
-
const renderOption =
|
|
3548
|
+
const renderOption = useCallback7((option) => {
|
|
3275
3549
|
const { provenance, releaseId } = option.payload;
|
|
3276
3550
|
const badgeTone = provenance === "published" ? "positive" : provenance === "release" ? "primary" : "caution";
|
|
3277
3551
|
const badgeLabel = provenance === "published" ? "Published" : provenance === "release" ? releaseId ?? "Release" : "Draft";
|
|
@@ -3283,7 +3557,7 @@ function DocumentFilter({
|
|
|
3283
3557
|
/* @__PURE__ */ jsx13(Badge4, { fontSize: 0, tone: badgeTone, children: badgeLabel })
|
|
3284
3558
|
] }) });
|
|
3285
3559
|
}, []);
|
|
3286
|
-
const renderValue =
|
|
3560
|
+
const renderValue = useCallback7((_value, option) => {
|
|
3287
3561
|
if (option?.payload.title) {
|
|
3288
3562
|
return `${option.payload.title} (${option.payload.slug})`;
|
|
3289
3563
|
}
|
|
@@ -3321,20 +3595,20 @@ function classifyDocId(id) {
|
|
|
3321
3595
|
// src/components/content-filters/PerspectiveFilter.tsx
|
|
3322
3596
|
import { SearchIcon as SearchIcon3 } from "@sanity/icons";
|
|
3323
3597
|
import { Autocomplete as Autocomplete3, Badge as Badge5, Card as Card8, Flex as Flex9, Stack as Stack10, Text as Text13 } from "@sanity/ui";
|
|
3324
|
-
import { useEffect as
|
|
3598
|
+
import { useEffect as useEffect5, useMemo as useMemo4, useState as useState5 } from "react";
|
|
3325
3599
|
import {
|
|
3326
3600
|
getReleaseIdFromReleaseDocumentId as getReleaseIdFromReleaseDocumentId3,
|
|
3327
3601
|
useActiveReleases as useActiveReleases3,
|
|
3328
3602
|
useArchivedReleases as useArchivedReleases3,
|
|
3329
|
-
useClient as
|
|
3603
|
+
useClient as useClient5
|
|
3330
3604
|
} from "sanity";
|
|
3331
3605
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3332
3606
|
function PerspectiveFilter({ value, onChange }) {
|
|
3333
|
-
const client =
|
|
3334
|
-
const [reportPerspectives, setReportPerspectives] =
|
|
3607
|
+
const client = useClient5({ apiVersion: API_VERSION });
|
|
3608
|
+
const [reportPerspectives, setReportPerspectives] = useState5([]);
|
|
3335
3609
|
const { data: activeReleases } = useActiveReleases3();
|
|
3336
3610
|
const { data: archivedReleases } = useArchivedReleases3();
|
|
3337
|
-
|
|
3611
|
+
useEffect5(() => {
|
|
3338
3612
|
client.fetch(distinctPerspectivesQuery).then(
|
|
3339
3613
|
(data) => setReportPerspectives((data ?? []).filter(Boolean).sort())
|
|
3340
3614
|
).catch(() => setReportPerspectives([]));
|
|
@@ -3402,7 +3676,7 @@ function PerspectiveFilter({ value, onChange }) {
|
|
|
3402
3676
|
|
|
3403
3677
|
// src/components/report-card/ReportCard.tsx
|
|
3404
3678
|
import { Badge as Badge10, Card as Card9, Flex as Flex13, Text as Text17 } from "@sanity/ui";
|
|
3405
|
-
import { useCallback as
|
|
3679
|
+
import { useCallback as useCallback8 } from "react";
|
|
3406
3680
|
|
|
3407
3681
|
// src/components/primitives/DeltaIndicator.tsx
|
|
3408
3682
|
import { Text as Text14 } from "@sanity/ui";
|
|
@@ -3609,7 +3883,7 @@ function StatusBadges({ regressed, improved }) {
|
|
|
3609
3883
|
// src/components/report-card/ReportCard.tsx
|
|
3610
3884
|
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3611
3885
|
function ReportCard({ data, onSelectReport }) {
|
|
3612
|
-
const handleClick =
|
|
3886
|
+
const handleClick = useCallback8(() => {
|
|
3613
3887
|
onSelectReport(data.reportId);
|
|
3614
3888
|
}, [data.reportId, onSelectReport]);
|
|
3615
3889
|
return /* @__PURE__ */ jsx20(
|
|
@@ -3649,10 +3923,10 @@ function ReportCard({ data, onSelectReport }) {
|
|
|
3649
3923
|
import { SearchIcon as SearchIcon4 } from "@sanity/icons";
|
|
3650
3924
|
import { Card as Card11, Flex as Flex16, Text as Text20 } from "@sanity/ui";
|
|
3651
3925
|
import {
|
|
3652
|
-
useCallback as
|
|
3653
|
-
useEffect as
|
|
3654
|
-
useRef as
|
|
3655
|
-
useState as
|
|
3926
|
+
useCallback as useCallback11,
|
|
3927
|
+
useEffect as useEffect6,
|
|
3928
|
+
useRef as useRef4,
|
|
3929
|
+
useState as useState6
|
|
3656
3930
|
} from "react";
|
|
3657
3931
|
|
|
3658
3932
|
// src/components/search-bar/types.ts
|
|
@@ -3793,12 +4067,12 @@ function filterAndExclude(values, query, dim, activeTokens) {
|
|
|
3793
4067
|
// src/components/search-bar/FilterBadge.tsx
|
|
3794
4068
|
import { CloseIcon } from "@sanity/icons";
|
|
3795
4069
|
import { Badge as Badge11, Flex as Flex14, Text as Text18 } from "@sanity/ui";
|
|
3796
|
-
import { useCallback as
|
|
4070
|
+
import { useCallback as useCallback9 } from "react";
|
|
3797
4071
|
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3798
4072
|
function FilterBadge({ token, onRemove }) {
|
|
3799
4073
|
const dim = DIMENSIONS.find((d) => d.key === token.dimension);
|
|
3800
4074
|
const tone = dim?.tone ?? "default";
|
|
3801
|
-
const handleRemove =
|
|
4075
|
+
const handleRemove = useCallback9(
|
|
3802
4076
|
(e) => {
|
|
3803
4077
|
e.stopPropagation();
|
|
3804
4078
|
onRemove(token.id);
|
|
@@ -3838,7 +4112,7 @@ function FilterBadge({ token, onRemove }) {
|
|
|
3838
4112
|
|
|
3839
4113
|
// src/components/search-bar/SuggestionList.tsx
|
|
3840
4114
|
import { Badge as Badge12, Card as Card10, Flex as Flex15, Stack as Stack12, Text as Text19 } from "@sanity/ui";
|
|
3841
|
-
import { useCallback as
|
|
4115
|
+
import { useCallback as useCallback10 } from "react";
|
|
3842
4116
|
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3843
4117
|
function SuggestionList({
|
|
3844
4118
|
suggestions,
|
|
@@ -3902,7 +4176,7 @@ function SuggestionItem({
|
|
|
3902
4176
|
const dim = DIMENSIONS.find((d) => d.key === suggestion.dimension);
|
|
3903
4177
|
const tone = dim?.tone ?? "default";
|
|
3904
4178
|
const isHint = suggestion.category === "Filters";
|
|
3905
|
-
const handleClick =
|
|
4179
|
+
const handleClick = useCallback10(() => {
|
|
3906
4180
|
onSelect(suggestion);
|
|
3907
4181
|
}, [onSelect, suggestion]);
|
|
3908
4182
|
return /* @__PURE__ */ jsx22(
|
|
@@ -3940,11 +4214,11 @@ function SearchBar({
|
|
|
3940
4214
|
onTokenAdd,
|
|
3941
4215
|
onTokenRemove
|
|
3942
4216
|
}) {
|
|
3943
|
-
const [focused, setFocused] =
|
|
3944
|
-
const [activeIndex, setActiveIndex] =
|
|
3945
|
-
const inputRef =
|
|
3946
|
-
const blurTimerRef =
|
|
3947
|
-
|
|
4217
|
+
const [focused, setFocused] = useState6(false);
|
|
4218
|
+
const [activeIndex, setActiveIndex] = useState6(-1);
|
|
4219
|
+
const inputRef = useRef4(null);
|
|
4220
|
+
const blurTimerRef = useRef4(null);
|
|
4221
|
+
useEffect6(() => {
|
|
3948
4222
|
return () => {
|
|
3949
4223
|
if (blurTimerRef.current) {
|
|
3950
4224
|
clearTimeout(blurTimerRef.current);
|
|
@@ -3952,10 +4226,10 @@ function SearchBar({
|
|
|
3952
4226
|
};
|
|
3953
4227
|
}, []);
|
|
3954
4228
|
const suggestions = focused ? computeSuggestions({ query, activeTokens: tokens, models, areas }) : [];
|
|
3955
|
-
|
|
4229
|
+
useEffect6(() => {
|
|
3956
4230
|
setActiveIndex(-1);
|
|
3957
4231
|
}, [query, tokens.length]);
|
|
3958
|
-
const handleTokenRemove =
|
|
4232
|
+
const handleTokenRemove = useCallback11(
|
|
3959
4233
|
(id) => {
|
|
3960
4234
|
onTokenRemove(id);
|
|
3961
4235
|
requestAnimationFrame(() => {
|
|
@@ -3964,7 +4238,7 @@ function SearchBar({
|
|
|
3964
4238
|
},
|
|
3965
4239
|
[onTokenRemove]
|
|
3966
4240
|
);
|
|
3967
|
-
const handleSuggestionSelect =
|
|
4241
|
+
const handleSuggestionSelect = useCallback11(
|
|
3968
4242
|
(suggestion) => {
|
|
3969
4243
|
if (suggestion.category === "Filters") {
|
|
3970
4244
|
onQueryChange(suggestion.value);
|
|
@@ -3983,7 +4257,7 @@ function SearchBar({
|
|
|
3983
4257
|
},
|
|
3984
4258
|
[onTokenAdd, onQueryChange]
|
|
3985
4259
|
);
|
|
3986
|
-
const handleKeyDown =
|
|
4260
|
+
const handleKeyDown = useCallback11(
|
|
3987
4261
|
(e) => {
|
|
3988
4262
|
if (e.key === "ArrowDown") {
|
|
3989
4263
|
e.preventDefault();
|
|
@@ -4011,27 +4285,27 @@ function SearchBar({
|
|
|
4011
4285
|
handleSuggestionSelect
|
|
4012
4286
|
]
|
|
4013
4287
|
);
|
|
4014
|
-
const handleInputChange =
|
|
4288
|
+
const handleInputChange = useCallback11(
|
|
4015
4289
|
(e) => {
|
|
4016
4290
|
const value = e.target.value;
|
|
4017
4291
|
onQueryChange(value);
|
|
4018
4292
|
},
|
|
4019
4293
|
[onQueryChange]
|
|
4020
4294
|
);
|
|
4021
|
-
const handleBlur =
|
|
4295
|
+
const handleBlur = useCallback11(() => {
|
|
4022
4296
|
blurTimerRef.current = setTimeout(() => {
|
|
4023
4297
|
blurTimerRef.current = null;
|
|
4024
4298
|
setFocused(false);
|
|
4025
4299
|
}, 200);
|
|
4026
4300
|
}, []);
|
|
4027
|
-
const handleFocus =
|
|
4301
|
+
const handleFocus = useCallback11(() => {
|
|
4028
4302
|
if (blurTimerRef.current) {
|
|
4029
4303
|
clearTimeout(blurTimerRef.current);
|
|
4030
4304
|
blurTimerRef.current = null;
|
|
4031
4305
|
}
|
|
4032
4306
|
setFocused(true);
|
|
4033
4307
|
}, []);
|
|
4034
|
-
const handleBarClick =
|
|
4308
|
+
const handleBarClick = useCallback11(() => {
|
|
4035
4309
|
inputRef.current?.focus();
|
|
4036
4310
|
}, []);
|
|
4037
4311
|
return /* @__PURE__ */ jsxs20("div", { style: { position: "relative" }, children: [
|
|
@@ -4104,22 +4378,22 @@ function LatestReports({
|
|
|
4104
4378
|
pageSize = 20,
|
|
4105
4379
|
source = null
|
|
4106
4380
|
}) {
|
|
4107
|
-
const client =
|
|
4108
|
-
const [initialLoading, setInitialLoading] =
|
|
4109
|
-
const [loadingMore, setLoadingMore] =
|
|
4110
|
-
const [reports, setReports] =
|
|
4111
|
-
const [hasMore, setHasMore] =
|
|
4112
|
-
const [searchQuery, setSearchQuery] =
|
|
4113
|
-
const [filterTokens, setFilterTokens] =
|
|
4114
|
-
const [documentSlug, setDocumentSlug] =
|
|
4115
|
-
const [perspective, setPerspective] =
|
|
4116
|
-
const [sort, setSort] =
|
|
4381
|
+
const client = useClient6({ apiVersion: API_VERSION });
|
|
4382
|
+
const [initialLoading, setInitialLoading] = useState7(true);
|
|
4383
|
+
const [loadingMore, setLoadingMore] = useState7(false);
|
|
4384
|
+
const [reports, setReports] = useState7([]);
|
|
4385
|
+
const [hasMore, setHasMore] = useState7(true);
|
|
4386
|
+
const [searchQuery, setSearchQuery] = useState7("");
|
|
4387
|
+
const [filterTokens, setFilterTokens] = useState7([]);
|
|
4388
|
+
const [documentSlug, setDocumentSlug] = useState7("");
|
|
4389
|
+
const [perspective, setPerspective] = useState7("");
|
|
4390
|
+
const [sort, setSort] = useState7({
|
|
4117
4391
|
direction: "desc",
|
|
4118
4392
|
field: "date"
|
|
4119
4393
|
});
|
|
4120
|
-
const [availableModels, setAvailableModels] =
|
|
4121
|
-
const [availableAreas, setAvailableAreas] =
|
|
4122
|
-
|
|
4394
|
+
const [availableModels, setAvailableModels] = useState7([]);
|
|
4395
|
+
const [availableAreas, setAvailableAreas] = useState7([]);
|
|
4396
|
+
useEffect7(() => {
|
|
4123
4397
|
setInitialLoading(true);
|
|
4124
4398
|
setHasMore(true);
|
|
4125
4399
|
client.fetch(latestReportsQuery, {
|
|
@@ -4137,7 +4411,7 @@ function LatestReports({
|
|
|
4137
4411
|
setInitialLoading(false);
|
|
4138
4412
|
});
|
|
4139
4413
|
}, [client, pageSize, mode, source]);
|
|
4140
|
-
const handleLoadMore =
|
|
4414
|
+
const handleLoadMore = useCallback12(() => {
|
|
4141
4415
|
if (loadingMore || !hasMore) return;
|
|
4142
4416
|
setLoadingMore(true);
|
|
4143
4417
|
const nextLimit = reports.length + pageSize;
|
|
@@ -4154,7 +4428,7 @@ function LatestReports({
|
|
|
4154
4428
|
setLoadingMore(false);
|
|
4155
4429
|
});
|
|
4156
4430
|
}, [client, hasMore, loadingMore, mode, pageSize, reports.length, source]);
|
|
4157
|
-
|
|
4431
|
+
useEffect7(() => {
|
|
4158
4432
|
client.fetch(distinctModelsQuery).then((data) => setAvailableModels((data ?? []).sort())).catch(() => setAvailableModels([]));
|
|
4159
4433
|
client.fetch(distinctAreasQuery).then((data) => setAvailableAreas((data ?? []).sort())).catch(() => setAvailableAreas([]));
|
|
4160
4434
|
}, [client]);
|
|
@@ -4238,7 +4512,7 @@ function LatestReports({
|
|
|
4238
4512
|
});
|
|
4239
4513
|
return result;
|
|
4240
4514
|
}, [reports, searchQuery, activeFilters, documentSlug, perspective, sort]);
|
|
4241
|
-
const handleTokenAdd =
|
|
4515
|
+
const handleTokenAdd = useCallback12((token) => {
|
|
4242
4516
|
setFilterTokens((prev) => {
|
|
4243
4517
|
const dim = token.dimension;
|
|
4244
4518
|
const isMulti = dim === "area";
|
|
@@ -4248,22 +4522,22 @@ function LatestReports({
|
|
|
4248
4522
|
return [...prev, token];
|
|
4249
4523
|
});
|
|
4250
4524
|
}, []);
|
|
4251
|
-
const handleTokenRemove =
|
|
4525
|
+
const handleTokenRemove = useCallback12((id) => {
|
|
4252
4526
|
setFilterTokens((prev) => prev.filter((t) => t.id !== id));
|
|
4253
4527
|
}, []);
|
|
4254
|
-
const toggleSortDirection =
|
|
4528
|
+
const toggleSortDirection = useCallback12(() => {
|
|
4255
4529
|
setSort((prev) => ({
|
|
4256
4530
|
...prev,
|
|
4257
4531
|
direction: prev.direction === "asc" ? "desc" : "asc"
|
|
4258
4532
|
}));
|
|
4259
4533
|
}, []);
|
|
4260
|
-
const handleSortFieldChange =
|
|
4534
|
+
const handleSortFieldChange = useCallback12((field) => {
|
|
4261
4535
|
setSort(
|
|
4262
4536
|
(prev) => prev.field === field ? { ...prev, direction: prev.direction === "asc" ? "desc" : "asc" } : { direction: "desc", field }
|
|
4263
4537
|
);
|
|
4264
4538
|
}, []);
|
|
4265
4539
|
const hasActiveFilters = searchQuery.trim() !== "" || filterTokens.length > 0 || documentSlug.trim() !== "" || perspective.trim() !== "";
|
|
4266
|
-
const handleClearFilters =
|
|
4540
|
+
const handleClearFilters = useCallback12(() => {
|
|
4267
4541
|
setSearchQuery("");
|
|
4268
4542
|
setFilterTokens([]);
|
|
4269
4543
|
setDocumentSlug("");
|
|
@@ -4471,15 +4745,15 @@ import {
|
|
|
4471
4745
|
Tooltip as Tooltip9
|
|
4472
4746
|
} from "@sanity/ui";
|
|
4473
4747
|
import {
|
|
4474
|
-
useCallback as
|
|
4475
|
-
useEffect as
|
|
4748
|
+
useCallback as useCallback13,
|
|
4749
|
+
useEffect as useEffect8,
|
|
4476
4750
|
useMemo as useMemo7,
|
|
4477
|
-
useState as
|
|
4751
|
+
useState as useState10
|
|
4478
4752
|
} from "react";
|
|
4479
|
-
import { useClient as
|
|
4753
|
+
import { useClient as useClient7 } from "sanity";
|
|
4480
4754
|
|
|
4481
4755
|
// src/components/report-detail/AgentActivitySection.tsx
|
|
4482
|
-
import { useMemo as useMemo6, useState as
|
|
4756
|
+
import { useMemo as useMemo6, useState as useState8 } from "react";
|
|
4483
4757
|
import { HelpCircleIcon as HelpCircleIcon5, SearchIcon as SearchIcon5 } from "@sanity/icons";
|
|
4484
4758
|
import {
|
|
4485
4759
|
Badge as Badge14,
|
|
@@ -4654,7 +4928,7 @@ function FeatureActivityCard({
|
|
|
4654
4928
|
] }) });
|
|
4655
4929
|
}
|
|
4656
4930
|
function SearchQueryList({ queries }) {
|
|
4657
|
-
const [filter, setFilter] =
|
|
4931
|
+
const [filter, setFilter] = useState8("");
|
|
4658
4932
|
const filtered = useMemo6(() => {
|
|
4659
4933
|
if (!filter) return queries;
|
|
4660
4934
|
const lower = filter.toLowerCase();
|
|
@@ -4958,7 +5232,7 @@ function AreaBadgeGroup({
|
|
|
4958
5232
|
}
|
|
4959
5233
|
|
|
4960
5234
|
// src/components/report-detail/JudgmentList.tsx
|
|
4961
|
-
import { useState as
|
|
5235
|
+
import { useState as useState9 } from "react";
|
|
4962
5236
|
import { HelpCircleIcon as HelpCircleIcon6 } from "@sanity/icons";
|
|
4963
5237
|
import { Badge as Badge16, Box as Box12, Card as Card18, Flex as Flex20, Stack as Stack18, Text as Text27, Tooltip as Tooltip6 } from "@sanity/ui";
|
|
4964
5238
|
|
|
@@ -5033,7 +5307,7 @@ function JudgmentList({ judgments }) {
|
|
|
5033
5307
|
] }) });
|
|
5034
5308
|
}
|
|
5035
5309
|
function JudgmentCard({ judgment }) {
|
|
5036
|
-
const [expanded, setExpanded] =
|
|
5310
|
+
const [expanded, setExpanded] = useState9(false);
|
|
5037
5311
|
const dimLabel = DIMENSION_LABELS[judgment.dimension] ?? judgment.dimension;
|
|
5038
5312
|
const sep = judgment.taskId.indexOf(" - ");
|
|
5039
5313
|
const taskName = sep > 0 ? judgment.taskId.substring(sep + 3) : judgment.taskId;
|
|
@@ -5090,7 +5364,7 @@ var editLinkStyle = {
|
|
|
5090
5364
|
function DocBadge({
|
|
5091
5365
|
doc
|
|
5092
5366
|
}) {
|
|
5093
|
-
const [hovered, setHovered] =
|
|
5367
|
+
const [hovered, setHovered] = useState9(false);
|
|
5094
5368
|
const isLinked = Boolean(doc.documentId);
|
|
5095
5369
|
const tooltipLabel = isLinked ? `Edit "${doc.title || doc.slug}"` : doc.title || doc.slug;
|
|
5096
5370
|
const badge = /* @__PURE__ */ jsx31(Badge16, { mode: "outline", tone: isLinked && hovered ? "caution" : "primary", children: doc.slug });
|
|
@@ -5672,10 +5946,10 @@ function ReportDetail({
|
|
|
5672
5946
|
onTabChange,
|
|
5673
5947
|
reportId
|
|
5674
5948
|
}) {
|
|
5675
|
-
const client =
|
|
5676
|
-
const [loading, setLoading] =
|
|
5677
|
-
const [report, setReport] =
|
|
5678
|
-
|
|
5949
|
+
const client = useClient7({ apiVersion: API_VERSION });
|
|
5950
|
+
const [loading, setLoading] = useState10(true);
|
|
5951
|
+
const [report, setReport] = useState10(null);
|
|
5952
|
+
useEffect8(() => {
|
|
5679
5953
|
let cancelled = false;
|
|
5680
5954
|
setLoading(true);
|
|
5681
5955
|
client.fetch(reportDetailQuery, { reportId }).then((data) => {
|
|
@@ -5690,7 +5964,7 @@ function ReportDetail({
|
|
|
5690
5964
|
cancelled = true;
|
|
5691
5965
|
};
|
|
5692
5966
|
}, [client, reportId]);
|
|
5693
|
-
const handleCopyReportId =
|
|
5967
|
+
const handleCopyReportId = useCallback13(() => {
|
|
5694
5968
|
if (!report) return;
|
|
5695
5969
|
navigator.clipboard.writeText(report.reportId).catch(() => {
|
|
5696
5970
|
});
|
|
@@ -5717,7 +5991,7 @@ function ReportDetail({
|
|
|
5717
5991
|
if (disabledTabs.has(parsed)) return "overview";
|
|
5718
5992
|
return tabs.some((t) => t.id === parsed) ? parsed : "overview";
|
|
5719
5993
|
}, [activeTab, disabledTabs, tabs]);
|
|
5720
|
-
const handleTabClick =
|
|
5994
|
+
const handleTabClick = useCallback13(
|
|
5721
5995
|
(tabId) => {
|
|
5722
5996
|
onTabChange(tabId === "overview" ? null : tabId);
|
|
5723
5997
|
},
|
|
@@ -5867,8 +6141,8 @@ function getDisabledTabTooltip(tabId, summary) {
|
|
|
5867
6141
|
|
|
5868
6142
|
// src/components/ScoreTimeline.tsx
|
|
5869
6143
|
import { Card as Card23, Flex as Flex25, Select as Select2, Stack as Stack24, Text as Text33 } from "@sanity/ui";
|
|
5870
|
-
import { useCallback as
|
|
5871
|
-
import { useClient as
|
|
6144
|
+
import { useCallback as useCallback14, useEffect as useEffect9, useMemo as useMemo8, useState as useState11 } from "react";
|
|
6145
|
+
import { useClient as useClient8 } from "sanity";
|
|
5872
6146
|
import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5873
6147
|
var CHART_HEIGHT = 220;
|
|
5874
6148
|
var CHART_WIDTH = 800;
|
|
@@ -5903,11 +6177,11 @@ function scoreForPoint(point, area) {
|
|
|
5903
6177
|
return match?.totalScore ?? null;
|
|
5904
6178
|
}
|
|
5905
6179
|
function ScoreTimeline({ mode = null, source = null }) {
|
|
5906
|
-
const client =
|
|
5907
|
-
const [dataPoints, setDataPoints] =
|
|
5908
|
-
const [loading, setLoading] =
|
|
5909
|
-
const [rangeDays, setRangeDays] =
|
|
5910
|
-
const [selectedArea, setSelectedArea] =
|
|
6180
|
+
const client = useClient8({ apiVersion: API_VERSION });
|
|
6181
|
+
const [dataPoints, setDataPoints] = useState11([]);
|
|
6182
|
+
const [loading, setLoading] = useState11(true);
|
|
6183
|
+
const [rangeDays, setRangeDays] = useState11(30);
|
|
6184
|
+
const [selectedArea, setSelectedArea] = useState11(null);
|
|
5911
6185
|
const areaNames = useMemo8(() => {
|
|
5912
6186
|
const names = /* @__PURE__ */ new Set();
|
|
5913
6187
|
for (const dp of dataPoints) {
|
|
@@ -5917,7 +6191,7 @@ function ScoreTimeline({ mode = null, source = null }) {
|
|
|
5917
6191
|
}
|
|
5918
6192
|
return Array.from(names).sort();
|
|
5919
6193
|
}, [dataPoints]);
|
|
5920
|
-
const fetchData =
|
|
6194
|
+
const fetchData = useCallback14(async () => {
|
|
5921
6195
|
setLoading(true);
|
|
5922
6196
|
try {
|
|
5923
6197
|
const startDate = rangeDays ? daysAgo(rangeDays) : "1970-01-01T00:00:00Z";
|
|
@@ -5932,7 +6206,7 @@ function ScoreTimeline({ mode = null, source = null }) {
|
|
|
5932
6206
|
setLoading(false);
|
|
5933
6207
|
}
|
|
5934
6208
|
}, [client, mode, rangeDays, source]);
|
|
5935
|
-
|
|
6209
|
+
useEffect9(() => {
|
|
5936
6210
|
void fetchData();
|
|
5937
6211
|
}, [fetchData]);
|
|
5938
6212
|
const chartPoints = useMemo8(() => {
|
|
@@ -5953,14 +6227,14 @@ function ScoreTimeline({ mode = null, source = null }) {
|
|
|
5953
6227
|
if (chartPoints.length === 0) return 0;
|
|
5954
6228
|
return chartPoints.reduce((sum, p) => sum + p.score, 0) / chartPoints.length;
|
|
5955
6229
|
}, [chartPoints]);
|
|
5956
|
-
const handleRangeChange =
|
|
6230
|
+
const handleRangeChange = useCallback14(
|
|
5957
6231
|
(e) => {
|
|
5958
6232
|
const val = e.currentTarget.value;
|
|
5959
6233
|
setRangeDays(val === "all" ? null : Number(val));
|
|
5960
6234
|
},
|
|
5961
6235
|
[]
|
|
5962
6236
|
);
|
|
5963
|
-
const handleAreaChange =
|
|
6237
|
+
const handleAreaChange = useCallback14(
|
|
5964
6238
|
(e) => {
|
|
5965
6239
|
const val = e.currentTarget.value;
|
|
5966
6240
|
setSelectedArea(val || null);
|
|
@@ -6093,13 +6367,13 @@ var VIEW_PARAM_MAP = {
|
|
|
6093
6367
|
timeline: "timeline"
|
|
6094
6368
|
};
|
|
6095
6369
|
function Dashboard() {
|
|
6096
|
-
const client =
|
|
6370
|
+
const client = useClient9({ apiVersion: API_VERSION });
|
|
6097
6371
|
const router = useRouter();
|
|
6098
6372
|
const routerState = router.state;
|
|
6099
6373
|
const reportId = routerState.reportId ?? null;
|
|
6100
6374
|
const isDetail = reportId !== null;
|
|
6101
6375
|
const activeTab = isDetail ? "latest" : VIEW_PARAM_MAP[routerState.view ?? ""] ?? "latest";
|
|
6102
|
-
const navigateToTab =
|
|
6376
|
+
const navigateToTab = useCallback15(
|
|
6103
6377
|
(tab) => {
|
|
6104
6378
|
if (tab === "latest") {
|
|
6105
6379
|
router.navigate({});
|
|
@@ -6109,13 +6383,13 @@ function Dashboard() {
|
|
|
6109
6383
|
},
|
|
6110
6384
|
[router]
|
|
6111
6385
|
);
|
|
6112
|
-
const handleSelectReport =
|
|
6386
|
+
const handleSelectReport = useCallback15(
|
|
6113
6387
|
(id) => {
|
|
6114
6388
|
router.navigate({ reportId: id });
|
|
6115
6389
|
},
|
|
6116
6390
|
[router]
|
|
6117
6391
|
);
|
|
6118
|
-
const handleTabChange =
|
|
6392
|
+
const handleTabChange = useCallback15(
|
|
6119
6393
|
(tab) => {
|
|
6120
6394
|
if (!routerState.reportId) return;
|
|
6121
6395
|
if (tab) {
|
|
@@ -6126,14 +6400,14 @@ function Dashboard() {
|
|
|
6126
6400
|
},
|
|
6127
6401
|
[router, routerState.reportId]
|
|
6128
6402
|
);
|
|
6129
|
-
const handleBack =
|
|
6403
|
+
const handleBack = useCallback15(() => {
|
|
6130
6404
|
router.navigate({});
|
|
6131
6405
|
}, [router]);
|
|
6132
|
-
const [source, setSource] =
|
|
6133
|
-
const [mode, setMode] =
|
|
6134
|
-
const [sources, setSources] =
|
|
6135
|
-
const [modes, setModes] =
|
|
6136
|
-
|
|
6406
|
+
const [source, setSource] = useState12(null);
|
|
6407
|
+
const [mode, setMode] = useState12(null);
|
|
6408
|
+
const [sources, setSources] = useState12([]);
|
|
6409
|
+
const [modes, setModes] = useState12([]);
|
|
6410
|
+
useEffect10(() => {
|
|
6137
6411
|
client.fetch(distinctSourcesQuery).then((data) => setSources(data ?? [])).catch(() => setSources([]));
|
|
6138
6412
|
client.fetch(distinctModesQuery).then((data) => setModes(data ?? [])).catch(() => setModes([]));
|
|
6139
6413
|
}, [client]);
|
|
@@ -6241,23 +6515,23 @@ function ailfTool(options = {}) {
|
|
|
6241
6515
|
|
|
6242
6516
|
// src/actions/RunEvaluationAction.tsx
|
|
6243
6517
|
import { BarChartIcon as BarChartIcon2 } from "@sanity/icons";
|
|
6244
|
-
import { useToast } from "@sanity/ui";
|
|
6245
|
-
import { useCallback as
|
|
6518
|
+
import { useToast as useToast2 } from "@sanity/ui";
|
|
6519
|
+
import { useCallback as useCallback16, useEffect as useEffect11, useRef as useRef5, useState as useState13 } from "react";
|
|
6246
6520
|
import {
|
|
6247
6521
|
getReleaseIdFromReleaseDocumentId as getReleaseIdFromReleaseDocumentId4,
|
|
6248
|
-
useClient as
|
|
6249
|
-
useCurrentUser,
|
|
6250
|
-
useDataset,
|
|
6251
|
-
useProjectId
|
|
6522
|
+
useClient as useClient10,
|
|
6523
|
+
useCurrentUser as useCurrentUser2,
|
|
6524
|
+
useDataset as useDataset2,
|
|
6525
|
+
useProjectId as useProjectId2
|
|
6252
6526
|
} from "sanity";
|
|
6253
6527
|
var API_VERSION2 = "2026-03-11";
|
|
6254
|
-
var
|
|
6255
|
-
var
|
|
6256
|
-
var
|
|
6257
|
-
var
|
|
6528
|
+
var EVAL_REQUEST_TYPE2 = "ailf.evalRequest";
|
|
6529
|
+
var POLL_INTERVAL_MS2 = 3e4;
|
|
6530
|
+
var MAX_POLL_MS2 = 30 * 60 * 1e3;
|
|
6531
|
+
var EVAL_REQUEST_STATUS_QUERY2 = (
|
|
6258
6532
|
/* groq */
|
|
6259
6533
|
`
|
|
6260
|
-
*[_type == "${
|
|
6534
|
+
*[_type == "${EVAL_REQUEST_TYPE2}" && _id == $id][0] {
|
|
6261
6535
|
status,
|
|
6262
6536
|
error,
|
|
6263
6537
|
reportId
|
|
@@ -6268,15 +6542,15 @@ function createRunEvaluationAction(options = {}) {
|
|
|
6268
6542
|
const { mode = "baseline" } = options;
|
|
6269
6543
|
const RunEvaluationAction = (props) => {
|
|
6270
6544
|
const { release } = props;
|
|
6271
|
-
const client =
|
|
6272
|
-
const dataset =
|
|
6273
|
-
const projectId =
|
|
6274
|
-
const currentUser =
|
|
6275
|
-
const toast =
|
|
6276
|
-
const [state, setState] =
|
|
6277
|
-
const requestedAtRef =
|
|
6545
|
+
const client = useClient10({ apiVersion: API_VERSION2 });
|
|
6546
|
+
const dataset = useDataset2();
|
|
6547
|
+
const projectId = useProjectId2();
|
|
6548
|
+
const currentUser = useCurrentUser2();
|
|
6549
|
+
const toast = useToast2();
|
|
6550
|
+
const [state, setState] = useState13({ status: "loading" });
|
|
6551
|
+
const requestedAtRef = useRef5(null);
|
|
6278
6552
|
const perspectiveId = getReleaseIdFromReleaseDocumentId4(release._id);
|
|
6279
|
-
|
|
6553
|
+
useEffect11(() => {
|
|
6280
6554
|
let cancelled = false;
|
|
6281
6555
|
client.fetch(contentImpactQuery, buildReportQueryParams(perspectiveId)).then((results) => {
|
|
6282
6556
|
if (cancelled) return;
|
|
@@ -6299,14 +6573,14 @@ function createRunEvaluationAction(options = {}) {
|
|
|
6299
6573
|
cancelled = true;
|
|
6300
6574
|
};
|
|
6301
6575
|
}, [client, perspectiveId]);
|
|
6302
|
-
|
|
6576
|
+
useEffect11(() => {
|
|
6303
6577
|
if (state.status !== "requested" && state.status !== "polling") return;
|
|
6304
6578
|
const { requestId, startedAt } = state;
|
|
6305
6579
|
if (state.status === "requested") {
|
|
6306
6580
|
setState({ requestId, startedAt, status: "polling" });
|
|
6307
6581
|
}
|
|
6308
6582
|
const interval = setInterval(async () => {
|
|
6309
|
-
if (Date.now() - startedAt >
|
|
6583
|
+
if (Date.now() - startedAt > MAX_POLL_MS2) {
|
|
6310
6584
|
clearInterval(interval);
|
|
6311
6585
|
setState({
|
|
6312
6586
|
message: "Evaluation is still running. Check the AI Literacy dashboard for results.",
|
|
@@ -6315,7 +6589,7 @@ function createRunEvaluationAction(options = {}) {
|
|
|
6315
6589
|
return;
|
|
6316
6590
|
}
|
|
6317
6591
|
try {
|
|
6318
|
-
const reqStatus = await client.fetch(
|
|
6592
|
+
const reqStatus = await client.fetch(EVAL_REQUEST_STATUS_QUERY2, {
|
|
6319
6593
|
id: requestId
|
|
6320
6594
|
});
|
|
6321
6595
|
if (reqStatus?.status === "failed") {
|
|
@@ -6346,10 +6620,10 @@ function createRunEvaluationAction(options = {}) {
|
|
|
6346
6620
|
}
|
|
6347
6621
|
} catch {
|
|
6348
6622
|
}
|
|
6349
|
-
},
|
|
6623
|
+
}, POLL_INTERVAL_MS2);
|
|
6350
6624
|
return () => clearInterval(interval);
|
|
6351
6625
|
}, [client, perspectiveId, state]);
|
|
6352
|
-
|
|
6626
|
+
useEffect11(() => {
|
|
6353
6627
|
if (state.status !== "error") return;
|
|
6354
6628
|
const timer = setTimeout(() => {
|
|
6355
6629
|
client.fetch(contentImpactQuery, buildReportQueryParams(perspectiveId)).then((results) => {
|
|
@@ -6369,13 +6643,13 @@ function createRunEvaluationAction(options = {}) {
|
|
|
6369
6643
|
}, 15e3);
|
|
6370
6644
|
return () => clearTimeout(timer);
|
|
6371
6645
|
}, [client, perspectiveId, state]);
|
|
6372
|
-
const handleRequest =
|
|
6646
|
+
const handleRequest = useCallback16(async () => {
|
|
6373
6647
|
const releaseTitle = release.metadata?.title ?? perspectiveId ?? "release";
|
|
6374
|
-
const tag = `release-${
|
|
6648
|
+
const tag = `release-${slugify2(releaseTitle)}-${dateStamp2()}`;
|
|
6375
6649
|
const now = Date.now();
|
|
6376
6650
|
try {
|
|
6377
6651
|
const doc = await client.create({
|
|
6378
|
-
_type:
|
|
6652
|
+
_type: EVAL_REQUEST_TYPE2,
|
|
6379
6653
|
dataset,
|
|
6380
6654
|
mode,
|
|
6381
6655
|
perspective: perspectiveId,
|
|
@@ -6415,15 +6689,15 @@ function createRunEvaluationAction(options = {}) {
|
|
|
6415
6689
|
return {
|
|
6416
6690
|
disabled: state.status === "loading" || state.status === "requested" || state.status === "polling",
|
|
6417
6691
|
icon: BarChartIcon2,
|
|
6418
|
-
label:
|
|
6692
|
+
label: getLabel2(state),
|
|
6419
6693
|
onHandle: handleRequest,
|
|
6420
|
-
title:
|
|
6694
|
+
title: getTitle2(state, perspectiveId)
|
|
6421
6695
|
};
|
|
6422
6696
|
};
|
|
6423
6697
|
RunEvaluationAction.displayName = "RunEvaluationAction";
|
|
6424
6698
|
return RunEvaluationAction;
|
|
6425
6699
|
}
|
|
6426
|
-
function
|
|
6700
|
+
function getLabel2(state) {
|
|
6427
6701
|
switch (state.status) {
|
|
6428
6702
|
case "loading":
|
|
6429
6703
|
return "AI Eval";
|
|
@@ -6441,7 +6715,7 @@ function getLabel(state) {
|
|
|
6441
6715
|
return "Eval Failed";
|
|
6442
6716
|
}
|
|
6443
6717
|
}
|
|
6444
|
-
function
|
|
6718
|
+
function getTitle2(state, perspectiveId) {
|
|
6445
6719
|
switch (state.status) {
|
|
6446
6720
|
case "loading":
|
|
6447
6721
|
return "Checking for existing evaluation results\u2026";
|
|
@@ -6469,10 +6743,10 @@ function buildReportQueryParams(perspectiveId) {
|
|
|
6469
6743
|
source: null
|
|
6470
6744
|
};
|
|
6471
6745
|
}
|
|
6472
|
-
function
|
|
6746
|
+
function slugify2(s) {
|
|
6473
6747
|
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
6474
6748
|
}
|
|
6475
|
-
function
|
|
6749
|
+
function dateStamp2() {
|
|
6476
6750
|
const d = /* @__PURE__ */ new Date();
|
|
6477
6751
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
6478
6752
|
}
|
|
@@ -6483,7 +6757,7 @@ var ailfPlugin = definePlugin({
|
|
|
6483
6757
|
document: {
|
|
6484
6758
|
actions: (prev, context) => {
|
|
6485
6759
|
if (context.schemaType === "ailf.task") {
|
|
6486
|
-
return [...prev, GraduateToNativeAction];
|
|
6760
|
+
return [...prev, GraduateToNativeAction, RunTaskEvaluationAction];
|
|
6487
6761
|
}
|
|
6488
6762
|
return prev;
|
|
6489
6763
|
}
|
|
@@ -6507,6 +6781,7 @@ export {
|
|
|
6507
6781
|
GraduateToNativeAction,
|
|
6508
6782
|
MirrorBanner,
|
|
6509
6783
|
ReleasePicker,
|
|
6784
|
+
RunTaskEvaluationAction,
|
|
6510
6785
|
SyncStatusBadge,
|
|
6511
6786
|
ailfPlugin,
|
|
6512
6787
|
ailfTool,
|