@bolt-foundry/gambit 0.8.5-rc.6 → 0.8.5
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/CHANGELOG.md +57 -2
- package/README.md +16 -7
- package/esm/_dnt.polyfills.d.ts +7 -7
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/_dnt.polyfills.js +14 -13
- package/esm/deps/jsr.io/@std/path/1.1.4/constants.d.ts +1 -1
- package/esm/gambit/simulator-ui/dist/bundle.js +2464 -380
- package/esm/gambit/simulator-ui/dist/bundle.js.map +4 -4
- package/esm/src/providers/codex.d.ts.map +1 -1
- package/esm/src/providers/codex.js +5 -1
- package/esm/src/providers/ollama.d.ts.map +1 -1
- package/esm/src/providers/ollama.js +57 -0
- package/esm/src/providers/openrouter.d.ts.map +1 -1
- package/esm/src/providers/openrouter.js +75 -1
- package/esm/src/server.d.ts.map +1 -1
- package/esm/src/server.js +346 -32
- package/esm/src/server_session_store.d.ts.map +1 -1
- package/esm/src/server_session_store.js +7 -4
- package/esm/src/server_types.d.ts +1 -0
- package/esm/src/server_types.d.ts.map +1 -1
- package/esm/src/server_ui_routes.d.ts.map +1 -1
- package/esm/src/server_ui_routes.js +3 -0
- package/esm/src/workspace.d.ts.map +1 -1
- package/esm/src/workspace.js +0 -2
- package/esm/src/workspace_contract.d.ts +1 -1
- package/esm/src/workspace_contract.d.ts.map +1 -1
- package/esm/src/workspace_contract.js +2 -1
- package/package.json +2 -2
- package/script/_dnt.polyfills.d.ts +7 -7
- package/script/_dnt.polyfills.d.ts.map +1 -1
- package/script/_dnt.polyfills.js +14 -13
- package/script/deps/jsr.io/@std/path/1.1.4/constants.d.ts +1 -1
- package/script/gambit/simulator-ui/dist/bundle.js +2464 -380
- package/script/gambit/simulator-ui/dist/bundle.js.map +4 -4
- package/script/src/providers/codex.d.ts.map +1 -1
- package/script/src/providers/codex.js +5 -1
- package/script/src/providers/ollama.d.ts.map +1 -1
- package/script/src/providers/ollama.js +57 -0
- package/script/src/providers/openrouter.d.ts.map +1 -1
- package/script/src/providers/openrouter.js +75 -1
- package/script/src/server.d.ts.map +1 -1
- package/script/src/server.js +346 -32
- package/script/src/server_session_store.d.ts.map +1 -1
- package/script/src/server_session_store.js +7 -4
- package/script/src/server_types.d.ts +1 -0
- package/script/src/server_types.d.ts.map +1 -1
- package/script/src/server_ui_routes.d.ts.map +1 -1
- package/script/src/server_ui_routes.js +3 -0
- package/script/src/workspace.d.ts.map +1 -1
- package/script/src/workspace.js +0 -2
- package/script/src/workspace_contract.d.ts +1 -1
- package/script/src/workspace_contract.d.ts.map +1 -1
- package/script/src/workspace_contract.js +2 -1
|
@@ -1013,17 +1013,17 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
1013
1013
|
function isValidElement(object) {
|
|
1014
1014
|
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
1015
1015
|
}
|
|
1016
|
-
var
|
|
1016
|
+
var React41 = require__(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React41.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
|
|
1017
1017
|
return null;
|
|
1018
1018
|
};
|
|
1019
|
-
|
|
1019
|
+
React41 = {
|
|
1020
1020
|
react_stack_bottom_frame: function(callStackForError) {
|
|
1021
1021
|
return callStackForError();
|
|
1022
1022
|
}
|
|
1023
1023
|
};
|
|
1024
1024
|
var specialPropKeyWarningShown;
|
|
1025
1025
|
var didWarnAboutElementRef = {};
|
|
1026
|
-
var unknownOwnerDebugStack =
|
|
1026
|
+
var unknownOwnerDebugStack = React41.react_stack_bottom_frame.bind(React41, UnknownOwner)();
|
|
1027
1027
|
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
1028
1028
|
var didWarnAboutKeySpread = {};
|
|
1029
1029
|
exports.Fragment = REACT_FRAGMENT_TYPE;
|
|
@@ -1347,7 +1347,7 @@ var require_react_dom_development = __commonJS({
|
|
|
1347
1347
|
return dispatcher;
|
|
1348
1348
|
}
|
|
1349
1349
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
1350
|
-
var
|
|
1350
|
+
var React41 = require__(), Internals = {
|
|
1351
1351
|
d: {
|
|
1352
1352
|
f: noop,
|
|
1353
1353
|
r: function() {
|
|
@@ -1363,7 +1363,7 @@ var require_react_dom_development = __commonJS({
|
|
|
1363
1363
|
},
|
|
1364
1364
|
p: 0,
|
|
1365
1365
|
findDOMNode: null
|
|
1366
|
-
}, REACT_PORTAL_TYPE = Symbol.for("react.portal"), ReactSharedInternals =
|
|
1366
|
+
}, REACT_PORTAL_TYPE = Symbol.for("react.portal"), ReactSharedInternals = React41.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
1367
1367
|
"function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills");
|
|
1368
1368
|
exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
|
|
1369
1369
|
exports.createPortal = function(children, container) {
|
|
@@ -2718,7 +2718,7 @@ var require_react_dom_client_development = __commonJS({
|
|
|
2718
2718
|
"number" === type && getActiveElement(node.ownerDocument) === node || node.defaultValue === "" + value || (node.defaultValue = "" + value);
|
|
2719
2719
|
}
|
|
2720
2720
|
function validateOptionProps(element, props) {
|
|
2721
|
-
null == props.value && ("object" === typeof props.children && null !== props.children ?
|
|
2721
|
+
null == props.value && ("object" === typeof props.children && null !== props.children ? React41.Children.forEach(props.children, function(child) {
|
|
2722
2722
|
null == child || "string" === typeof child || "number" === typeof child || "bigint" === typeof child || didWarnInvalidChild || (didWarnInvalidChild = true, console.error("Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to <option>."));
|
|
2723
2723
|
}) : null == props.dangerouslySetInnerHTML || didWarnInvalidInnerHTML || (didWarnInvalidInnerHTML = true, console.error("Pass a `value` prop if you set dangerouslyInnerHTML so React knows which value should be selected.")));
|
|
2724
2724
|
null == props.selected || didWarnSelectedSetOnOption || (console.error("Use the `defaultValue` or `value` props on <select> instead of setting `selected` on <option>."), didWarnSelectedSetOnOption = true);
|
|
@@ -13575,14 +13575,14 @@ var require_react_dom_client_development = __commonJS({
|
|
|
13575
13575
|
container[internalContainerInstanceKey] && (container._reactRootContainer ? console.error("You are calling ReactDOMClient.createRoot() on a container that was previously passed to ReactDOM.render(). This is not supported.") : console.error("You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it."));
|
|
13576
13576
|
}
|
|
13577
13577
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
13578
|
-
var Scheduler = require__2(),
|
|
13578
|
+
var Scheduler = require__2(), React41 = require__(), ReactDOM = require__3(), assign = Object.assign, REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
13579
13579
|
Symbol.for("react.scope");
|
|
13580
13580
|
var REACT_ACTIVITY_TYPE = Symbol.for("react.activity");
|
|
13581
13581
|
Symbol.for("react.legacy_hidden");
|
|
13582
13582
|
Symbol.for("react.tracing_marker");
|
|
13583
13583
|
var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");
|
|
13584
13584
|
Symbol.for("react.view_transition");
|
|
13585
|
-
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals =
|
|
13585
|
+
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, ReactSharedInternals = React41.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, ReactDOMSharedInternals = ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, NotPending = Object.freeze({
|
|
13586
13586
|
pending: false,
|
|
13587
13587
|
data: null,
|
|
13588
13588
|
method: null,
|
|
@@ -16555,7 +16555,7 @@ var require_react_dom_client_development = __commonJS({
|
|
|
16555
16555
|
}
|
|
16556
16556
|
};
|
|
16557
16557
|
(function() {
|
|
16558
|
-
var isomorphicReactPackageVersion =
|
|
16558
|
+
var isomorphicReactPackageVersion = React41.version;
|
|
16559
16559
|
if ("19.2.4" !== isomorphicReactPackageVersion) throw Error('Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + "\n - react-dom: 19.2.4\nLearn more: https://react.dev/warnings/version-mismatch"));
|
|
16560
16560
|
})();
|
|
16561
16561
|
"function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://react.dev/link/react-polyfills");
|
|
@@ -16651,8 +16651,8 @@ var require_client = __commonJS({
|
|
|
16651
16651
|
});
|
|
16652
16652
|
|
|
16653
16653
|
// simulator-ui/src/main.tsx
|
|
16654
|
-
var
|
|
16655
|
-
var
|
|
16654
|
+
var import_jsx_runtime44 = __toESM(require_jsx_runtime());
|
|
16655
|
+
var import_react41 = __toESM(require__());
|
|
16656
16656
|
var import_client = __toESM(require_client());
|
|
16657
16657
|
|
|
16658
16658
|
// simulator-ui/src/DocsPage.tsx
|
|
@@ -16675,7 +16675,7 @@ var buildWorkspacePath = (tab, workspaceId, opts) => {
|
|
|
16675
16675
|
return `${base}/${encodeURIComponent(runId)}`;
|
|
16676
16676
|
};
|
|
16677
16677
|
var parseWorkspaceRoute = (pathname) => {
|
|
16678
|
-
const match = pathname.match(/^\/workspaces\/([^/]+)\/(debug|build|test|grade)(?:\/([^/]+))?$/);
|
|
16678
|
+
const match = pathname.match(/^\/workspaces\/([^/]+)\/(debug|build|test|grade|verify)(?:\/([^/]+))?$/);
|
|
16679
16679
|
if (!match) return null;
|
|
16680
16680
|
const rawId = decodeURIComponent(match[1]);
|
|
16681
16681
|
const tab = match[2];
|
|
@@ -16714,16 +16714,19 @@ var DEFAULT_WORKSPACE_DEBUG_PATH = buildWorkspacePath("debug");
|
|
|
16714
16714
|
var DEFAULT_TEST_PATH = buildWorkspacePath("test");
|
|
16715
16715
|
var DEFAULT_BUILD_PATH = buildWorkspacePath("build");
|
|
16716
16716
|
var DEFAULT_GRADE_PATH = buildWorkspacePath("grade");
|
|
16717
|
+
var DEFAULT_VERIFY_PATH = buildWorkspacePath("verify");
|
|
16717
16718
|
var buildGradePath = (workspaceId, gradeRunId) => buildWorkspacePath("grade", workspaceId, {
|
|
16718
16719
|
runId: gradeRunId
|
|
16719
16720
|
});
|
|
16720
16721
|
var buildTestPath = (workspaceId, runId) => buildWorkspacePath("test", workspaceId, {
|
|
16721
16722
|
runId
|
|
16722
16723
|
});
|
|
16724
|
+
var buildVerifyPath = (workspaceId) => buildWorkspacePath("verify", workspaceId);
|
|
16723
16725
|
var DURABLE_STREAM_PREFIX = "/api/durable-streams/stream/";
|
|
16724
16726
|
var SIMULATOR_STREAM_ID = "gambit-simulator";
|
|
16725
16727
|
var WORKSPACE_STREAM_ID = "gambit-workspace";
|
|
16726
16728
|
var buildTabEnabled = Boolean(window.__GAMBIT_BUILD_TAB_ENABLED__);
|
|
16729
|
+
var verifyTabEnabled = Boolean(window.__GAMBIT_VERIFY_TAB_ENABLED__);
|
|
16727
16730
|
var workspaceOnboardingEnabled = Boolean(window.__GAMBIT_WORKSPACE_ONBOARDING__);
|
|
16728
16731
|
var workspaceIdFromWindow = window.__GAMBIT_WORKSPACE_ID__ ?? null;
|
|
16729
16732
|
var chatAccordionEnabled = Boolean(window.__GAMBIT_CHAT_ACCORDION_ENABLED__);
|
|
@@ -17484,6 +17487,27 @@ ${normalizedText}`;
|
|
|
17484
17487
|
});
|
|
17485
17488
|
continue;
|
|
17486
17489
|
}
|
|
17490
|
+
if (itemType.includes(":")) {
|
|
17491
|
+
const extensionData = Object.hasOwn(item, "data") ? item.data : item;
|
|
17492
|
+
const extensionText = (() => {
|
|
17493
|
+
try {
|
|
17494
|
+
return JSON.stringify(extensionData);
|
|
17495
|
+
} catch {
|
|
17496
|
+
return String(extensionData);
|
|
17497
|
+
}
|
|
17498
|
+
})();
|
|
17499
|
+
if (!extensionText || extensionText === "{}") continue;
|
|
17500
|
+
const outputIndex = typeof payload.output_index === "number" ? String(payload.output_index) : "";
|
|
17501
|
+
const actionScope2 = asString(record.actionCallId) || asString(record.runId);
|
|
17502
|
+
const baseExtensionId = asString(item.id) || asString(payload.item_id) || (outputIndex ? `extension-${outputIndex}` : itemType);
|
|
17503
|
+
upsertReasoning({
|
|
17504
|
+
reasoningId: scopedId(actionScope2, `extension:${baseExtensionId}`),
|
|
17505
|
+
text: `${itemType}: ${extensionText}`,
|
|
17506
|
+
raw: item,
|
|
17507
|
+
mode: "replace"
|
|
17508
|
+
});
|
|
17509
|
+
continue;
|
|
17510
|
+
}
|
|
17487
17511
|
if (itemType !== "reasoning") continue;
|
|
17488
17512
|
let text = "";
|
|
17489
17513
|
const summary = item.summary;
|
|
@@ -17620,7 +17644,7 @@ function deriveReasoningByAssistant(traces) {
|
|
|
17620
17644
|
}
|
|
17621
17645
|
return buckets;
|
|
17622
17646
|
}
|
|
17623
|
-
var
|
|
17647
|
+
var LEGACY_RESPOND_TOOL_NAME = "gambit_respond";
|
|
17624
17648
|
var stringifyMessageContent = (value) => {
|
|
17625
17649
|
if (value === null || value === void 0) return "";
|
|
17626
17650
|
if (typeof value === "string") return value;
|
|
@@ -17641,7 +17665,7 @@ var safeParseJson = (text) => {
|
|
|
17641
17665
|
var summarizeRespondMessage = (message) => {
|
|
17642
17666
|
if (!message || message.role !== "tool") return null;
|
|
17643
17667
|
const name = typeof message.name === "string" ? message.name : void 0;
|
|
17644
|
-
if (name !==
|
|
17668
|
+
if (name !== LEGACY_RESPOND_TOOL_NAME) return null;
|
|
17645
17669
|
const parsed = safeParseJson(typeof message.content === "string" ? message.content : "");
|
|
17646
17670
|
const payload = parsed && typeof parsed === "object" ? "payload" in parsed ? parsed.payload : parsed : void 0;
|
|
17647
17671
|
const status = typeof parsed?.status === "number" ? parsed.status : void 0;
|
|
@@ -17683,7 +17707,7 @@ function buildConversationEntries(state) {
|
|
|
17683
17707
|
message: {
|
|
17684
17708
|
role: "assistant",
|
|
17685
17709
|
content: respondSummary.displayText,
|
|
17686
|
-
name:
|
|
17710
|
+
name: LEGACY_RESPOND_TOOL_NAME
|
|
17687
17711
|
},
|
|
17688
17712
|
feedback: ref ? feedbackByRef.get(ref.id) : void 0,
|
|
17689
17713
|
respond: {
|
|
@@ -17736,6 +17760,12 @@ function normalizeAppPath(input) {
|
|
|
17736
17760
|
}
|
|
17737
17761
|
return DEFAULT_GRADE_PATH;
|
|
17738
17762
|
}
|
|
17763
|
+
if (trimmed === "/verify") {
|
|
17764
|
+
if (window.location.pathname !== DEFAULT_VERIFY_PATH) {
|
|
17765
|
+
window.history.replaceState({}, "", DEFAULT_VERIFY_PATH);
|
|
17766
|
+
}
|
|
17767
|
+
return DEFAULT_VERIFY_PATH;
|
|
17768
|
+
}
|
|
17739
17769
|
if (trimmed === "/build") {
|
|
17740
17770
|
if (window.location.pathname !== DEFAULT_BUILD_PATH) {
|
|
17741
17771
|
window.history.replaceState({}, "", DEFAULT_BUILD_PATH);
|
|
@@ -17748,7 +17778,7 @@ function normalizeAppPath(input) {
|
|
|
17748
17778
|
}
|
|
17749
17779
|
return DEFAULT_WORKSPACE_DEBUG_PATH;
|
|
17750
17780
|
}
|
|
17751
|
-
if (/^\/workspaces\/[^/]+\/(debug|build)$/.test(trimmed) || /^\/workspaces\/[^/]+\/(test|grade)(?:\/[^/]+)?$/.test(trimmed)) {
|
|
17781
|
+
if (/^\/workspaces\/[^/]+\/(debug|build|verify)$/.test(trimmed) || /^\/workspaces\/[^/]+\/(test|grade)(?:\/[^/]+)?$/.test(trimmed)) {
|
|
17752
17782
|
return trimmed;
|
|
17753
17783
|
}
|
|
17754
17784
|
if (trimmed.startsWith("/debug/workspaces/")) {
|
|
@@ -17758,7 +17788,7 @@ function normalizeAppPath(input) {
|
|
|
17758
17788
|
window.history.replaceState({}, "", next);
|
|
17759
17789
|
return next;
|
|
17760
17790
|
}
|
|
17761
|
-
if (trimmed.startsWith("/workspaces/") && !trimmed.includes("/debug") && !trimmed.includes("/test") && !trimmed.includes("/grade") && !trimmed.includes("/build") && trimmed !== DEFAULT_WORKSPACE_DEBUG_PATH) {
|
|
17791
|
+
if (trimmed.startsWith("/workspaces/") && !trimmed.includes("/debug") && !trimmed.includes("/test") && !trimmed.includes("/grade") && !trimmed.includes("/build") && !trimmed.includes("/verify") && trimmed !== DEFAULT_WORKSPACE_DEBUG_PATH) {
|
|
17762
17792
|
const remainder = trimmed.slice("/workspaces/".length);
|
|
17763
17793
|
if (remainder && remainder !== "new") {
|
|
17764
17794
|
const decoded = decodeURIComponent(remainder);
|
|
@@ -18374,6 +18404,11 @@ code:not(pre *) {
|
|
|
18374
18404
|
width: 100%;
|
|
18375
18405
|
min-height: 0;
|
|
18376
18406
|
}
|
|
18407
|
+
.verify-shell .verify-layout {
|
|
18408
|
+
grid-template-columns: 320px minmax(0, 1fr);
|
|
18409
|
+
width: 100%;
|
|
18410
|
+
min-height: 0;
|
|
18411
|
+
}
|
|
18377
18412
|
@media (max-width: 1100px) {
|
|
18378
18413
|
.calibrate-shell .calibrate-layout {
|
|
18379
18414
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -18382,6 +18417,9 @@ code:not(pre *) {
|
|
|
18382
18417
|
position: static;
|
|
18383
18418
|
max-height: none;
|
|
18384
18419
|
}
|
|
18420
|
+
.verify-shell .verify-layout {
|
|
18421
|
+
grid-template-columns: minmax(0, 1fr);
|
|
18422
|
+
}
|
|
18385
18423
|
}
|
|
18386
18424
|
.calibrate-shell .calibrate-runner {
|
|
18387
18425
|
flex: 0 0 auto;
|
|
@@ -18391,6 +18429,227 @@ code:not(pre *) {
|
|
|
18391
18429
|
min-height: 0;
|
|
18392
18430
|
overflow-y: auto;
|
|
18393
18431
|
}
|
|
18432
|
+
.verify-controls {
|
|
18433
|
+
display: flex;
|
|
18434
|
+
flex-direction: column;
|
|
18435
|
+
gap: 12px;
|
|
18436
|
+
}
|
|
18437
|
+
.verify-controls-header {
|
|
18438
|
+
display: flex;
|
|
18439
|
+
flex-direction: column;
|
|
18440
|
+
gap: 4px;
|
|
18441
|
+
}
|
|
18442
|
+
.verify-number-grid {
|
|
18443
|
+
display: grid;
|
|
18444
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
18445
|
+
gap: 8px;
|
|
18446
|
+
}
|
|
18447
|
+
.verify-number-field {
|
|
18448
|
+
display: flex;
|
|
18449
|
+
flex-direction: column;
|
|
18450
|
+
gap: 6px;
|
|
18451
|
+
font-size: 12px;
|
|
18452
|
+
color: var(--color-text-muted);
|
|
18453
|
+
font-weight: 600;
|
|
18454
|
+
}
|
|
18455
|
+
.verify-number-field input {
|
|
18456
|
+
border: 1px solid var(--color-border-strong);
|
|
18457
|
+
border-radius: calc(10px * var(--corner-radius-scale, 1));
|
|
18458
|
+
corner-shape: squircle;
|
|
18459
|
+
padding: 6px 8px;
|
|
18460
|
+
background: var(--color-surface);
|
|
18461
|
+
color: var(--color-text);
|
|
18462
|
+
font-size: 13px;
|
|
18463
|
+
}
|
|
18464
|
+
.verify-results {
|
|
18465
|
+
display: flex;
|
|
18466
|
+
flex-direction: column;
|
|
18467
|
+
gap: 12px;
|
|
18468
|
+
min-height: 0;
|
|
18469
|
+
overflow-y: auto;
|
|
18470
|
+
}
|
|
18471
|
+
.verify-status-row {
|
|
18472
|
+
display: flex;
|
|
18473
|
+
flex-wrap: wrap;
|
|
18474
|
+
align-items: flex-start;
|
|
18475
|
+
justify-content: flex-start;
|
|
18476
|
+
gap: 10px;
|
|
18477
|
+
}
|
|
18478
|
+
.verify-status-main {
|
|
18479
|
+
display: flex;
|
|
18480
|
+
flex-direction: column;
|
|
18481
|
+
gap: 4px;
|
|
18482
|
+
}
|
|
18483
|
+
.verify-status-meta {
|
|
18484
|
+
font-size: 12px;
|
|
18485
|
+
color: var(--color-text-muted);
|
|
18486
|
+
}
|
|
18487
|
+
.verify-progress-row {
|
|
18488
|
+
display: flex;
|
|
18489
|
+
flex-wrap: wrap;
|
|
18490
|
+
gap: 8px;
|
|
18491
|
+
font-size: 12px;
|
|
18492
|
+
color: var(--color-text-muted);
|
|
18493
|
+
}
|
|
18494
|
+
.verify-verdict-badge {
|
|
18495
|
+
margin-left: auto;
|
|
18496
|
+
border-radius: calc(10px * var(--corner-radius-scale, 1));
|
|
18497
|
+
corner-shape: squircle;
|
|
18498
|
+
border: 1px solid var(--color-border);
|
|
18499
|
+
padding: 4px 8px;
|
|
18500
|
+
font-size: 11px;
|
|
18501
|
+
font-weight: 700;
|
|
18502
|
+
letter-spacing: 0.02em;
|
|
18503
|
+
}
|
|
18504
|
+
.verify-verdict-badge--pass {
|
|
18505
|
+
background: var(--color-success-soft);
|
|
18506
|
+
border-color: var(--color-success-strong);
|
|
18507
|
+
color: var(--color-success-strong);
|
|
18508
|
+
}
|
|
18509
|
+
.verify-verdict-badge--warn {
|
|
18510
|
+
background: var(--color-warning-soft);
|
|
18511
|
+
border-color: var(--color-warning-border);
|
|
18512
|
+
color: var(--color-warning);
|
|
18513
|
+
}
|
|
18514
|
+
.verify-verdict-badge--fail {
|
|
18515
|
+
background: var(--color-danger-soft);
|
|
18516
|
+
border-color: var(--color-danger-strong);
|
|
18517
|
+
color: var(--color-danger-strong);
|
|
18518
|
+
}
|
|
18519
|
+
.verify-metric-grid {
|
|
18520
|
+
display: grid;
|
|
18521
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
18522
|
+
gap: 8px;
|
|
18523
|
+
}
|
|
18524
|
+
@media (max-width: 800px) {
|
|
18525
|
+
.verify-metric-grid {
|
|
18526
|
+
grid-template-columns: minmax(0, 1fr);
|
|
18527
|
+
}
|
|
18528
|
+
}
|
|
18529
|
+
.verify-metric-card {
|
|
18530
|
+
border: 1px solid var(--color-border);
|
|
18531
|
+
border-radius: calc(12px * var(--corner-radius-scale, 1));
|
|
18532
|
+
corner-shape: squircle;
|
|
18533
|
+
padding: 8px;
|
|
18534
|
+
background: var(--color-surface-muted);
|
|
18535
|
+
}
|
|
18536
|
+
.verify-metric-label {
|
|
18537
|
+
font-size: 11px;
|
|
18538
|
+
text-transform: uppercase;
|
|
18539
|
+
letter-spacing: 0.02em;
|
|
18540
|
+
color: var(--color-text-muted);
|
|
18541
|
+
}
|
|
18542
|
+
.verify-metric-value {
|
|
18543
|
+
margin-top: 4px;
|
|
18544
|
+
font-size: 20px;
|
|
18545
|
+
font-weight: 700;
|
|
18546
|
+
color: var(--color-text);
|
|
18547
|
+
}
|
|
18548
|
+
.verify-sample-size-row {
|
|
18549
|
+
display: flex;
|
|
18550
|
+
align-items: center;
|
|
18551
|
+
justify-content: space-between;
|
|
18552
|
+
gap: 8px;
|
|
18553
|
+
flex-wrap: wrap;
|
|
18554
|
+
}
|
|
18555
|
+
.verify-sample-size-copy {
|
|
18556
|
+
display: flex;
|
|
18557
|
+
flex-direction: column;
|
|
18558
|
+
}
|
|
18559
|
+
.verify-sample-size-row .verify-metric-value {
|
|
18560
|
+
margin-top: 4px;
|
|
18561
|
+
}
|
|
18562
|
+
.verify-sample-scope-select {
|
|
18563
|
+
min-width: 170px;
|
|
18564
|
+
}
|
|
18565
|
+
.verify-sample-scope-select .gds-listbox-field-label {
|
|
18566
|
+
display: none;
|
|
18567
|
+
}
|
|
18568
|
+
.verify-metric-value--compact {
|
|
18569
|
+
font-size: 14px;
|
|
18570
|
+
}
|
|
18571
|
+
.verify-section {
|
|
18572
|
+
display: flex;
|
|
18573
|
+
flex-direction: column;
|
|
18574
|
+
gap: 8px;
|
|
18575
|
+
}
|
|
18576
|
+
.verify-section-header {
|
|
18577
|
+
display: flex;
|
|
18578
|
+
align-items: center;
|
|
18579
|
+
justify-content: space-between;
|
|
18580
|
+
gap: 8px;
|
|
18581
|
+
flex-wrap: wrap;
|
|
18582
|
+
}
|
|
18583
|
+
.verify-section-controls {
|
|
18584
|
+
display: flex;
|
|
18585
|
+
align-items: center;
|
|
18586
|
+
gap: 8px;
|
|
18587
|
+
flex-wrap: wrap;
|
|
18588
|
+
}
|
|
18589
|
+
.verify-section-sort {
|
|
18590
|
+
min-width: 150px;
|
|
18591
|
+
}
|
|
18592
|
+
.verify-section-sort .gds-listbox-field-label {
|
|
18593
|
+
display: none;
|
|
18594
|
+
}
|
|
18595
|
+
.verify-outlier-list {
|
|
18596
|
+
display: flex;
|
|
18597
|
+
flex-direction: column;
|
|
18598
|
+
gap: 8px;
|
|
18599
|
+
}
|
|
18600
|
+
.verify-outlier-card {
|
|
18601
|
+
border: 1px solid var(--color-border);
|
|
18602
|
+
border-radius: calc(12px * var(--corner-radius-scale, 1));
|
|
18603
|
+
corner-shape: squircle;
|
|
18604
|
+
padding: 8px;
|
|
18605
|
+
background: var(--color-surface-muted);
|
|
18606
|
+
display: flex;
|
|
18607
|
+
flex-direction: column;
|
|
18608
|
+
gap: 6px;
|
|
18609
|
+
}
|
|
18610
|
+
.verify-outlier-header {
|
|
18611
|
+
display: flex;
|
|
18612
|
+
align-items: center;
|
|
18613
|
+
justify-content: space-between;
|
|
18614
|
+
gap: 8px;
|
|
18615
|
+
}
|
|
18616
|
+
.verify-outlier-meta {
|
|
18617
|
+
font-size: 12px;
|
|
18618
|
+
color: var(--color-text-muted);
|
|
18619
|
+
}
|
|
18620
|
+
.verify-outlier-links {
|
|
18621
|
+
display: flex;
|
|
18622
|
+
flex-wrap: wrap;
|
|
18623
|
+
gap: 8px;
|
|
18624
|
+
font-size: 12px;
|
|
18625
|
+
}
|
|
18626
|
+
.verify-request-list {
|
|
18627
|
+
list-style: none;
|
|
18628
|
+
margin: 0;
|
|
18629
|
+
padding: 0;
|
|
18630
|
+
display: flex;
|
|
18631
|
+
flex-direction: column;
|
|
18632
|
+
gap: 6px;
|
|
18633
|
+
}
|
|
18634
|
+
.verify-request-row {
|
|
18635
|
+
border: 1px solid var(--color-border);
|
|
18636
|
+
border-radius: calc(10px * var(--corner-radius-scale, 1));
|
|
18637
|
+
corner-shape: squircle;
|
|
18638
|
+
padding: 6px 8px;
|
|
18639
|
+
background: var(--color-surface-muted);
|
|
18640
|
+
display: flex;
|
|
18641
|
+
align-items: center;
|
|
18642
|
+
gap: 8px;
|
|
18643
|
+
flex-wrap: wrap;
|
|
18644
|
+
font-size: 12px;
|
|
18645
|
+
}
|
|
18646
|
+
.verify-request-index {
|
|
18647
|
+
color: var(--color-text-muted);
|
|
18648
|
+
min-width: 28px;
|
|
18649
|
+
}
|
|
18650
|
+
.verify-request-error {
|
|
18651
|
+
color: var(--color-danger-strong);
|
|
18652
|
+
}
|
|
18394
18653
|
.calibrate-run-card {
|
|
18395
18654
|
border: 1px solid var(--color-border);
|
|
18396
18655
|
border-radius: calc(14px * var(--corner-radius-scale, 1));
|
|
@@ -20110,6 +20369,67 @@ code:not(pre *) {
|
|
|
20110
20369
|
.workbench-chat-current.is-history {
|
|
20111
20370
|
transform: translateX(85%);
|
|
20112
20371
|
}
|
|
20372
|
+
.workbench-chat-readonly-overlay {
|
|
20373
|
+
position: absolute;
|
|
20374
|
+
inset: 0;
|
|
20375
|
+
z-index: 2;
|
|
20376
|
+
background: rgba(248, 250, 252, 0.88);
|
|
20377
|
+
display: flex;
|
|
20378
|
+
align-items: center;
|
|
20379
|
+
justify-content: center;
|
|
20380
|
+
padding: 16px;
|
|
20381
|
+
}
|
|
20382
|
+
.workbench-chat-readonly-card {
|
|
20383
|
+
background: var(--color-surface);
|
|
20384
|
+
border: 1px solid var(--color-border);
|
|
20385
|
+
border-radius: calc(16px * var(--corner-radius-scale, 1));
|
|
20386
|
+
corner-shape: squircle;
|
|
20387
|
+
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.08);
|
|
20388
|
+
width: 100%;
|
|
20389
|
+
max-width: 640px;
|
|
20390
|
+
padding: 16px;
|
|
20391
|
+
display: flex;
|
|
20392
|
+
flex-direction: column;
|
|
20393
|
+
gap: 10px;
|
|
20394
|
+
text-align: left;
|
|
20395
|
+
}
|
|
20396
|
+
.workbench-chat-readonly-title {
|
|
20397
|
+
margin: 0;
|
|
20398
|
+
font-size: 16px;
|
|
20399
|
+
}
|
|
20400
|
+
.workbench-chat-readonly-copy {
|
|
20401
|
+
margin: 0;
|
|
20402
|
+
font-size: 13px;
|
|
20403
|
+
color: var(--color-text-muted);
|
|
20404
|
+
}
|
|
20405
|
+
.workbench-chat-readonly-actions {
|
|
20406
|
+
display: flex;
|
|
20407
|
+
flex-wrap: wrap;
|
|
20408
|
+
align-items: center;
|
|
20409
|
+
gap: 8px;
|
|
20410
|
+
}
|
|
20411
|
+
.workbench-chat-command-row {
|
|
20412
|
+
display: flex;
|
|
20413
|
+
align-items: flex-start;
|
|
20414
|
+
gap: 8px;
|
|
20415
|
+
}
|
|
20416
|
+
.workbench-chat-command-code {
|
|
20417
|
+
margin: 0;
|
|
20418
|
+
flex: 1;
|
|
20419
|
+
max-width: 100%;
|
|
20420
|
+
padding: 10px 12px;
|
|
20421
|
+
border: 1px solid var(--color-border);
|
|
20422
|
+
border-radius: calc(10px * var(--corner-radius-scale, 1));
|
|
20423
|
+
corner-shape: squircle;
|
|
20424
|
+
background: var(--color-surface-muted);
|
|
20425
|
+
overflow-x: auto;
|
|
20426
|
+
}
|
|
20427
|
+
.workbench-chat-command-code code {
|
|
20428
|
+
font-size: 12px;
|
|
20429
|
+
line-height: 1.4;
|
|
20430
|
+
white-space: pre-wrap;
|
|
20431
|
+
word-break: break-all;
|
|
20432
|
+
}
|
|
20113
20433
|
.gds-accordion .gds-accordion-open-only {
|
|
20114
20434
|
display: none;
|
|
20115
20435
|
}
|
|
@@ -20334,6 +20654,23 @@ code:not(pre *) {
|
|
|
20334
20654
|
opacity: 0.6;
|
|
20335
20655
|
cursor: not-allowed;
|
|
20336
20656
|
}
|
|
20657
|
+
.gds-listbox--size-small .gds-listbox-field-label {
|
|
20658
|
+
margin-bottom: 4px;
|
|
20659
|
+
font-size: 12px;
|
|
20660
|
+
}
|
|
20661
|
+
.gds-listbox--size-small .gds-listbox-trigger {
|
|
20662
|
+
padding: 4px 28px 4px 10px;
|
|
20663
|
+
gap: 0;
|
|
20664
|
+
}
|
|
20665
|
+
.gds-listbox--size-small .gds-listbox-label {
|
|
20666
|
+
font-size: 13px;
|
|
20667
|
+
}
|
|
20668
|
+
.gds-listbox--size-small .gds-listbox-meta {
|
|
20669
|
+
display: none;
|
|
20670
|
+
}
|
|
20671
|
+
.gds-listbox--size-small .gds-listbox-caret {
|
|
20672
|
+
right: 9px;
|
|
20673
|
+
}
|
|
20337
20674
|
.gds-listbox-label {
|
|
20338
20675
|
font-weight: 600;
|
|
20339
20676
|
font-size: 14px;
|
|
@@ -21655,26 +21992,42 @@ function formatScoreLabel(score) {
|
|
|
21655
21992
|
return score > 0 ? `+${score}` : String(score);
|
|
21656
21993
|
}
|
|
21657
21994
|
function formatContextLabel(context) {
|
|
21658
|
-
if (context.source === "scenario_run_error") return "
|
|
21995
|
+
if (context.source === "scenario_run_error") return "Scenario error";
|
|
21996
|
+
if (context.source === "grader_run_error") return "Grader error";
|
|
21659
21997
|
if (context.source === "message_rating") {
|
|
21660
21998
|
return formatScoreLabel(context.score);
|
|
21661
21999
|
}
|
|
22000
|
+
if (context.source === "verify_outlier") return "Verify";
|
|
21662
22001
|
return "Flag";
|
|
21663
22002
|
}
|
|
21664
22003
|
function formatContextTooltip(context) {
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
22004
|
+
switch (context.source) {
|
|
22005
|
+
case "scenario_run_error":
|
|
22006
|
+
case "grader_run_error":
|
|
22007
|
+
return context.error;
|
|
22008
|
+
case "message_rating":
|
|
22009
|
+
return context.reason?.trim() || `Rating ${formatScoreLabel(context.score)}`;
|
|
22010
|
+
case "grading_flag":
|
|
22011
|
+
case "verify_outlier":
|
|
22012
|
+
return context.message;
|
|
22013
|
+
}
|
|
22014
|
+
}
|
|
22015
|
+
function getVerifyOutlierClass(context) {
|
|
22016
|
+
if (typeof context.instability === "boolean") {
|
|
22017
|
+
return getScoreClass(context.instability ? -1 : 1);
|
|
21668
22018
|
}
|
|
21669
|
-
|
|
22019
|
+
if (typeof context.score === "number" && Number.isFinite(context.score)) {
|
|
22020
|
+
return getScoreClass(context.score);
|
|
22021
|
+
}
|
|
22022
|
+
return getScoreClass(0);
|
|
21670
22023
|
}
|
|
21671
22024
|
function WorkbenchComposerChip(props) {
|
|
21672
22025
|
const { className, context, enabled, onEnabledChange, onRemove, testId, ...rest } = props;
|
|
21673
22026
|
const label = formatContextLabel(context);
|
|
21674
22027
|
const tooltip = formatContextTooltip(context);
|
|
21675
22028
|
const score = "score" in context ? context.score : void 0;
|
|
21676
|
-
const badgeClassName = classNames("workbench-context-chip", context.source === "scenario_run_error" && "workbench-context-chip--error", context.source === "grading_flag" && "workbench-context-chip--flag", context.source === "grading_flag" && typeof score === "number" && getScoreClass(score), context.source === "message_rating" && "workbench-context-chip--rating", context.source === "message_rating" && typeof score === "number" && getScoreClass(score));
|
|
21677
|
-
const testIds = context.source === "scenario_run_error" ? {
|
|
22029
|
+
const badgeClassName = classNames("workbench-context-chip", (context.source === "scenario_run_error" || context.source === "grader_run_error") && "workbench-context-chip--error", context.source === "grading_flag" && "workbench-context-chip--flag", context.source === "grading_flag" && typeof score === "number" && getScoreClass(score), context.source === "verify_outlier" && "workbench-context-chip--flag", context.source === "verify_outlier" && getVerifyOutlierClass(context), context.source === "message_rating" && "workbench-context-chip--rating", context.source === "message_rating" && typeof score === "number" && getScoreClass(score));
|
|
22030
|
+
const testIds = context.source === "scenario_run_error" || context.source === "grader_run_error" ? {
|
|
21678
22031
|
badge: "workbench-error-chip",
|
|
21679
22032
|
toggle: "workbench-error-chip-toggle",
|
|
21680
22033
|
remove: "workbench-error-chip-remove"
|
|
@@ -21685,7 +22038,7 @@ function WorkbenchComposerChip(props) {
|
|
|
21685
22038
|
const content = context.source === "grading_flag" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, {
|
|
21686
22039
|
name: "flag",
|
|
21687
22040
|
size: 10
|
|
21688
|
-
}) : label;
|
|
22041
|
+
}) : context.source === "verify_outlier" ? "Verify" : label;
|
|
21689
22042
|
if (isPassive) {
|
|
21690
22043
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Tooltip, {
|
|
21691
22044
|
content: tooltip,
|
|
@@ -23306,6 +23659,12 @@ function WorkspaceProvider(props) {
|
|
|
23306
23659
|
];
|
|
23307
23660
|
});
|
|
23308
23661
|
}
|
|
23662
|
+
if (!data.run) {
|
|
23663
|
+
throw new Error(data.error ?? "Calibration response missing run payload");
|
|
23664
|
+
}
|
|
23665
|
+
if (data.run.status !== "completed") {
|
|
23666
|
+
throw new Error(data.run.error ?? `Calibration run ended with status ${data.run.status}`);
|
|
23667
|
+
}
|
|
23309
23668
|
setGradeError(null);
|
|
23310
23669
|
return data;
|
|
23311
23670
|
} catch (err) {
|
|
@@ -23500,6 +23859,9 @@ function useBuildChat() {
|
|
|
23500
23859
|
}
|
|
23501
23860
|
|
|
23502
23861
|
// simulator-ui/src/Chat.tsx
|
|
23862
|
+
function isWorkbenchErrorChip(chip) {
|
|
23863
|
+
return chip.source === "scenario_run_error" || chip.source === "grader_run_error";
|
|
23864
|
+
}
|
|
23503
23865
|
var ERROR_CONTEXT_START_MARKER = "[gambit:error-context/v1]";
|
|
23504
23866
|
var ERROR_CONTEXT_END_MARKER = "[/gambit:error-context/v1]";
|
|
23505
23867
|
var WORKBENCH_CONTEXT_START_MARKER = "[gambit:workbench-context/v2]";
|
|
@@ -23514,12 +23876,12 @@ function parseWorkbenchContext(value) {
|
|
|
23514
23876
|
}
|
|
23515
23877
|
const workspaceId = typeof record.workspaceId === "string" ? record.workspaceId : void 0;
|
|
23516
23878
|
const runId = typeof record.runId === "string" ? record.runId : void 0;
|
|
23517
|
-
if (record.source === "scenario_run_error") {
|
|
23879
|
+
if (record.source === "scenario_run_error" || record.source === "grader_run_error") {
|
|
23518
23880
|
if (typeof record.error !== "string" || record.error.trim().length === 0) {
|
|
23519
23881
|
return null;
|
|
23520
23882
|
}
|
|
23521
23883
|
return {
|
|
23522
|
-
source:
|
|
23884
|
+
source: record.source,
|
|
23523
23885
|
workspaceId,
|
|
23524
23886
|
runId,
|
|
23525
23887
|
capturedAt: record.capturedAt,
|
|
@@ -23557,6 +23919,21 @@ function parseWorkbenchContext(value) {
|
|
|
23557
23919
|
message: record.message
|
|
23558
23920
|
};
|
|
23559
23921
|
}
|
|
23922
|
+
if (record.source === "verify_outlier") {
|
|
23923
|
+
if (typeof record.outlierKey !== "string" || record.outlierKey.trim().length === 0 || typeof record.message !== "string" || record.message.trim().length === 0) {
|
|
23924
|
+
return null;
|
|
23925
|
+
}
|
|
23926
|
+
return {
|
|
23927
|
+
source: "verify_outlier",
|
|
23928
|
+
workspaceId,
|
|
23929
|
+
runId,
|
|
23930
|
+
capturedAt: record.capturedAt,
|
|
23931
|
+
outlierKey: record.outlierKey,
|
|
23932
|
+
instability: typeof record.instability === "boolean" ? record.instability : void 0,
|
|
23933
|
+
score: typeof record.score === "number" && Number.isFinite(record.score) ? record.score : void 0,
|
|
23934
|
+
message: record.message
|
|
23935
|
+
};
|
|
23936
|
+
}
|
|
23560
23937
|
return null;
|
|
23561
23938
|
}
|
|
23562
23939
|
function decodeLegacyWorkbenchErrorContext(content) {
|
|
@@ -23648,7 +24025,7 @@ function UserMessageContent(props) {
|
|
|
23648
24025
|
children: decoded.contexts.map((context, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(WorkbenchComposerChip, {
|
|
23649
24026
|
className: "workbench-context-chip--transcript",
|
|
23650
24027
|
context,
|
|
23651
|
-
testId: context.source === "scenario_run_error" ? "workbench-transcript-error-chip" : void 0
|
|
24028
|
+
testId: context.source === "scenario_run_error" ? "workbench-transcript-error-chip" : context.source === "grader_run_error" ? "workbench-transcript-error-chip" : void 0
|
|
23652
24029
|
}, `${context.source}-${index}`))
|
|
23653
24030
|
}),
|
|
23654
24031
|
showBody && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", {
|
|
@@ -23811,13 +24188,13 @@ function ChatView(props) {
|
|
|
23811
24188
|
return;
|
|
23812
24189
|
}
|
|
23813
24190
|
if (!onScenarioErrorChipChange) return;
|
|
23814
|
-
const errorChip = next.find(
|
|
24191
|
+
const errorChip = next.find(isWorkbenchErrorChip);
|
|
23815
24192
|
if (!errorChip) {
|
|
23816
24193
|
onScenarioErrorChipChange(null);
|
|
23817
24194
|
return;
|
|
23818
24195
|
}
|
|
23819
24196
|
onScenarioErrorChipChange({
|
|
23820
|
-
source:
|
|
24197
|
+
source: errorChip.source,
|
|
23821
24198
|
workspaceId: errorChip.workspaceId,
|
|
23822
24199
|
runId: errorChip.runId,
|
|
23823
24200
|
capturedAt: errorChip.capturedAt,
|
|
@@ -23835,18 +24212,20 @@ function ChatView(props) {
|
|
|
23835
24212
|
const message = chatDraft.trim();
|
|
23836
24213
|
const activeChips = resolvedComposerChips.filter((chip) => chip.enabled);
|
|
23837
24214
|
const activeChipIds = new Set(activeChips.map((chip) => chip.chipId));
|
|
23838
|
-
const activeContexts =
|
|
23839
|
-
|
|
23840
|
-
|
|
23841
|
-
|
|
24215
|
+
const activeContexts = [];
|
|
24216
|
+
for (const chip of activeChips) {
|
|
24217
|
+
if (isWorkbenchErrorChip(chip)) {
|
|
24218
|
+
activeContexts.push({
|
|
24219
|
+
source: chip.source,
|
|
23842
24220
|
workspaceId: chip.workspaceId,
|
|
23843
24221
|
runId: chip.runId,
|
|
23844
24222
|
capturedAt: chip.capturedAt,
|
|
23845
24223
|
error: chip.error
|
|
23846
|
-
};
|
|
24224
|
+
});
|
|
24225
|
+
continue;
|
|
23847
24226
|
}
|
|
23848
24227
|
if (chip.source === "message_rating") {
|
|
23849
|
-
|
|
24228
|
+
activeContexts.push({
|
|
23850
24229
|
source: "message_rating",
|
|
23851
24230
|
workspaceId: chip.workspaceId,
|
|
23852
24231
|
runId: chip.runId,
|
|
@@ -23856,19 +24235,35 @@ function ChatView(props) {
|
|
|
23856
24235
|
statePointer: chip.statePointer,
|
|
23857
24236
|
score: chip.score,
|
|
23858
24237
|
reason: chip.reason
|
|
23859
|
-
};
|
|
24238
|
+
});
|
|
24239
|
+
continue;
|
|
23860
24240
|
}
|
|
23861
|
-
|
|
23862
|
-
|
|
23863
|
-
|
|
23864
|
-
|
|
23865
|
-
|
|
23866
|
-
|
|
23867
|
-
|
|
23868
|
-
|
|
23869
|
-
|
|
23870
|
-
|
|
23871
|
-
|
|
24241
|
+
if (chip.source === "grading_flag") {
|
|
24242
|
+
activeContexts.push({
|
|
24243
|
+
source: "grading_flag",
|
|
24244
|
+
workspaceId: chip.workspaceId,
|
|
24245
|
+
runId: chip.runId,
|
|
24246
|
+
capturedAt: chip.capturedAt,
|
|
24247
|
+
flagId: chip.flagId,
|
|
24248
|
+
refId: chip.refId,
|
|
24249
|
+
score: chip.score,
|
|
24250
|
+
message: chip.message
|
|
24251
|
+
});
|
|
24252
|
+
continue;
|
|
24253
|
+
}
|
|
24254
|
+
if (chip.source === "verify_outlier") {
|
|
24255
|
+
activeContexts.push({
|
|
24256
|
+
source: "verify_outlier",
|
|
24257
|
+
workspaceId: chip.workspaceId,
|
|
24258
|
+
runId: chip.runId,
|
|
24259
|
+
capturedAt: chip.capturedAt,
|
|
24260
|
+
outlierKey: chip.outlierKey,
|
|
24261
|
+
instability: chip.instability,
|
|
24262
|
+
score: chip.score,
|
|
24263
|
+
message: chip.message
|
|
24264
|
+
});
|
|
24265
|
+
}
|
|
24266
|
+
}
|
|
23872
24267
|
if (!message && activeContexts.length === 0) return;
|
|
23873
24268
|
const outboundMessage = activeContexts.length > 0 ? encodeWorkbenchMessageWithContext(message, activeContexts) : message;
|
|
23874
24269
|
setOptimisticUser({
|
|
@@ -24201,9 +24596,21 @@ function WorkbenchDrawer(props) {
|
|
|
24201
24596
|
const [chatHistoryLoading, setChatHistoryLoading] = (0, import_react28.useState)(false);
|
|
24202
24597
|
const [chatHistoryError, setChatHistoryError] = (0, import_react28.useState)(null);
|
|
24203
24598
|
const [copiedStatePath, setCopiedStatePath] = (0, import_react28.useState)(false);
|
|
24599
|
+
const [copiedCodexLoginCommand, setCopiedCodexLoginCommand] = (0, import_react28.useState)(false);
|
|
24600
|
+
const [codexTrustPending, setCodexTrustPending] = (0, import_react28.useState)(false);
|
|
24601
|
+
const [codexTrustError, setCodexTrustError] = (0, import_react28.useState)(null);
|
|
24602
|
+
const [codexTrustSuccess, setCodexTrustSuccess] = (0, import_react28.useState)(null);
|
|
24603
|
+
const [codexWorkspaceWriteEnabled, setCodexWorkspaceWriteEnabled] = (0, import_react28.useState)(null);
|
|
24604
|
+
const [codexWorkspaceLoggedIn, setCodexWorkspaceLoggedIn] = (0, import_react28.useState)(null);
|
|
24605
|
+
const [codexLoginStatusText, setCodexLoginStatusText] = (0, import_react28.useState)(null);
|
|
24606
|
+
const [codexTrustedPath, setCodexTrustedPath] = (0, import_react28.useState)(null);
|
|
24607
|
+
const [codexTrustOverlayDismissed, setCodexTrustOverlayDismissed] = (0, import_react28.useState)(false);
|
|
24204
24608
|
const initializedChipTrackingRef = (0, import_react28.useRef)(false);
|
|
24205
24609
|
const seenRatingChipIdsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Set());
|
|
24206
24610
|
const seenFlagChipIdsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Set());
|
|
24611
|
+
const showCodexTrustOverlay = (codexWorkspaceWriteEnabled === false || codexWorkspaceLoggedIn === false) && !codexTrustOverlayDismissed || Boolean(codexTrustError);
|
|
24612
|
+
const workspaceIdForTrust = (sessionId ?? run.id) || void 0;
|
|
24613
|
+
const codexLoginCommand = codexTrustedPath ? `CODEX_HOME="${codexTrustedPath}/.codex" codex login` : 'CODEX_HOME="<workspace>/.codex" codex login';
|
|
24207
24614
|
const resolvedStatePath = (0, import_react28.useMemo)(() => {
|
|
24208
24615
|
if (statePath) return statePath;
|
|
24209
24616
|
const meta = sessionDetail?.meta;
|
|
@@ -24421,9 +24828,49 @@ function WorkbenchDrawer(props) {
|
|
|
24421
24828
|
initializedChipTrackingRef.current = false;
|
|
24422
24829
|
seenRatingChipIdsRef.current.clear();
|
|
24423
24830
|
seenFlagChipIdsRef.current.clear();
|
|
24831
|
+
setCodexTrustPending(false);
|
|
24832
|
+
setCodexTrustError(null);
|
|
24833
|
+
setCodexTrustSuccess(null);
|
|
24834
|
+
setCodexWorkspaceWriteEnabled(null);
|
|
24835
|
+
setCodexWorkspaceLoggedIn(null);
|
|
24836
|
+
setCodexLoginStatusText(null);
|
|
24837
|
+
setCodexTrustedPath(null);
|
|
24838
|
+
setCopiedCodexLoginCommand(false);
|
|
24839
|
+
setCodexTrustOverlayDismissed(false);
|
|
24424
24840
|
}, [
|
|
24425
24841
|
sessionId
|
|
24426
24842
|
]);
|
|
24843
|
+
(0, import_react28.useEffect)(() => {
|
|
24844
|
+
if (!open) return;
|
|
24845
|
+
if (!workspaceIdForTrust) return;
|
|
24846
|
+
let canceled = false;
|
|
24847
|
+
setCodexTrustError(null);
|
|
24848
|
+
fetch(`/api/codex/trust-workspace?workspaceId=${encodeURIComponent(workspaceIdForTrust)}`).then(async (response) => {
|
|
24849
|
+
const payload = await response.json();
|
|
24850
|
+
if (!response.ok || payload.ok === false) {
|
|
24851
|
+
throw new Error(payload.error || response.statusText);
|
|
24852
|
+
}
|
|
24853
|
+
if (canceled) return;
|
|
24854
|
+
setCodexWorkspaceWriteEnabled(payload.writeEnabled === true);
|
|
24855
|
+
setCodexWorkspaceLoggedIn(payload.codexLoggedIn === true);
|
|
24856
|
+
setCodexLoginStatusText(typeof payload.codexLoginStatus === "string" ? payload.codexLoginStatus : null);
|
|
24857
|
+
setCodexTrustedPath(typeof payload.trustedPath === "string" ? payload.trustedPath : null);
|
|
24858
|
+
}).catch((err) => {
|
|
24859
|
+
if (canceled) return;
|
|
24860
|
+
setCodexWorkspaceWriteEnabled(null);
|
|
24861
|
+
setCodexWorkspaceLoggedIn(null);
|
|
24862
|
+
setCodexLoginStatusText(null);
|
|
24863
|
+
setCodexTrustError(err instanceof Error ? err.message : String(err));
|
|
24864
|
+
}).finally(() => {
|
|
24865
|
+
if (canceled) return;
|
|
24866
|
+
});
|
|
24867
|
+
return () => {
|
|
24868
|
+
canceled = true;
|
|
24869
|
+
};
|
|
24870
|
+
}, [
|
|
24871
|
+
open,
|
|
24872
|
+
workspaceIdForTrust
|
|
24873
|
+
]);
|
|
24427
24874
|
(0, import_react28.useEffect)(() => {
|
|
24428
24875
|
if (loading) return;
|
|
24429
24876
|
const currentRatingChipIds = new Set(resolvedFeedbackItems.map(({ entry }) => `rating:${entry.messageRefId}:${entry.id}`));
|
|
@@ -24460,18 +24907,20 @@ function WorkbenchDrawer(props) {
|
|
|
24460
24907
|
let didChange = false;
|
|
24461
24908
|
const syncedChips = composerChips.filter((chip) => {
|
|
24462
24909
|
if (chip.source === "message_rating") {
|
|
24910
|
+
if (!chip.chipId.startsWith("rating:")) return true;
|
|
24463
24911
|
const stillExists = ratingByChipId.has(chip.chipId);
|
|
24464
24912
|
if (!stillExists) didChange = true;
|
|
24465
24913
|
return stillExists;
|
|
24466
24914
|
}
|
|
24467
24915
|
if (chip.source === "grading_flag") {
|
|
24916
|
+
if (!chip.chipId.startsWith("flag:")) return true;
|
|
24468
24917
|
const stillExists = flagByChipId.has(chip.chipId);
|
|
24469
24918
|
if (!stillExists) didChange = true;
|
|
24470
24919
|
return stillExists;
|
|
24471
24920
|
}
|
|
24472
24921
|
return true;
|
|
24473
24922
|
}).map((chip) => {
|
|
24474
|
-
const latest = chip.source === "message_rating" ? ratingByChipId.get(chip.chipId) : chip.source === "grading_flag" ? flagByChipId.get(chip.chipId) : void 0;
|
|
24923
|
+
const latest = chip.source === "message_rating" && chip.chipId.startsWith("rating:") ? ratingByChipId.get(chip.chipId) : chip.source === "grading_flag" && chip.chipId.startsWith("flag:") ? flagByChipId.get(chip.chipId) : void 0;
|
|
24475
24924
|
if (!latest) return chip;
|
|
24476
24925
|
const next = {
|
|
24477
24926
|
...chip,
|
|
@@ -24539,6 +24988,13 @@ function WorkbenchDrawer(props) {
|
|
|
24539
24988
|
}, [
|
|
24540
24989
|
resolvedStatePath
|
|
24541
24990
|
]);
|
|
24991
|
+
const handleCopyCodexLoginCommand = (0, import_react28.useCallback)(() => {
|
|
24992
|
+
navigator.clipboard?.writeText(codexLoginCommand);
|
|
24993
|
+
setCopiedCodexLoginCommand(true);
|
|
24994
|
+
window.setTimeout(() => setCopiedCodexLoginCommand(false), 1200);
|
|
24995
|
+
}, [
|
|
24996
|
+
codexLoginCommand
|
|
24997
|
+
]);
|
|
24542
24998
|
(0, import_react28.useEffect)(() => {
|
|
24543
24999
|
if (!open) return;
|
|
24544
25000
|
if (!onClose) return;
|
|
@@ -24553,6 +25009,55 @@ function WorkbenchDrawer(props) {
|
|
|
24553
25009
|
onClose,
|
|
24554
25010
|
open
|
|
24555
25011
|
]);
|
|
25012
|
+
const trustWorkspaceInCodex = (0, import_react28.useCallback)(async () => {
|
|
25013
|
+
setCodexTrustPending(true);
|
|
25014
|
+
setCodexTrustError(null);
|
|
25015
|
+
setCodexTrustSuccess(null);
|
|
25016
|
+
try {
|
|
25017
|
+
const statusResponse = await fetch(`/api/codex/trust-workspace?workspaceId=${encodeURIComponent(workspaceIdForTrust ?? "")}`);
|
|
25018
|
+
const statusPayload = await statusResponse.json();
|
|
25019
|
+
if (!statusResponse.ok || statusPayload.ok === false) {
|
|
25020
|
+
throw new Error(statusPayload.error || statusResponse.statusText);
|
|
25021
|
+
}
|
|
25022
|
+
if (statusPayload.writeEnabled === true && statusPayload.codexLoggedIn === true) {
|
|
25023
|
+
setCodexWorkspaceWriteEnabled(true);
|
|
25024
|
+
setCodexWorkspaceLoggedIn(true);
|
|
25025
|
+
setCodexTrustSuccess("Workspace is already configured for Codex writes.");
|
|
25026
|
+
setCodexTrustOverlayDismissed(true);
|
|
25027
|
+
return;
|
|
25028
|
+
}
|
|
25029
|
+
setCodexWorkspaceWriteEnabled(statusPayload.writeEnabled === true);
|
|
25030
|
+
setCodexWorkspaceLoggedIn(statusPayload.codexLoggedIn === true);
|
|
25031
|
+
setCodexLoginStatusText(typeof statusPayload.codexLoginStatus === "string" ? statusPayload.codexLoginStatus : null);
|
|
25032
|
+
setCodexTrustedPath(typeof statusPayload.trustedPath === "string" ? statusPayload.trustedPath : null);
|
|
25033
|
+
const response = await fetch("/api/codex/trust-workspace", {
|
|
25034
|
+
method: "POST",
|
|
25035
|
+
headers: {
|
|
25036
|
+
"content-type": "application/json"
|
|
25037
|
+
},
|
|
25038
|
+
body: JSON.stringify({
|
|
25039
|
+
workspaceId: workspaceIdForTrust
|
|
25040
|
+
})
|
|
25041
|
+
});
|
|
25042
|
+
const payload = await response.json();
|
|
25043
|
+
if (!response.ok || payload.ok === false) {
|
|
25044
|
+
throw new Error(payload.error || response.statusText);
|
|
25045
|
+
}
|
|
25046
|
+
const trustedPath = typeof payload.trustedPath === "string" ? payload.trustedPath : "workspace";
|
|
25047
|
+
setCodexTrustSuccess(`Codex write enabled for: ${trustedPath}`);
|
|
25048
|
+
setCodexWorkspaceWriteEnabled(payload.writeEnabled === true);
|
|
25049
|
+
setCodexWorkspaceLoggedIn(payload.codexLoggedIn === true);
|
|
25050
|
+
setCodexLoginStatusText(typeof payload.codexLoginStatus === "string" ? payload.codexLoginStatus : null);
|
|
25051
|
+
setCodexTrustedPath(typeof payload.trustedPath === "string" ? payload.trustedPath : null);
|
|
25052
|
+
setCodexTrustOverlayDismissed(payload.codexLoggedIn === true);
|
|
25053
|
+
} catch (err) {
|
|
25054
|
+
setCodexTrustError(err instanceof Error ? err.message : String(err));
|
|
25055
|
+
} finally {
|
|
25056
|
+
setCodexTrustPending(false);
|
|
25057
|
+
}
|
|
25058
|
+
}, [
|
|
25059
|
+
workspaceIdForTrust
|
|
25060
|
+
]);
|
|
24556
25061
|
if (!open) return null;
|
|
24557
25062
|
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("aside", {
|
|
24558
25063
|
className: "workbench-drawer-docked",
|
|
@@ -24653,12 +25158,87 @@ function WorkbenchDrawer(props) {
|
|
|
24653
25158
|
})
|
|
24654
25159
|
]
|
|
24655
25160
|
}),
|
|
24656
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.
|
|
25161
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", {
|
|
24657
25162
|
className: `workbench-chat-current${chatHistoryOpen ? " is-history" : ""}`,
|
|
24658
|
-
children:
|
|
24659
|
-
|
|
24660
|
-
|
|
24661
|
-
|
|
25163
|
+
children: [
|
|
25164
|
+
showCodexTrustOverlay && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", {
|
|
25165
|
+
className: "workbench-chat-readonly-overlay",
|
|
25166
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", {
|
|
25167
|
+
className: "workbench-chat-readonly-card",
|
|
25168
|
+
children: [
|
|
25169
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", {
|
|
25170
|
+
className: "workbench-chat-readonly-title",
|
|
25171
|
+
children: "Codex setup required"
|
|
25172
|
+
}),
|
|
25173
|
+
codexWorkspaceWriteEnabled === false && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", {
|
|
25174
|
+
className: "workbench-chat-readonly-copy",
|
|
25175
|
+
children: "Codex write access is disabled for this workspace. Trust this workspace to enable file edits."
|
|
25176
|
+
}),
|
|
25177
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", {
|
|
25178
|
+
className: "workbench-chat-readonly-actions",
|
|
25179
|
+
children: codexWorkspaceWriteEnabled === false && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button, {
|
|
25180
|
+
variant: "primary",
|
|
25181
|
+
onClick: () => trustWorkspaceInCodex(),
|
|
25182
|
+
disabled: codexTrustPending,
|
|
25183
|
+
children: codexTrustPending ? "Trusting..." : "Trust workspace"
|
|
25184
|
+
})
|
|
25185
|
+
}),
|
|
25186
|
+
codexWorkspaceLoggedIn === false && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, {
|
|
25187
|
+
children: [
|
|
25188
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", {
|
|
25189
|
+
className: "workbench-chat-readonly-copy",
|
|
25190
|
+
children: "Codex login is required for this workspace."
|
|
25191
|
+
}),
|
|
25192
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", {
|
|
25193
|
+
className: "workbench-chat-readonly-copy",
|
|
25194
|
+
children: "Run this in this workspace to authenticate Codex, then restart Gambit."
|
|
25195
|
+
}),
|
|
25196
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", {
|
|
25197
|
+
className: "workbench-chat-command-row",
|
|
25198
|
+
children: [
|
|
25199
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("pre", {
|
|
25200
|
+
className: "workbench-chat-command-code",
|
|
25201
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("code", {
|
|
25202
|
+
children: codexLoginCommand
|
|
25203
|
+
})
|
|
25204
|
+
}),
|
|
25205
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Button, {
|
|
25206
|
+
variant: "secondary",
|
|
25207
|
+
size: "small",
|
|
25208
|
+
onClick: handleCopyCodexLoginCommand,
|
|
25209
|
+
children: [
|
|
25210
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Icon, {
|
|
25211
|
+
name: copiedCodexLoginCommand ? "copied" : "copy",
|
|
25212
|
+
size: 14
|
|
25213
|
+
}),
|
|
25214
|
+
copiedCodexLoginCommand ? "Copied" : "Copy"
|
|
25215
|
+
]
|
|
25216
|
+
})
|
|
25217
|
+
]
|
|
25218
|
+
})
|
|
25219
|
+
]
|
|
25220
|
+
}),
|
|
25221
|
+
codexLoginStatusText && !/^not logged in$/i.test(codexLoginStatusText.trim()) && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Callout, {
|
|
25222
|
+
children: codexLoginStatusText
|
|
25223
|
+
}),
|
|
25224
|
+
codexTrustError && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", {
|
|
25225
|
+
className: "error",
|
|
25226
|
+
children: codexTrustError
|
|
25227
|
+
}),
|
|
25228
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button, {
|
|
25229
|
+
variant: "secondary",
|
|
25230
|
+
onClick: () => setCodexTrustOverlayDismissed(true),
|
|
25231
|
+
disabled: codexTrustPending,
|
|
25232
|
+
children: "Dismiss"
|
|
25233
|
+
})
|
|
25234
|
+
]
|
|
25235
|
+
})
|
|
25236
|
+
}),
|
|
25237
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Chat, {
|
|
25238
|
+
composerChips,
|
|
25239
|
+
onComposerChipsChange
|
|
25240
|
+
})
|
|
25241
|
+
]
|
|
24662
25242
|
})
|
|
24663
25243
|
]
|
|
24664
25244
|
})
|
|
@@ -24672,6 +25252,9 @@ function WorkbenchDrawer(props) {
|
|
|
24672
25252
|
content: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", {
|
|
24673
25253
|
className: "workbench-ratings",
|
|
24674
25254
|
children: [
|
|
25255
|
+
codexTrustSuccess && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Callout, {
|
|
25256
|
+
children: codexTrustSuccess
|
|
25257
|
+
}),
|
|
24675
25258
|
showCopyStatePath && handleCopyStatePath && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, {
|
|
24676
25259
|
children: [
|
|
24677
25260
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Button, {
|
|
@@ -25140,7 +25723,7 @@ function MessageBubble(props) {
|
|
|
25140
25723
|
className: "respond-meta",
|
|
25141
25724
|
children: [
|
|
25142
25725
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Badge, {
|
|
25143
|
-
children: "
|
|
25726
|
+
children: "legacy respond envelope"
|
|
25144
25727
|
}),
|
|
25145
25728
|
typeof entry.respond?.status === "number" && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(Badge, {
|
|
25146
25729
|
variant: "ghost",
|
|
@@ -25253,16 +25836,20 @@ function FeedbackControls(props) {
|
|
|
25253
25836
|
const [errorMessage, setErrorMessage] = (0, import_react32.useState)(null);
|
|
25254
25837
|
const requestSeqRef = (0, import_react32.useRef)(0);
|
|
25255
25838
|
(0, import_react32.useEffect)(() => {
|
|
25256
|
-
|
|
25257
|
-
if (
|
|
25258
|
-
|
|
25259
|
-
|
|
25260
|
-
|
|
25839
|
+
const isEditing = status === "unsaved" || status === "saving";
|
|
25840
|
+
if (!isEditing) {
|
|
25841
|
+
setReason(feedback?.reason ?? "");
|
|
25842
|
+
if (typeof feedback?.score === "number" || feedback?.reason !== void 0) {
|
|
25843
|
+
setStatus("saved");
|
|
25844
|
+
} else {
|
|
25845
|
+
setStatus("idle");
|
|
25846
|
+
}
|
|
25847
|
+
setErrorMessage(null);
|
|
25261
25848
|
}
|
|
25262
|
-
setErrorMessage(null);
|
|
25263
25849
|
}, [
|
|
25264
25850
|
feedback?.reason,
|
|
25265
|
-
feedback?.score
|
|
25851
|
+
feedback?.score,
|
|
25852
|
+
status
|
|
25266
25853
|
]);
|
|
25267
25854
|
(0, import_react32.useEffect)(() => {
|
|
25268
25855
|
if (typeof feedback?.score === "number") {
|
|
@@ -25963,7 +26550,7 @@ var import_jsx_runtime36 = __toESM(require_jsx_runtime());
|
|
|
25963
26550
|
var import_react33 = __toESM(require__());
|
|
25964
26551
|
var import_react_dom2 = __toESM(require__3());
|
|
25965
26552
|
function Listbox(props) {
|
|
25966
|
-
const { value, options, placeholder = "Select", disabled = false, onChange, label, labelClassName, id } = props;
|
|
26553
|
+
const { value, options, placeholder = "Select", disabled = false, onChange, label, labelClassName, id, popoverMatchTriggerWidth = true, popoverMinWidth, popoverAlign = "left", size = "default" } = props;
|
|
25967
26554
|
const [open, setOpen] = (0, import_react33.useState)(false);
|
|
25968
26555
|
const rootRef = (0, import_react33.useRef)(null);
|
|
25969
26556
|
const triggerRef = (0, import_react33.useRef)(null);
|
|
@@ -25983,17 +26570,40 @@ function Listbox(props) {
|
|
|
25983
26570
|
options,
|
|
25984
26571
|
value
|
|
25985
26572
|
]);
|
|
26573
|
+
const selectedTriggerMeta = (0, import_react33.useMemo)(() => {
|
|
26574
|
+
if (!selected) return null;
|
|
26575
|
+
if ("triggerMeta" in selected) return selected.triggerMeta ?? null;
|
|
26576
|
+
return selected.meta ?? null;
|
|
26577
|
+
}, [
|
|
26578
|
+
selected
|
|
26579
|
+
]);
|
|
25986
26580
|
const updatePopover = (0, import_react33.useCallback)(() => {
|
|
25987
26581
|
const trigger = triggerRef.current;
|
|
25988
26582
|
if (!trigger) return;
|
|
25989
26583
|
const rect = trigger.getBoundingClientRect();
|
|
25990
|
-
|
|
26584
|
+
const style = {
|
|
25991
26585
|
position: "fixed",
|
|
25992
|
-
top: rect.bottom + 6
|
|
25993
|
-
|
|
25994
|
-
|
|
25995
|
-
|
|
25996
|
-
|
|
26586
|
+
top: rect.bottom + 6
|
|
26587
|
+
};
|
|
26588
|
+
if (popoverMatchTriggerWidth) {
|
|
26589
|
+
style.width = rect.width;
|
|
26590
|
+
} else if (typeof popoverMinWidth === "number" && Number.isFinite(popoverMinWidth)) {
|
|
26591
|
+
style.minWidth = popoverMinWidth;
|
|
26592
|
+
}
|
|
26593
|
+
if (popoverAlign === "right") {
|
|
26594
|
+
style.left = popoverMatchTriggerWidth ? rect.right - rect.width : rect.right;
|
|
26595
|
+
if (!popoverMatchTriggerWidth) {
|
|
26596
|
+
style.transform = "translateX(-100%)";
|
|
26597
|
+
}
|
|
26598
|
+
} else {
|
|
26599
|
+
style.left = rect.left;
|
|
26600
|
+
}
|
|
26601
|
+
setPopoverStyle(style);
|
|
26602
|
+
}, [
|
|
26603
|
+
popoverAlign,
|
|
26604
|
+
popoverMatchTriggerWidth,
|
|
26605
|
+
popoverMinWidth
|
|
26606
|
+
]);
|
|
25997
26607
|
(0, import_react33.useLayoutEffect)(() => {
|
|
25998
26608
|
if (!open) return;
|
|
25999
26609
|
updatePopover();
|
|
@@ -26032,8 +26642,9 @@ function Listbox(props) {
|
|
|
26032
26642
|
open,
|
|
26033
26643
|
updatePopover
|
|
26034
26644
|
]);
|
|
26645
|
+
const rootClassName = size === "small" ? "gds-listbox gds-listbox--size-small" : "gds-listbox";
|
|
26035
26646
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", {
|
|
26036
|
-
className:
|
|
26647
|
+
className: rootClassName,
|
|
26037
26648
|
ref: rootRef,
|
|
26038
26649
|
children: [
|
|
26039
26650
|
label && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("label", {
|
|
@@ -26054,11 +26665,11 @@ function Listbox(props) {
|
|
|
26054
26665
|
ref: triggerRef,
|
|
26055
26666
|
children: [
|
|
26056
26667
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ScrollingText, {
|
|
26057
|
-
text: selected?.label ?? placeholder,
|
|
26668
|
+
text: selected?.triggerLabel ?? selected?.label ?? placeholder,
|
|
26058
26669
|
className: "gds-listbox-label"
|
|
26059
26670
|
}),
|
|
26060
|
-
|
|
26061
|
-
text:
|
|
26671
|
+
selectedTriggerMeta && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ScrollingText, {
|
|
26672
|
+
text: selectedTriggerMeta,
|
|
26062
26673
|
className: "gds-listbox-meta"
|
|
26063
26674
|
}),
|
|
26064
26675
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", {
|
|
@@ -26176,7 +26787,7 @@ var scenarioRunIdFromCalibrationRun = (run) => {
|
|
|
26176
26787
|
const scenarioRunId = meta.scenarioRunId;
|
|
26177
26788
|
return typeof scenarioRunId === "string" && scenarioRunId.trim().length > 0 ? scenarioRunId : null;
|
|
26178
26789
|
};
|
|
26179
|
-
function GradePage({ setNavActions, onAppPathChange, activeWorkspaceId, onFlagsUpdate, onOptimisticToggleFlag, onOptimisticFlagReason, requestedGradeRunId }) {
|
|
26790
|
+
function GradePage({ setNavActions, onAppPathChange, activeWorkspaceId, onFlagsUpdate, onOptimisticToggleFlag, onOptimisticFlagReason, onAddErrorToWorkbench, requestedGradeRunId }) {
|
|
26180
26791
|
const workspaceGrade = useWorkspaceGrade();
|
|
26181
26792
|
const { loading, error, running, graders, sessions, sessionDetail, loadData, loadSessionDetail, runGrader: runGrade, toggleFlag: toggleGradeFlag, updateFlagReason: updateGradeFlagReason } = workspaceGrade;
|
|
26182
26793
|
const workspaceRouting = useWorkspaceRouting();
|
|
@@ -26757,8 +27368,23 @@ function GradePage({ setNavActions, onAppPathChange, activeWorkspaceId, onFlagsU
|
|
|
26757
27368
|
gap: 12
|
|
26758
27369
|
},
|
|
26759
27370
|
children: [
|
|
26760
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
26761
|
-
|
|
27371
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Callout, {
|
|
27372
|
+
variant: "danger",
|
|
27373
|
+
title: "Grader run failed",
|
|
27374
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Button, {
|
|
27375
|
+
variant: "secondary",
|
|
27376
|
+
size: "small",
|
|
27377
|
+
onClick: () => onAddErrorToWorkbench?.({
|
|
27378
|
+
source: "grader_run_error",
|
|
27379
|
+
workspaceId: selectedSessionId ?? activeWorkspaceId ?? void 0,
|
|
27380
|
+
runId: routeGradeRunId ?? expandedRunId ?? void 0,
|
|
27381
|
+
error
|
|
27382
|
+
}),
|
|
27383
|
+
disabled: !onAddErrorToWorkbench,
|
|
27384
|
+
"data-testid": "grade-add-error-to-chat",
|
|
27385
|
+
children: "Add to chat"
|
|
27386
|
+
}),
|
|
27387
|
+
"data-testid": "grade-error-callout",
|
|
26762
27388
|
children: error
|
|
26763
27389
|
}),
|
|
26764
27390
|
loading && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", {
|
|
@@ -26769,11 +27395,21 @@ function GradePage({ setNavActions, onAppPathChange, activeWorkspaceId, onFlagsU
|
|
|
26769
27395
|
children: [
|
|
26770
27396
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", {
|
|
26771
27397
|
className: "flex-column gap-4",
|
|
26772
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime39.
|
|
27398
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", {
|
|
26773
27399
|
className: "flex-row items-center gap-8",
|
|
26774
|
-
children:
|
|
26775
|
-
|
|
26776
|
-
|
|
27400
|
+
children: [
|
|
27401
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("strong", {
|
|
27402
|
+
children: "Grader runs"
|
|
27403
|
+
}),
|
|
27404
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", {
|
|
27405
|
+
className: "secondary-note",
|
|
27406
|
+
children: [
|
|
27407
|
+
"(",
|
|
27408
|
+
filteredSessionRuns.length,
|
|
27409
|
+
")"
|
|
27410
|
+
]
|
|
27411
|
+
})
|
|
27412
|
+
]
|
|
26777
27413
|
})
|
|
26778
27414
|
}),
|
|
26779
27415
|
runItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Callout, {
|
|
@@ -27052,8 +27688,23 @@ function GradePage({ setNavActions, onAppPathChange, activeWorkspaceId, onFlagsU
|
|
|
27052
27688
|
]
|
|
27053
27689
|
})
|
|
27054
27690
|
}),
|
|
27055
|
-
item.error && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
27056
|
-
|
|
27691
|
+
item.error && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Callout, {
|
|
27692
|
+
variant: "danger",
|
|
27693
|
+
title: "Grade run failed",
|
|
27694
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Button, {
|
|
27695
|
+
variant: "secondary",
|
|
27696
|
+
size: "small",
|
|
27697
|
+
onClick: () => onAddErrorToWorkbench?.({
|
|
27698
|
+
source: "grader_run_error",
|
|
27699
|
+
workspaceId: selectedSessionId ?? activeWorkspaceId ?? void 0,
|
|
27700
|
+
runId: item.runId,
|
|
27701
|
+
error: item.error
|
|
27702
|
+
}),
|
|
27703
|
+
disabled: !onAddErrorToWorkbench,
|
|
27704
|
+
"data-testid": "grade-run-add-error-to-chat",
|
|
27705
|
+
children: "Add to chat"
|
|
27706
|
+
}),
|
|
27707
|
+
"data-testid": "grade-run-error-callout",
|
|
27057
27708
|
children: item.error
|
|
27058
27709
|
}),
|
|
27059
27710
|
isOpen && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", {
|
|
@@ -27125,7 +27776,7 @@ var import_react38 = __toESM(require__());
|
|
|
27125
27776
|
var import_jsx_runtime40 = __toESM(require_jsx_runtime());
|
|
27126
27777
|
var import_react37 = __toESM(require__());
|
|
27127
27778
|
function TestBotChatPanel(props) {
|
|
27128
|
-
const { run, runWorkspaceId, runStatusLabel, activeWorkspaceId, requestedRunNotFound, canStart, canRunPersona, hasPersonaSelection, botJsonErrorCount, deckJsonErrorCount, missingBotInput, missingDeckInit, lastInitFill, isUserStart, showStartOverlay, canStartAssistant, canSendChat, chatDraft, setChatDraft, chatError, optimisticUser, streamingUser, streamingAssistant, startRun, stopRun, handleNewChat, handleSendChat, handleStartAssistant, onScore, onReasonChange,
|
|
27779
|
+
const { run, runWorkspaceId, runStatusLabel, activeWorkspaceId, requestedRunNotFound, canStart, canRunPersona, hasPersonaSelection, botJsonErrorCount, deckJsonErrorCount, missingBotInput, missingDeckInit, lastInitFill, isUserStart, showStartOverlay, canStartAssistant, canSendChat, chatDraft, setChatDraft, chatError, optimisticUser, streamingUser, streamingAssistant, startRun, stopRun, handleNewChat, handleSendChat, handleStartAssistant, onScore, onReasonChange, onAddErrorToWorkbench } = props;
|
|
27129
27780
|
const transcriptRef = (0, import_react37.useRef)(null);
|
|
27130
27781
|
const lastRunMessageCountRef = (0, import_react37.useRef)(0);
|
|
27131
27782
|
(0, import_react37.useEffect)(() => {
|
|
@@ -27333,12 +27984,13 @@ function TestBotChatPanel(props) {
|
|
|
27333
27984
|
actions: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Button, {
|
|
27334
27985
|
variant: "secondary",
|
|
27335
27986
|
size: "small",
|
|
27336
|
-
onClick: () =>
|
|
27987
|
+
onClick: () => onAddErrorToWorkbench?.({
|
|
27988
|
+
source: "scenario_run_error",
|
|
27337
27989
|
workspaceId: runWorkspaceId ?? activeWorkspaceId ?? void 0,
|
|
27338
27990
|
runId: run.id,
|
|
27339
27991
|
error: run.error
|
|
27340
27992
|
}),
|
|
27341
|
-
disabled: !
|
|
27993
|
+
disabled: !onAddErrorToWorkbench,
|
|
27342
27994
|
"data-testid": "testbot-add-error-to-chat",
|
|
27343
27995
|
children: "Add to chat"
|
|
27344
27996
|
}),
|
|
@@ -27416,7 +28068,7 @@ function TestBotChatPanel(props) {
|
|
|
27416
28068
|
className: "respond-meta",
|
|
27417
28069
|
children: [
|
|
27418
28070
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Badge, {
|
|
27419
|
-
children: "
|
|
28071
|
+
children: "legacy respond envelope"
|
|
27420
28072
|
}),
|
|
27421
28073
|
typeof message.respondStatus === "number" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Badge, {
|
|
27422
28074
|
variant: "ghost",
|
|
@@ -27624,7 +28276,7 @@ var getScenarioTitle2 = (summary, opts) => {
|
|
|
27624
28276
|
return fromDeckCatalogById ?? fromDeckCatalogByPath ?? fromDeckLabel ?? fromDeckId ?? fromPath ?? summary.runId;
|
|
27625
28277
|
};
|
|
27626
28278
|
function TestBotPage(props) {
|
|
27627
|
-
const { onReplaceTestBotSession, onResetTestBotSession, activeWorkspaceId, requestedRunId, resetToken, setNavActions, onFeedbackPersisted,
|
|
28279
|
+
const { onReplaceTestBotSession, onResetTestBotSession, activeWorkspaceId, requestedRunId, resetToken, setNavActions, onFeedbackPersisted, onAddErrorToWorkbench } = props;
|
|
27628
28280
|
const deckStorageKey = "gambit:test:selected-deck";
|
|
27629
28281
|
const [testDecks, setTestDecks] = (0, import_react38.useState)([]);
|
|
27630
28282
|
const [selectedDeckId, setSelectedDeckId] = (0, import_react38.useState)(null);
|
|
@@ -28746,7 +29398,7 @@ function TestBotPage(props) {
|
|
|
28746
29398
|
handleStartAssistant,
|
|
28747
29399
|
onScore: handleTestBotScore,
|
|
28748
29400
|
onReasonChange: handleTestBotReason,
|
|
28749
|
-
|
|
29401
|
+
onAddErrorToWorkbench
|
|
28750
29402
|
})
|
|
28751
29403
|
]
|
|
28752
29404
|
})
|
|
@@ -29147,103 +29799,1421 @@ function BuildPage(props) {
|
|
|
29147
29799
|
});
|
|
29148
29800
|
}
|
|
29149
29801
|
|
|
29150
|
-
// simulator-ui/src/
|
|
29151
|
-
var
|
|
29152
|
-
|
|
29153
|
-
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
|
|
29160
|
-
|
|
29161
|
-
|
|
29162
|
-
|
|
29163
|
-
|
|
29164
|
-
|
|
29165
|
-
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
|
|
29169
|
-
|
|
29802
|
+
// simulator-ui/src/VerifyPage.tsx
|
|
29803
|
+
var import_jsx_runtime43 = __toESM(require_jsx_runtime());
|
|
29804
|
+
var import_react40 = __toESM(require__());
|
|
29805
|
+
|
|
29806
|
+
// simulator-ui/src/verify_metrics.ts
|
|
29807
|
+
var VERIFY_CONSISTENCY_THRESHOLDS = {
|
|
29808
|
+
minSampleSize: 6,
|
|
29809
|
+
instabilityScoreDelta: 1.5,
|
|
29810
|
+
pass: {
|
|
29811
|
+
agreementMin: 0.9,
|
|
29812
|
+
maxSpread: 1,
|
|
29813
|
+
maxInstabilityCount: 0
|
|
29814
|
+
},
|
|
29815
|
+
warn: {
|
|
29816
|
+
agreementMin: 0.75,
|
|
29817
|
+
maxSpread: 2,
|
|
29818
|
+
maxInstabilityCount: 2
|
|
29819
|
+
}
|
|
29820
|
+
};
|
|
29821
|
+
var pickPayload = (result) => {
|
|
29822
|
+
if (!result || typeof result !== "object") return {};
|
|
29823
|
+
const record = result;
|
|
29824
|
+
if (record.payload && typeof record.payload === "object" && !Array.isArray(record.payload)) {
|
|
29825
|
+
return record.payload;
|
|
29826
|
+
}
|
|
29827
|
+
return record;
|
|
29828
|
+
};
|
|
29829
|
+
var extractScoreReasonPass = (result) => {
|
|
29830
|
+
const payload = pickPayload(result);
|
|
29831
|
+
const score = typeof payload.score === "number" && Number.isFinite(payload.score) ? payload.score : void 0;
|
|
29832
|
+
const reason = typeof payload.reason === "string" ? payload.reason : void 0;
|
|
29833
|
+
if (typeof payload.pass === "boolean") {
|
|
29834
|
+
return {
|
|
29835
|
+
score,
|
|
29836
|
+
reason,
|
|
29837
|
+
pass: payload.pass
|
|
29170
29838
|
};
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
|
|
29174
|
-
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
setIsRunning(false);
|
|
29178
|
-
setStreamText("");
|
|
29839
|
+
}
|
|
29840
|
+
if (typeof payload.passed === "boolean") {
|
|
29841
|
+
return {
|
|
29842
|
+
score,
|
|
29843
|
+
reason,
|
|
29844
|
+
pass: payload.passed
|
|
29179
29845
|
};
|
|
29180
|
-
|
|
29181
|
-
|
|
29182
|
-
|
|
29183
|
-
|
|
29184
|
-
|
|
29185
|
-
|
|
29186
|
-
|
|
29187
|
-
}
|
|
29188
|
-
const parsedOffset = Number(event.lastEventId);
|
|
29189
|
-
if (Number.isFinite(parsedOffset)) {
|
|
29190
|
-
setDurableStreamOffset(streamId, parsedOffset + 1);
|
|
29191
|
-
}
|
|
29192
|
-
if (!msg || typeof msg !== "object") return;
|
|
29193
|
-
if (msg.type === "state") {
|
|
29194
|
-
setSavedState(msg.state);
|
|
29195
|
-
if (Array.isArray(msg.state.traces)) {
|
|
29196
|
-
setTraceEvents(msg.state.traces);
|
|
29197
|
-
}
|
|
29198
|
-
} else if (msg.type === "stream") {
|
|
29199
|
-
if (typeof msg.chunk === "string" && msg.chunk.length > 0) {
|
|
29200
|
-
setStreamText((prev) => prev + msg.chunk);
|
|
29201
|
-
}
|
|
29202
|
-
} else if (msg.type === "result") {
|
|
29203
|
-
setIsRunning(false);
|
|
29204
|
-
setStreamText("");
|
|
29205
|
-
} else if (msg.type === "trace" && msg.event) {
|
|
29206
|
-
setTraceEvents((prev) => [
|
|
29207
|
-
...prev,
|
|
29208
|
-
msg.event
|
|
29209
|
-
].slice(-200));
|
|
29210
|
-
} else if (msg.type === "error") {
|
|
29211
|
-
const message = msg.message ?? "Unknown error";
|
|
29212
|
-
setErrors((prev) => [
|
|
29213
|
-
...prev,
|
|
29214
|
-
message
|
|
29215
|
-
]);
|
|
29216
|
-
if (msg.runId || message !== "Run already in progress") {
|
|
29217
|
-
setIsRunning(false);
|
|
29218
|
-
}
|
|
29219
|
-
setStreamText("");
|
|
29220
|
-
}
|
|
29846
|
+
}
|
|
29847
|
+
if (typeof payload.verdict === "string") {
|
|
29848
|
+
const verdict = payload.verdict.trim().toLowerCase();
|
|
29849
|
+
if (verdict === "pass") return {
|
|
29850
|
+
score,
|
|
29851
|
+
reason,
|
|
29852
|
+
pass: true
|
|
29221
29853
|
};
|
|
29222
|
-
|
|
29223
|
-
|
|
29224
|
-
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
|
|
29228
|
-
|
|
29229
|
-
|
|
29230
|
-
|
|
29231
|
-
|
|
29232
|
-
|
|
29854
|
+
if (verdict === "fail") return {
|
|
29855
|
+
score,
|
|
29856
|
+
reason,
|
|
29857
|
+
pass: false
|
|
29858
|
+
};
|
|
29859
|
+
}
|
|
29860
|
+
if (typeof score === "number") {
|
|
29861
|
+
return {
|
|
29862
|
+
score,
|
|
29863
|
+
reason,
|
|
29864
|
+
pass: score >= 0
|
|
29865
|
+
};
|
|
29866
|
+
}
|
|
29867
|
+
return {
|
|
29868
|
+
score,
|
|
29869
|
+
reason
|
|
29870
|
+
};
|
|
29871
|
+
};
|
|
29872
|
+
var flattenRunExamples = (run) => {
|
|
29873
|
+
if (!run.result || typeof run.result !== "object") return [];
|
|
29874
|
+
const record = run.result;
|
|
29875
|
+
if (record.mode === "turns" && Array.isArray(record.turns)) {
|
|
29876
|
+
const buckets = [];
|
|
29877
|
+
record.turns.forEach((turn, fallbackIndex) => {
|
|
29878
|
+
if (!turn || typeof turn !== "object") return;
|
|
29879
|
+
const turnRecord = turn;
|
|
29880
|
+
const index = typeof turnRecord.index === "number" && Number.isFinite(turnRecord.index) ? Math.max(0, Math.round(turnRecord.index)) : fallbackIndex;
|
|
29881
|
+
const messageRefId = typeof turnRecord.messageRefId === "string" && turnRecord.messageRefId.trim().length > 0 ? turnRecord.messageRefId : void 0;
|
|
29882
|
+
const key = messageRefId ? `ref:${messageRefId}` : `turn:${index}`;
|
|
29883
|
+
const label = `Assistant turn ${fallbackIndex + 1}`;
|
|
29884
|
+
const parsed2 = extractScoreReasonPass(turnRecord.result);
|
|
29885
|
+
buckets.push({
|
|
29886
|
+
key,
|
|
29887
|
+
label,
|
|
29888
|
+
points: [
|
|
29889
|
+
{
|
|
29890
|
+
runId: run.id,
|
|
29891
|
+
runAt: run.runAt,
|
|
29892
|
+
score: parsed2.score,
|
|
29893
|
+
pass: parsed2.pass,
|
|
29894
|
+
reason: parsed2.reason,
|
|
29895
|
+
turnIndex: index,
|
|
29896
|
+
messageRefId
|
|
29897
|
+
}
|
|
29898
|
+
]
|
|
29899
|
+
});
|
|
29900
|
+
});
|
|
29901
|
+
return buckets;
|
|
29902
|
+
}
|
|
29903
|
+
const parsed = extractScoreReasonPass(run.result);
|
|
29904
|
+
return [
|
|
29905
|
+
{
|
|
29906
|
+
key: "conversation",
|
|
29907
|
+
label: "Conversation score",
|
|
29908
|
+
points: [
|
|
29909
|
+
{
|
|
29910
|
+
runId: run.id,
|
|
29911
|
+
runAt: run.runAt,
|
|
29912
|
+
score: parsed.score,
|
|
29913
|
+
pass: parsed.pass,
|
|
29914
|
+
reason: parsed.reason
|
|
29915
|
+
}
|
|
29916
|
+
]
|
|
29233
29917
|
}
|
|
29234
|
-
|
|
29235
|
-
|
|
29236
|
-
|
|
29237
|
-
|
|
29238
|
-
|
|
29239
|
-
|
|
29240
|
-
|
|
29241
|
-
|
|
29918
|
+
];
|
|
29919
|
+
};
|
|
29920
|
+
var median = (values) => {
|
|
29921
|
+
if (!values.length) return null;
|
|
29922
|
+
const sorted = [
|
|
29923
|
+
...values
|
|
29924
|
+
].sort((a, b) => a - b);
|
|
29925
|
+
const mid = Math.floor(sorted.length / 2);
|
|
29926
|
+
if (sorted.length % 2 === 1) return sorted[mid];
|
|
29927
|
+
return (sorted[mid - 1] + sorted[mid]) / 2;
|
|
29928
|
+
};
|
|
29929
|
+
var round2 = (value) => Math.round(value * 100) / 100;
|
|
29930
|
+
var resolveVerdict = (input) => {
|
|
29931
|
+
const t = VERIFY_CONSISTENCY_THRESHOLDS;
|
|
29932
|
+
if (input.sampleSize < t.minSampleSize) {
|
|
29933
|
+
return {
|
|
29934
|
+
verdict: "WARN",
|
|
29935
|
+
reason: `Need at least ${t.minSampleSize} samples before issuing a firm verdict.`
|
|
29242
29936
|
};
|
|
29243
|
-
}
|
|
29937
|
+
}
|
|
29938
|
+
if (input.agreementRate === null) {
|
|
29939
|
+
return {
|
|
29940
|
+
verdict: "WARN",
|
|
29941
|
+
reason: "No comparable pass/fail evidence was found in the sampled runs."
|
|
29942
|
+
};
|
|
29943
|
+
}
|
|
29944
|
+
const spreadMax = input.spreadMax ?? 0;
|
|
29945
|
+
if (input.agreementRate >= t.pass.agreementMin && spreadMax <= t.pass.maxSpread && input.instabilityCount <= t.pass.maxInstabilityCount) {
|
|
29946
|
+
return {
|
|
29947
|
+
verdict: "PASS",
|
|
29948
|
+
reason: "Agreement, spread, and instability all meet PASS thresholds."
|
|
29949
|
+
};
|
|
29950
|
+
}
|
|
29951
|
+
if (input.agreementRate >= t.warn.agreementMin && spreadMax <= t.warn.maxSpread && input.instabilityCount <= t.warn.maxInstabilityCount) {
|
|
29952
|
+
return {
|
|
29953
|
+
verdict: "WARN",
|
|
29954
|
+
reason: "Some variation was detected, but results remain within WARN thresholds."
|
|
29955
|
+
};
|
|
29956
|
+
}
|
|
29957
|
+
return {
|
|
29958
|
+
verdict: "FAIL",
|
|
29959
|
+
reason: "Agreement/spread instability exceeds WARN thresholds."
|
|
29960
|
+
};
|
|
29961
|
+
};
|
|
29962
|
+
function buildVerifyConsistencyReport(runs) {
|
|
29963
|
+
const completedRuns = runs.filter((run) => run.status === "completed");
|
|
29964
|
+
const sampleSize = completedRuns.length;
|
|
29965
|
+
const bucketsByKey = /* @__PURE__ */ new Map();
|
|
29966
|
+
completedRuns.forEach((run) => {
|
|
29967
|
+
flattenRunExamples(run).forEach((entry) => {
|
|
29968
|
+
const existing = bucketsByKey.get(entry.key);
|
|
29969
|
+
if (!existing) {
|
|
29970
|
+
bucketsByKey.set(entry.key, {
|
|
29971
|
+
key: entry.key,
|
|
29972
|
+
label: entry.label,
|
|
29973
|
+
points: [
|
|
29974
|
+
...entry.points
|
|
29975
|
+
]
|
|
29976
|
+
});
|
|
29977
|
+
return;
|
|
29978
|
+
}
|
|
29979
|
+
existing.points.push(...entry.points);
|
|
29980
|
+
});
|
|
29981
|
+
});
|
|
29982
|
+
const outliers = [];
|
|
29983
|
+
let agreementVotes = 0;
|
|
29984
|
+
let agreementTotal = 0;
|
|
29985
|
+
const scoreDeltas = [];
|
|
29986
|
+
bucketsByKey.forEach((bucket) => {
|
|
29987
|
+
const scores = bucket.points.map((point) => point.score).filter((score) => typeof score === "number" && Number.isFinite(score));
|
|
29988
|
+
const minScore = scores.length ? Math.min(...scores) : null;
|
|
29989
|
+
const maxScore = scores.length ? Math.max(...scores) : null;
|
|
29990
|
+
const scoreDelta = minScore !== null && maxScore !== null ? round2(maxScore - minScore) : null;
|
|
29991
|
+
const passVotes = bucket.points.map((point) => point.pass).filter((pass) => typeof pass === "boolean");
|
|
29992
|
+
const passCount = passVotes.filter((value) => value).length;
|
|
29993
|
+
const failCount = passVotes.length - passCount;
|
|
29994
|
+
const agreementRate2 = passVotes.length > 0 ? round2(Math.max(passCount, failCount) / passVotes.length) : null;
|
|
29995
|
+
if (passVotes.length > 0) {
|
|
29996
|
+
agreementVotes += Math.max(passCount, failCount);
|
|
29997
|
+
agreementTotal += passVotes.length;
|
|
29998
|
+
}
|
|
29999
|
+
if (scoreDelta !== null) {
|
|
30000
|
+
scoreDeltas.push(scoreDelta);
|
|
30001
|
+
}
|
|
30002
|
+
const passFlip = passCount > 0 && failCount > 0;
|
|
30003
|
+
const instability = passFlip || scoreDelta !== null && scoreDelta > VERIFY_CONSISTENCY_THRESHOLDS.instabilityScoreDelta;
|
|
30004
|
+
const minPoint = minScore === null ? void 0 : bucket.points.find((point) => point.score === minScore);
|
|
30005
|
+
const maxPoint = maxScore === null ? void 0 : bucket.points.find((point) => point.score === maxScore);
|
|
30006
|
+
outliers.push({
|
|
30007
|
+
key: bucket.key,
|
|
30008
|
+
label: bucket.label,
|
|
30009
|
+
sampleSize: bucket.points.length,
|
|
30010
|
+
agreementRate: agreementRate2,
|
|
30011
|
+
scoreDelta,
|
|
30012
|
+
passFlip,
|
|
30013
|
+
instability,
|
|
30014
|
+
minScore,
|
|
30015
|
+
maxScore,
|
|
30016
|
+
minRunId: minPoint?.runId,
|
|
30017
|
+
maxRunId: maxPoint?.runId,
|
|
30018
|
+
turnIndex: maxPoint?.turnIndex ?? minPoint?.turnIndex,
|
|
30019
|
+
messageRefId: maxPoint?.messageRefId ?? minPoint?.messageRefId
|
|
30020
|
+
});
|
|
30021
|
+
});
|
|
30022
|
+
outliers.sort((a, b) => {
|
|
30023
|
+
if (a.instability !== b.instability) return a.instability ? -1 : 1;
|
|
30024
|
+
if (a.passFlip !== b.passFlip) return a.passFlip ? -1 : 1;
|
|
30025
|
+
const aDelta = a.scoreDelta ?? -1;
|
|
30026
|
+
const bDelta = b.scoreDelta ?? -1;
|
|
30027
|
+
if (aDelta !== bDelta) return bDelta - aDelta;
|
|
30028
|
+
if (a.sampleSize !== b.sampleSize) return b.sampleSize - a.sampleSize;
|
|
30029
|
+
return a.label.localeCompare(b.label);
|
|
30030
|
+
});
|
|
30031
|
+
const agreementRate = agreementTotal > 0 ? round2(agreementVotes / agreementTotal) : null;
|
|
30032
|
+
const scoreSpreadMin = scoreDeltas.length ? Math.min(...scoreDeltas) : null;
|
|
30033
|
+
const scoreSpreadMax = scoreDeltas.length ? Math.max(...scoreDeltas) : null;
|
|
30034
|
+
const scoreSpreadMedian = median(scoreDeltas);
|
|
30035
|
+
const instabilityCount = outliers.filter((entry) => entry.instability).length;
|
|
30036
|
+
const verdict = resolveVerdict({
|
|
30037
|
+
sampleSize,
|
|
30038
|
+
agreementRate,
|
|
30039
|
+
spreadMax: scoreSpreadMax,
|
|
30040
|
+
instabilityCount
|
|
30041
|
+
});
|
|
30042
|
+
return {
|
|
30043
|
+
sampleSize,
|
|
30044
|
+
comparableExampleCount: outliers.length,
|
|
30045
|
+
agreementRate,
|
|
30046
|
+
scoreSpreadMin: scoreSpreadMin === null ? null : round2(scoreSpreadMin),
|
|
30047
|
+
scoreSpreadMedian: scoreSpreadMedian === null ? null : round2(scoreSpreadMedian),
|
|
30048
|
+
scoreSpreadMax: scoreSpreadMax === null ? null : round2(scoreSpreadMax),
|
|
30049
|
+
instabilityCount,
|
|
30050
|
+
verdict: verdict.verdict,
|
|
30051
|
+
verdictReason: verdict.reason,
|
|
30052
|
+
outliers
|
|
30053
|
+
};
|
|
30054
|
+
}
|
|
30055
|
+
|
|
30056
|
+
// simulator-ui/src/VerifyPage.tsx
|
|
30057
|
+
var MAX_BATCH_SIZE = 24;
|
|
30058
|
+
var MAX_BATCH_CONCURRENCY = 6;
|
|
30059
|
+
var DEFAULT_BATCH_SIZE = 8;
|
|
30060
|
+
var DEFAULT_BATCH_CONCURRENCY = 3;
|
|
30061
|
+
var NO_SCENARIO_RUN_VALUE = "__workspace_context__";
|
|
30062
|
+
var parseScenarioRunSummary2 = (value) => {
|
|
30063
|
+
if (!value || typeof value !== "object") return null;
|
|
30064
|
+
const summary = value;
|
|
30065
|
+
const scenarioRunId = typeof summary.scenarioRunId === "string" ? summary.scenarioRunId : null;
|
|
30066
|
+
if (!scenarioRunId) return null;
|
|
30067
|
+
return {
|
|
30068
|
+
scenarioRunId,
|
|
30069
|
+
lastEventSeq: typeof summary.lastEventSeq === "number" && Number.isFinite(summary.lastEventSeq) ? summary.lastEventSeq : void 0,
|
|
30070
|
+
updatedAt: typeof summary.updatedAt === "string" ? summary.updatedAt : void 0,
|
|
30071
|
+
selectedScenarioDeckId: typeof summary.selectedScenarioDeckId === "string" ? summary.selectedScenarioDeckId : void 0,
|
|
30072
|
+
selectedScenarioDeckLabel: typeof summary.selectedScenarioDeckLabel === "string" ? summary.selectedScenarioDeckLabel : void 0,
|
|
30073
|
+
scenarioConfigPath: typeof summary.scenarioConfigPath === "string" ? summary.scenarioConfigPath : void 0
|
|
30074
|
+
};
|
|
30075
|
+
};
|
|
30076
|
+
var getScenarioTitle3 = (summary) => {
|
|
30077
|
+
const fromDeckLabel = typeof summary.selectedScenarioDeckLabel === "string" && summary.selectedScenarioDeckLabel.trim().length > 0 ? summary.selectedScenarioDeckLabel : null;
|
|
30078
|
+
const fromDeckId = typeof summary.selectedScenarioDeckId === "string" && summary.selectedScenarioDeckId.trim().length > 0 ? scenarioNameFromValue(summary.selectedScenarioDeckId) ?? summary.selectedScenarioDeckId : null;
|
|
30079
|
+
const fromPath = scenarioNameFromValue(summary.scenarioConfigPath ?? null) ?? botFilename(summary.scenarioConfigPath ?? null);
|
|
30080
|
+
return fromDeckLabel ?? fromDeckId ?? fromPath ?? summary.scenarioRunId;
|
|
30081
|
+
};
|
|
30082
|
+
var scenarioRunIdFromCalibrationRun2 = (run) => {
|
|
30083
|
+
if (!run.input || typeof run.input !== "object") return null;
|
|
30084
|
+
const input = run.input;
|
|
30085
|
+
const session = input.session;
|
|
30086
|
+
if (!session || typeof session !== "object") return null;
|
|
30087
|
+
const meta = session.meta;
|
|
30088
|
+
if (!meta || typeof meta !== "object") return null;
|
|
30089
|
+
const scenarioRunId = meta.scenarioRunId;
|
|
30090
|
+
return typeof scenarioRunId === "string" && scenarioRunId.trim().length > 0 ? scenarioRunId : null;
|
|
30091
|
+
};
|
|
30092
|
+
var parseRunAt = (run) => {
|
|
30093
|
+
const parsed = Date.parse(run.runAt ?? "");
|
|
30094
|
+
return Number.isFinite(parsed) ? parsed : -1;
|
|
30095
|
+
};
|
|
30096
|
+
var clampInt = (value, min, max) => {
|
|
30097
|
+
const rounded = Number.isFinite(value) ? Math.round(value) : min;
|
|
30098
|
+
return Math.max(min, Math.min(max, rounded));
|
|
30099
|
+
};
|
|
30100
|
+
var formatSignedScore = (value) => {
|
|
30101
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "\u2014";
|
|
30102
|
+
return `${value > 0 ? "+" : ""}${value}`;
|
|
30103
|
+
};
|
|
30104
|
+
var scoreBadgeVariant = (value) => {
|
|
30105
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "ghost";
|
|
30106
|
+
if (value < 0) return "error";
|
|
30107
|
+
if (value > 0) return "completed";
|
|
30108
|
+
return "idle";
|
|
30109
|
+
};
|
|
30110
|
+
function VerifyPage({ setNavActions, onAppPathChange, activeWorkspaceId, composerChips, onComposerChipsChange }) {
|
|
30111
|
+
const { loading, error, graders, sessions, sessionDetail, loadData, loadSessionDetail } = useWorkspaceGrade();
|
|
30112
|
+
const workspaceRouting = useWorkspaceRouting();
|
|
30113
|
+
const [selectedSessionId, setSelectedSessionId] = (0, import_react40.useState)(activeWorkspaceId ?? null);
|
|
30114
|
+
const [selectedGraderId, setSelectedGraderId] = (0, import_react40.useState)(null);
|
|
30115
|
+
const [selectedScenarioRunId, setSelectedScenarioRunId] = (0, import_react40.useState)(null);
|
|
30116
|
+
const [batchSize, setBatchSize] = (0, import_react40.useState)(DEFAULT_BATCH_SIZE);
|
|
30117
|
+
const [batchConcurrency, setBatchConcurrency] = (0, import_react40.useState)(DEFAULT_BATCH_CONCURRENCY);
|
|
30118
|
+
const [batchState, setBatchState] = (0, import_react40.useState)({
|
|
30119
|
+
batchId: 0,
|
|
30120
|
+
status: "idle",
|
|
30121
|
+
requested: 0,
|
|
30122
|
+
concurrency: 0,
|
|
30123
|
+
completed: 0,
|
|
30124
|
+
failed: 0,
|
|
30125
|
+
active: 0,
|
|
30126
|
+
initialRunIds: [],
|
|
30127
|
+
requests: []
|
|
30128
|
+
});
|
|
30129
|
+
const [reportScope, setReportScope] = (0, import_react40.useState)("all_matching");
|
|
30130
|
+
const [inconsistentOnly, setInconsistentOnly] = (0, import_react40.useState)(false);
|
|
30131
|
+
const [exampleSort, setExampleSort] = (0, import_react40.useState)("default");
|
|
30132
|
+
const batchSeqRef = (0, import_react40.useRef)(0);
|
|
30133
|
+
const updateVerifyPath = (0, import_react40.useCallback)((sessionId) => {
|
|
30134
|
+
const targetPath = buildVerifyPath(sessionId);
|
|
30135
|
+
if (window.location.pathname === targetPath) return;
|
|
30136
|
+
window.history.replaceState({}, "", targetPath);
|
|
30137
|
+
onAppPathChange?.(targetPath);
|
|
30138
|
+
}, [
|
|
30139
|
+
onAppPathChange
|
|
30140
|
+
]);
|
|
30141
|
+
const navigateToAppPath = (0, import_react40.useCallback)((nextPath) => {
|
|
30142
|
+
if (window.location.pathname === nextPath) return;
|
|
30143
|
+
window.history.pushState({}, "", nextPath);
|
|
30144
|
+
onAppPathChange?.(nextPath);
|
|
30145
|
+
}, [
|
|
30146
|
+
onAppPathChange
|
|
30147
|
+
]);
|
|
30148
|
+
const handleInternalLinkClick = (0, import_react40.useCallback)((event, href) => {
|
|
30149
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button !== 0) {
|
|
30150
|
+
return;
|
|
30151
|
+
}
|
|
30152
|
+
event.preventDefault();
|
|
30153
|
+
navigateToAppPath(href);
|
|
30154
|
+
}, [
|
|
30155
|
+
navigateToAppPath
|
|
30156
|
+
]);
|
|
30157
|
+
const loadVerifyData = (0, import_react40.useCallback)(async () => {
|
|
30158
|
+
await loadData({
|
|
30159
|
+
workspaceId: activeWorkspaceId ?? null
|
|
30160
|
+
});
|
|
30161
|
+
}, [
|
|
30162
|
+
activeWorkspaceId,
|
|
30163
|
+
loadData
|
|
30164
|
+
]);
|
|
30165
|
+
(0, import_react40.useEffect)(() => {
|
|
30166
|
+
loadVerifyData();
|
|
30167
|
+
}, [
|
|
30168
|
+
loadVerifyData
|
|
30169
|
+
]);
|
|
30170
|
+
(0, import_react40.useEffect)(() => {
|
|
30171
|
+
setSelectedSessionId((prev) => {
|
|
30172
|
+
if (activeWorkspaceId) return activeWorkspaceId;
|
|
30173
|
+
if (prev && sessions.some((session) => session.id === prev)) return prev;
|
|
30174
|
+
return sessions[0]?.id ?? null;
|
|
30175
|
+
});
|
|
30176
|
+
}, [
|
|
30177
|
+
activeWorkspaceId,
|
|
30178
|
+
sessions
|
|
30179
|
+
]);
|
|
30180
|
+
(0, import_react40.useEffect)(() => {
|
|
30181
|
+
setSelectedGraderId((prev) => {
|
|
30182
|
+
if (prev && graders.some((grader) => grader.id === prev)) return prev;
|
|
30183
|
+
return graders[0]?.id ?? null;
|
|
30184
|
+
});
|
|
30185
|
+
}, [
|
|
30186
|
+
graders
|
|
30187
|
+
]);
|
|
30188
|
+
(0, import_react40.useEffect)(() => {
|
|
30189
|
+
if (!selectedSessionId) return;
|
|
30190
|
+
updateVerifyPath(selectedSessionId);
|
|
30191
|
+
}, [
|
|
30192
|
+
selectedSessionId,
|
|
30193
|
+
updateVerifyPath
|
|
30194
|
+
]);
|
|
30195
|
+
(0, import_react40.useEffect)(() => {
|
|
30196
|
+
loadSessionDetail(selectedSessionId).catch((err) => {
|
|
30197
|
+
console.error(err);
|
|
30198
|
+
});
|
|
30199
|
+
}, [
|
|
30200
|
+
loadSessionDetail,
|
|
30201
|
+
selectedSessionId
|
|
30202
|
+
]);
|
|
30203
|
+
const selectedSession = (0, import_react40.useMemo)(() => sessions.find((session) => session.id === selectedSessionId) ?? null, [
|
|
30204
|
+
sessions,
|
|
30205
|
+
selectedSessionId
|
|
30206
|
+
]);
|
|
30207
|
+
const selectedGrader = (0, import_react40.useMemo)(() => graders.find((grader) => grader.id === selectedGraderId) ?? null, [
|
|
30208
|
+
graders,
|
|
30209
|
+
selectedGraderId
|
|
30210
|
+
]);
|
|
30211
|
+
const scenarioRunOptions = (0, import_react40.useMemo)(() => {
|
|
30212
|
+
const meta = sessionDetail?.meta && typeof sessionDetail.meta === "object" ? sessionDetail.meta : {};
|
|
30213
|
+
const fromList = Array.isArray(meta.scenarioRunSummaries) ? meta.scenarioRunSummaries.map((entry) => parseScenarioRunSummary2(entry)) : [];
|
|
30214
|
+
const fromCurrent = parseScenarioRunSummary2(meta.scenarioRunSummary);
|
|
30215
|
+
const all = [
|
|
30216
|
+
...fromList,
|
|
30217
|
+
fromCurrent
|
|
30218
|
+
].filter((entry) => Boolean(entry));
|
|
30219
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
30220
|
+
all.forEach((entry) => {
|
|
30221
|
+
const existing = deduped.get(entry.scenarioRunId);
|
|
30222
|
+
if (!existing) {
|
|
30223
|
+
deduped.set(entry.scenarioRunId, entry);
|
|
30224
|
+
return;
|
|
30225
|
+
}
|
|
30226
|
+
const existingSeq = existing.lastEventSeq ?? -1;
|
|
30227
|
+
const nextSeq = entry.lastEventSeq ?? -1;
|
|
30228
|
+
if (nextSeq > existingSeq) {
|
|
30229
|
+
deduped.set(entry.scenarioRunId, entry);
|
|
30230
|
+
return;
|
|
30231
|
+
}
|
|
30232
|
+
if (nextSeq === existingSeq) {
|
|
30233
|
+
const existingStamp = existing.updatedAt ?? "";
|
|
30234
|
+
const nextStamp = entry.updatedAt ?? "";
|
|
30235
|
+
if (nextStamp.localeCompare(existingStamp) > 0) {
|
|
30236
|
+
deduped.set(entry.scenarioRunId, entry);
|
|
30237
|
+
}
|
|
30238
|
+
}
|
|
30239
|
+
});
|
|
30240
|
+
return [
|
|
30241
|
+
...deduped.values()
|
|
30242
|
+
].sort((a, b) => {
|
|
30243
|
+
const aTime = Date.parse(a.updatedAt ?? "");
|
|
30244
|
+
const bTime = Date.parse(b.updatedAt ?? "");
|
|
30245
|
+
const aValidTime = Number.isFinite(aTime) ? aTime : -1;
|
|
30246
|
+
const bValidTime = Number.isFinite(bTime) ? bTime : -1;
|
|
30247
|
+
if (aValidTime !== bValidTime) return bValidTime - aValidTime;
|
|
30248
|
+
const aSeq = a.lastEventSeq ?? -1;
|
|
30249
|
+
const bSeq = b.lastEventSeq ?? -1;
|
|
30250
|
+
if (aSeq !== bSeq) return bSeq - aSeq;
|
|
30251
|
+
return b.scenarioRunId.localeCompare(a.scenarioRunId);
|
|
30252
|
+
});
|
|
30253
|
+
}, [
|
|
30254
|
+
sessionDetail?.meta
|
|
30255
|
+
]);
|
|
30256
|
+
(0, import_react40.useEffect)(() => {
|
|
30257
|
+
const hasOption = (runId) => Boolean(runId && scenarioRunOptions.some((entry) => entry.scenarioRunId === runId));
|
|
30258
|
+
const meta = sessionDetail?.meta && typeof sessionDetail.meta === "object" ? sessionDetail.meta : {};
|
|
30259
|
+
const currentScenarioRunId = typeof meta.scenarioRunId === "string" && meta.scenarioRunId.trim().length > 0 ? meta.scenarioRunId : null;
|
|
30260
|
+
const nextRunId = hasOption(workspaceRouting.testRunId) ? workspaceRouting.testRunId : hasOption(selectedScenarioRunId) ? selectedScenarioRunId : hasOption(currentScenarioRunId) ? currentScenarioRunId : scenarioRunOptions[0]?.scenarioRunId ?? null;
|
|
30261
|
+
if (selectedScenarioRunId !== nextRunId) {
|
|
30262
|
+
setSelectedScenarioRunId(nextRunId);
|
|
30263
|
+
}
|
|
30264
|
+
if (workspaceRouting.testRunId !== nextRunId) {
|
|
30265
|
+
workspaceRouting.setTestRunId(nextRunId);
|
|
30266
|
+
}
|
|
30267
|
+
}, [
|
|
30268
|
+
scenarioRunOptions,
|
|
30269
|
+
selectedScenarioRunId,
|
|
30270
|
+
sessionDetail?.meta,
|
|
30271
|
+
workspaceRouting
|
|
30272
|
+
]);
|
|
30273
|
+
const sessionRuns = (0, import_react40.useMemo)(() => {
|
|
30274
|
+
if (!selectedSession?.gradingRuns) return [];
|
|
30275
|
+
return [
|
|
30276
|
+
...selectedSession.gradingRuns
|
|
30277
|
+
].sort((a, b) => parseRunAt(b) - parseRunAt(a));
|
|
30278
|
+
}, [
|
|
30279
|
+
selectedSession?.gradingRuns
|
|
30280
|
+
]);
|
|
30281
|
+
const filteredRuns = (0, import_react40.useMemo)(() => {
|
|
30282
|
+
const latestScenarioRunIdFromRuns = sessionRuns.map((run) => scenarioRunIdFromCalibrationRun2(run)).find((runId) => Boolean(runId));
|
|
30283
|
+
const hasOption = (runId) => Boolean(runId && scenarioRunOptions.some((entry) => entry.scenarioRunId === runId));
|
|
30284
|
+
const meta = sessionDetail?.meta && typeof sessionDetail.meta === "object" ? sessionDetail.meta : {};
|
|
30285
|
+
const currentScenarioRunId = typeof meta.scenarioRunId === "string" && meta.scenarioRunId.trim().length > 0 ? meta.scenarioRunId : null;
|
|
30286
|
+
const activeScenarioRunFilterId = hasOption(workspaceRouting.testRunId) ? workspaceRouting.testRunId : hasOption(selectedScenarioRunId) ? selectedScenarioRunId : hasOption(currentScenarioRunId) ? currentScenarioRunId : scenarioRunOptions[0]?.scenarioRunId ?? latestScenarioRunIdFromRuns ?? null;
|
|
30287
|
+
return sessionRuns.filter((run) => {
|
|
30288
|
+
if (selectedGraderId && run.graderId !== selectedGraderId) return false;
|
|
30289
|
+
if (!activeScenarioRunFilterId) return true;
|
|
30290
|
+
return scenarioRunIdFromCalibrationRun2(run) === activeScenarioRunFilterId;
|
|
30291
|
+
});
|
|
30292
|
+
}, [
|
|
30293
|
+
scenarioRunOptions,
|
|
30294
|
+
selectedGraderId,
|
|
30295
|
+
selectedScenarioRunId,
|
|
30296
|
+
sessionDetail?.meta,
|
|
30297
|
+
sessionRuns,
|
|
30298
|
+
workspaceRouting.testRunId
|
|
30299
|
+
]);
|
|
30300
|
+
const runConsistencySample = (0, import_react40.useCallback)(async (payload) => {
|
|
30301
|
+
const res = await fetch("/api/calibrate/run", {
|
|
30302
|
+
method: "POST",
|
|
30303
|
+
headers: {
|
|
30304
|
+
"content-type": "application/json"
|
|
30305
|
+
},
|
|
30306
|
+
body: JSON.stringify(payload)
|
|
30307
|
+
});
|
|
30308
|
+
const body = await res.json().catch(() => ({}));
|
|
30309
|
+
if (!res.ok) {
|
|
30310
|
+
throw new Error(body.error ?? res.statusText);
|
|
30311
|
+
}
|
|
30312
|
+
if (!body.run) {
|
|
30313
|
+
throw new Error(body.error ?? "Calibration run response missing run payload");
|
|
30314
|
+
}
|
|
30315
|
+
return {
|
|
30316
|
+
run: body.run,
|
|
30317
|
+
error: body.error
|
|
30318
|
+
};
|
|
30319
|
+
}, []);
|
|
30320
|
+
const updateBatchRequest = (0, import_react40.useCallback)((batchId, index, patch) => {
|
|
30321
|
+
setBatchState((prev) => {
|
|
30322
|
+
if (prev.batchId !== batchId) return prev;
|
|
30323
|
+
if (index < 0 || index >= prev.requests.length) return prev;
|
|
30324
|
+
const nextRequests = prev.requests.map((request, requestIndex) => requestIndex === index ? {
|
|
30325
|
+
...request,
|
|
30326
|
+
...patch
|
|
30327
|
+
} : request);
|
|
30328
|
+
const completed = nextRequests.filter((request) => request.status === "completed").length;
|
|
30329
|
+
const failed = nextRequests.filter((request) => request.status === "error").length;
|
|
30330
|
+
const active = nextRequests.filter((request) => request.status === "running").length;
|
|
30331
|
+
const terminal = completed + failed === prev.requested && active === 0;
|
|
30332
|
+
const nextStatus = terminal ? failed > 0 ? "error" : "completed" : "running";
|
|
30333
|
+
return {
|
|
30334
|
+
...prev,
|
|
30335
|
+
requests: nextRequests,
|
|
30336
|
+
completed,
|
|
30337
|
+
failed,
|
|
30338
|
+
active,
|
|
30339
|
+
status: nextStatus,
|
|
30340
|
+
finishedAt: terminal ? (/* @__PURE__ */ new Date()).toISOString() : prev.finishedAt
|
|
30341
|
+
};
|
|
30342
|
+
});
|
|
30343
|
+
}, []);
|
|
30344
|
+
const runConsistencyBatch = (0, import_react40.useCallback)(async () => {
|
|
30345
|
+
if (!selectedSessionId || !selectedGraderId) return;
|
|
30346
|
+
const nextBatchSize = clampInt(batchSize, 1, MAX_BATCH_SIZE);
|
|
30347
|
+
const nextConcurrency = clampInt(batchConcurrency, 1, Math.min(MAX_BATCH_CONCURRENCY, nextBatchSize));
|
|
30348
|
+
const batchId = batchSeqRef.current + 1;
|
|
30349
|
+
batchSeqRef.current = batchId;
|
|
30350
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
30351
|
+
const initialRunIds = filteredRuns.map((run) => run.id);
|
|
30352
|
+
const initialRequests = Array.from({
|
|
30353
|
+
length: nextBatchSize
|
|
30354
|
+
}, (_, index) => ({
|
|
30355
|
+
requestId: `${batchId}:${index + 1}`,
|
|
30356
|
+
status: "queued"
|
|
30357
|
+
}));
|
|
30358
|
+
setBatchState({
|
|
30359
|
+
batchId,
|
|
30360
|
+
status: "running",
|
|
30361
|
+
startedAt: now,
|
|
30362
|
+
finishedAt: void 0,
|
|
30363
|
+
requested: nextBatchSize,
|
|
30364
|
+
concurrency: nextConcurrency,
|
|
30365
|
+
completed: 0,
|
|
30366
|
+
failed: 0,
|
|
30367
|
+
active: 0,
|
|
30368
|
+
initialRunIds,
|
|
30369
|
+
requests: initialRequests
|
|
30370
|
+
});
|
|
30371
|
+
let cursor = 0;
|
|
30372
|
+
const workers = Array.from({
|
|
30373
|
+
length: nextConcurrency
|
|
30374
|
+
}, () => (async () => {
|
|
30375
|
+
while (true) {
|
|
30376
|
+
const nextIndex = cursor;
|
|
30377
|
+
cursor += 1;
|
|
30378
|
+
if (nextIndex >= nextBatchSize) return;
|
|
30379
|
+
if (batchSeqRef.current !== batchId) return;
|
|
30380
|
+
updateBatchRequest(batchId, nextIndex, {
|
|
30381
|
+
status: "running"
|
|
30382
|
+
});
|
|
30383
|
+
try {
|
|
30384
|
+
const response = await runConsistencySample({
|
|
30385
|
+
workspaceId: selectedSessionId,
|
|
30386
|
+
graderId: selectedGraderId,
|
|
30387
|
+
scenarioRunId: selectedScenarioRunId ?? void 0
|
|
30388
|
+
});
|
|
30389
|
+
if (batchSeqRef.current !== batchId) return;
|
|
30390
|
+
if (response.run.status !== "completed") {
|
|
30391
|
+
updateBatchRequest(batchId, nextIndex, {
|
|
30392
|
+
status: "error",
|
|
30393
|
+
runId: response.run.id,
|
|
30394
|
+
error: response.run.error ?? `Calibration run ended with status ${response.run.status}`
|
|
30395
|
+
});
|
|
30396
|
+
continue;
|
|
30397
|
+
}
|
|
30398
|
+
updateBatchRequest(batchId, nextIndex, {
|
|
30399
|
+
status: "completed",
|
|
30400
|
+
runId: response.run.id
|
|
30401
|
+
});
|
|
30402
|
+
} catch (err) {
|
|
30403
|
+
if (batchSeqRef.current !== batchId) return;
|
|
30404
|
+
updateBatchRequest(batchId, nextIndex, {
|
|
30405
|
+
status: "error",
|
|
30406
|
+
error: err instanceof Error ? err.message : String(err)
|
|
30407
|
+
});
|
|
30408
|
+
}
|
|
30409
|
+
}
|
|
30410
|
+
})());
|
|
30411
|
+
await Promise.all(workers);
|
|
30412
|
+
if (batchSeqRef.current !== batchId) return;
|
|
30413
|
+
await loadData({
|
|
30414
|
+
workspaceId: selectedSessionId
|
|
30415
|
+
}).catch(() => {
|
|
30416
|
+
});
|
|
30417
|
+
}, [
|
|
30418
|
+
batchConcurrency,
|
|
30419
|
+
batchSize,
|
|
30420
|
+
filteredRuns,
|
|
30421
|
+
loadData,
|
|
30422
|
+
runConsistencySample,
|
|
30423
|
+
selectedGraderId,
|
|
30424
|
+
selectedScenarioRunId,
|
|
30425
|
+
selectedSessionId,
|
|
30426
|
+
updateBatchRequest
|
|
30427
|
+
]);
|
|
30428
|
+
const batchInitialRunIdSet = (0, import_react40.useMemo)(() => new Set(batchState.initialRunIds), [
|
|
30429
|
+
batchState.initialRunIds
|
|
30430
|
+
]);
|
|
30431
|
+
const activeBatchRuns = (0, import_react40.useMemo)(() => {
|
|
30432
|
+
if (!batchState.startedAt) return [];
|
|
30433
|
+
const startedAt = Date.parse(batchState.startedAt);
|
|
30434
|
+
const hasStartedAt = Number.isFinite(startedAt);
|
|
30435
|
+
return filteredRuns.filter((run) => {
|
|
30436
|
+
if (batchInitialRunIdSet.has(run.id)) return false;
|
|
30437
|
+
if (!hasStartedAt) return true;
|
|
30438
|
+
const runAt = parseRunAt(run);
|
|
30439
|
+
return runAt < 0 || runAt >= startedAt - 2e3;
|
|
30440
|
+
});
|
|
30441
|
+
}, [
|
|
30442
|
+
batchInitialRunIdSet,
|
|
30443
|
+
batchState.startedAt,
|
|
30444
|
+
filteredRuns
|
|
30445
|
+
]);
|
|
30446
|
+
const completedBatchRuns = (0, import_react40.useMemo)(() => activeBatchRuns.filter((run) => run.status === "completed"), [
|
|
30447
|
+
activeBatchRuns
|
|
30448
|
+
]);
|
|
30449
|
+
const historicalCompletedRuns = (0, import_react40.useMemo)(() => filteredRuns.filter((run) => run.status === "completed"), [
|
|
30450
|
+
filteredRuns
|
|
30451
|
+
]);
|
|
30452
|
+
const reportRuns = (0, import_react40.useMemo)(() => reportScope === "current_batch" ? completedBatchRuns : historicalCompletedRuns, [
|
|
30453
|
+
completedBatchRuns,
|
|
30454
|
+
historicalCompletedRuns,
|
|
30455
|
+
reportScope
|
|
30456
|
+
]);
|
|
30457
|
+
const consistencyReport = (0, import_react40.useMemo)(() => buildVerifyConsistencyReport(reportRuns), [
|
|
30458
|
+
reportRuns
|
|
30459
|
+
]);
|
|
30460
|
+
const queuedCount = (0, import_react40.useMemo)(() => batchState.requests.filter((request) => request.status === "queued").length, [
|
|
30461
|
+
batchState.requests
|
|
30462
|
+
]);
|
|
30463
|
+
const canRun = Boolean(selectedSessionId && selectedGraderId && batchState.status !== "running");
|
|
30464
|
+
const displayedOutliers = (0, import_react40.useMemo)(() => {
|
|
30465
|
+
const filtered = inconsistentOnly ? consistencyReport.outliers.filter((outlier) => outlier.instability) : consistencyReport.outliers;
|
|
30466
|
+
if (exampleSort === "default") return filtered;
|
|
30467
|
+
const next = [
|
|
30468
|
+
...filtered
|
|
30469
|
+
];
|
|
30470
|
+
if (exampleSort === "delta_desc") {
|
|
30471
|
+
next.sort((a, b) => {
|
|
30472
|
+
const aDelta = a.scoreDelta ?? -1;
|
|
30473
|
+
const bDelta = b.scoreDelta ?? -1;
|
|
30474
|
+
if (aDelta !== bDelta) return bDelta - aDelta;
|
|
30475
|
+
return a.label.localeCompare(b.label);
|
|
30476
|
+
});
|
|
30477
|
+
return next;
|
|
30478
|
+
}
|
|
30479
|
+
if (exampleSort === "agreement_asc") {
|
|
30480
|
+
next.sort((a, b) => {
|
|
30481
|
+
const aAgreement = a.agreementRate ?? Number.POSITIVE_INFINITY;
|
|
30482
|
+
const bAgreement = b.agreementRate ?? Number.POSITIVE_INFINITY;
|
|
30483
|
+
if (aAgreement !== bAgreement) return aAgreement - bAgreement;
|
|
30484
|
+
return a.label.localeCompare(b.label);
|
|
30485
|
+
});
|
|
30486
|
+
return next;
|
|
30487
|
+
}
|
|
30488
|
+
if (exampleSort === "samples_desc") {
|
|
30489
|
+
next.sort((a, b) => {
|
|
30490
|
+
if (a.sampleSize !== b.sampleSize) return b.sampleSize - a.sampleSize;
|
|
30491
|
+
return a.label.localeCompare(b.label);
|
|
30492
|
+
});
|
|
30493
|
+
return next;
|
|
30494
|
+
}
|
|
30495
|
+
next.sort((a, b) => a.label.localeCompare(b.label));
|
|
30496
|
+
return next;
|
|
30497
|
+
}, [
|
|
30498
|
+
consistencyReport.outliers,
|
|
30499
|
+
exampleSort,
|
|
30500
|
+
inconsistentOnly
|
|
30501
|
+
]);
|
|
30502
|
+
const reportScopeLabel = reportScope === "current_batch" ? "current batch" : "all matching runs";
|
|
30503
|
+
const resolvedComposerChips = (0, import_react40.useMemo)(() => composerChips ?? [], [
|
|
30504
|
+
composerChips
|
|
30505
|
+
]);
|
|
30506
|
+
const composerChipIds = (0, import_react40.useMemo)(() => new Set(resolvedComposerChips.map((chip) => chip.chipId)), [
|
|
30507
|
+
resolvedComposerChips
|
|
30508
|
+
]);
|
|
30509
|
+
const mergeComposerChip = (0, import_react40.useCallback)((base, chip) => {
|
|
30510
|
+
const next = [
|
|
30511
|
+
...base
|
|
30512
|
+
];
|
|
30513
|
+
const existingIndex = next.findIndex((entry) => entry.chipId === chip.chipId);
|
|
30514
|
+
if (existingIndex >= 0) {
|
|
30515
|
+
next[existingIndex] = {
|
|
30516
|
+
...next[existingIndex],
|
|
30517
|
+
...chip,
|
|
30518
|
+
enabled: true
|
|
30519
|
+
};
|
|
30520
|
+
return next;
|
|
30521
|
+
}
|
|
30522
|
+
next.push(chip);
|
|
30523
|
+
return next;
|
|
30524
|
+
}, []);
|
|
30525
|
+
const addComposerChip = (0, import_react40.useCallback)((chip) => {
|
|
30526
|
+
if (!onComposerChipsChange) return;
|
|
30527
|
+
onComposerChipsChange(mergeComposerChip(resolvedComposerChips, chip));
|
|
30528
|
+
}, [
|
|
30529
|
+
mergeComposerChip,
|
|
30530
|
+
onComposerChipsChange,
|
|
30531
|
+
resolvedComposerChips
|
|
30532
|
+
]);
|
|
30533
|
+
const removeComposerChip = (0, import_react40.useCallback)((chipId) => {
|
|
30534
|
+
if (!onComposerChipsChange) return;
|
|
30535
|
+
onComposerChipsChange(resolvedComposerChips.filter((chip) => chip.chipId !== chipId));
|
|
30536
|
+
}, [
|
|
30537
|
+
onComposerChipsChange,
|
|
30538
|
+
resolvedComposerChips
|
|
30539
|
+
]);
|
|
30540
|
+
const buildOutlierChip = (0, import_react40.useCallback)((outlier) => {
|
|
30541
|
+
const chipId = `verify:${selectedSessionId ?? ""}:${outlier.key}`;
|
|
30542
|
+
const runId = outlier.maxRunId ?? outlier.minRunId;
|
|
30543
|
+
const score = outlier.maxScore ?? outlier.minScore ?? void 0;
|
|
30544
|
+
const agreementText = outlier.agreementRate === null ? "agreement unavailable" : `agreement ${Math.round(outlier.agreementRate * 100)}%`;
|
|
30545
|
+
const deltaText = outlier.scoreDelta === null ? "delta unavailable" : `delta ${outlier.scoreDelta}`;
|
|
30546
|
+
return {
|
|
30547
|
+
chipId,
|
|
30548
|
+
source: "verify_outlier",
|
|
30549
|
+
workspaceId: selectedSessionId ?? void 0,
|
|
30550
|
+
runId,
|
|
30551
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30552
|
+
outlierKey: outlier.key,
|
|
30553
|
+
instability: outlier.instability,
|
|
30554
|
+
score,
|
|
30555
|
+
message: `Verify outlier ${outlier.label}: ${agreementText}, ${deltaText}, samples ${outlier.sampleSize}`,
|
|
30556
|
+
enabled: true
|
|
30557
|
+
};
|
|
30558
|
+
}, [
|
|
30559
|
+
selectedSessionId
|
|
30560
|
+
]);
|
|
30561
|
+
(0, import_react40.useEffect)(() => {
|
|
30562
|
+
if (!setNavActions) return;
|
|
30563
|
+
setNavActions(null);
|
|
30564
|
+
return () => setNavActions(null);
|
|
30565
|
+
}, [
|
|
30566
|
+
setNavActions
|
|
30567
|
+
]);
|
|
30568
|
+
(0, import_react40.useEffect)(() => {
|
|
30569
|
+
return () => {
|
|
30570
|
+
batchSeqRef.current += 1;
|
|
30571
|
+
};
|
|
30572
|
+
}, []);
|
|
30573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PageShell, {
|
|
30574
|
+
className: "verify-shell",
|
|
30575
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(PageGrid, {
|
|
30576
|
+
as: "main",
|
|
30577
|
+
className: "verify-layout",
|
|
30578
|
+
children: [
|
|
30579
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(Panel_default, {
|
|
30580
|
+
className: "verify-controls",
|
|
30581
|
+
children: [
|
|
30582
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30583
|
+
className: "verify-controls-header",
|
|
30584
|
+
children: [
|
|
30585
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", {
|
|
30586
|
+
children: "Verify consistency"
|
|
30587
|
+
}),
|
|
30588
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", {
|
|
30589
|
+
className: "secondary-note",
|
|
30590
|
+
children: "Run repeated grading checks against one grader and scenario."
|
|
30591
|
+
})
|
|
30592
|
+
]
|
|
30593
|
+
}),
|
|
30594
|
+
scenarioRunOptions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Listbox, {
|
|
30595
|
+
label: "Scenario run",
|
|
30596
|
+
value: selectedScenarioRunId ?? NO_SCENARIO_RUN_VALUE,
|
|
30597
|
+
onChange: (runId) => {
|
|
30598
|
+
if (runId === NO_SCENARIO_RUN_VALUE) {
|
|
30599
|
+
setSelectedScenarioRunId(null);
|
|
30600
|
+
workspaceRouting.setTestRunId(null);
|
|
30601
|
+
return;
|
|
30602
|
+
}
|
|
30603
|
+
setSelectedScenarioRunId(runId);
|
|
30604
|
+
workspaceRouting.setTestRunId(runId);
|
|
30605
|
+
},
|
|
30606
|
+
options: [
|
|
30607
|
+
{
|
|
30608
|
+
value: NO_SCENARIO_RUN_VALUE,
|
|
30609
|
+
label: "Current workspace context",
|
|
30610
|
+
meta: "Run without a prior scenario run binding"
|
|
30611
|
+
},
|
|
30612
|
+
...scenarioRunOptions.map((entry) => ({
|
|
30613
|
+
value: entry.scenarioRunId,
|
|
30614
|
+
label: getScenarioTitle3(entry),
|
|
30615
|
+
meta: [
|
|
30616
|
+
entry.updatedAt ? formatTimestampShort(entry.updatedAt) : null,
|
|
30617
|
+
entry.scenarioRunId
|
|
30618
|
+
].filter(Boolean).join(" \xB7 ")
|
|
30619
|
+
}))
|
|
30620
|
+
],
|
|
30621
|
+
placeholder: "Select scenario run"
|
|
30622
|
+
}),
|
|
30623
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Listbox, {
|
|
30624
|
+
label: "Grader",
|
|
30625
|
+
value: selectedGraderId ?? "",
|
|
30626
|
+
onChange: (value) => setSelectedGraderId(value.length ? value : null),
|
|
30627
|
+
options: graders.map((grader) => ({
|
|
30628
|
+
value: grader.id,
|
|
30629
|
+
label: grader.label,
|
|
30630
|
+
meta: botFilename(grader.path ?? null) ?? void 0
|
|
30631
|
+
})),
|
|
30632
|
+
placeholder: "Select grader",
|
|
30633
|
+
disabled: graders.length === 0
|
|
30634
|
+
}),
|
|
30635
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30636
|
+
className: "verify-number-grid",
|
|
30637
|
+
children: [
|
|
30638
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("label", {
|
|
30639
|
+
className: "verify-number-field",
|
|
30640
|
+
children: [
|
|
30641
|
+
"Batch size",
|
|
30642
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("input", {
|
|
30643
|
+
type: "number",
|
|
30644
|
+
min: 1,
|
|
30645
|
+
max: MAX_BATCH_SIZE,
|
|
30646
|
+
value: batchSize,
|
|
30647
|
+
onChange: (event) => setBatchSize(clampInt(Number(event.target.value), 1, MAX_BATCH_SIZE))
|
|
30648
|
+
})
|
|
30649
|
+
]
|
|
30650
|
+
}),
|
|
30651
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("label", {
|
|
30652
|
+
className: "verify-number-field",
|
|
30653
|
+
children: [
|
|
30654
|
+
"Concurrency",
|
|
30655
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("input", {
|
|
30656
|
+
type: "number",
|
|
30657
|
+
min: 1,
|
|
30658
|
+
max: MAX_BATCH_CONCURRENCY,
|
|
30659
|
+
value: batchConcurrency,
|
|
30660
|
+
onChange: (event) => setBatchConcurrency(clampInt(Number(event.target.value), 1, MAX_BATCH_CONCURRENCY))
|
|
30661
|
+
})
|
|
30662
|
+
]
|
|
30663
|
+
})
|
|
30664
|
+
]
|
|
30665
|
+
}),
|
|
30666
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, {
|
|
30667
|
+
variant: "primary",
|
|
30668
|
+
onClick: runConsistencyBatch,
|
|
30669
|
+
disabled: !canRun,
|
|
30670
|
+
children: batchState.status === "running" ? "Running consistency batch\u2026" : "Run consistency batch"
|
|
30671
|
+
}),
|
|
30672
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Callout, {
|
|
30673
|
+
variant: "emphasis",
|
|
30674
|
+
title: "Build assistant stays available",
|
|
30675
|
+
children: "Use the chat drawer toggle in the top-right corner to investigate and iterate while this page remains open."
|
|
30676
|
+
}),
|
|
30677
|
+
sessions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Callout, {
|
|
30678
|
+
children: "No workspaces found yet. Run a Test scenario first so Verify has evidence to grade."
|
|
30679
|
+
}),
|
|
30680
|
+
graders.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(Callout, {
|
|
30681
|
+
children: [
|
|
30682
|
+
"No graders are available. Add ",
|
|
30683
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("code", {
|
|
30684
|
+
children: "[[graders]]"
|
|
30685
|
+
}),
|
|
30686
|
+
" ",
|
|
30687
|
+
"entries to the active root deck."
|
|
30688
|
+
]
|
|
30689
|
+
}),
|
|
30690
|
+
selectedGrader?.description && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Callout, {
|
|
30691
|
+
children: selectedGrader.description
|
|
30692
|
+
})
|
|
30693
|
+
]
|
|
30694
|
+
}),
|
|
30695
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(Panel_default, {
|
|
30696
|
+
className: "verify-results",
|
|
30697
|
+
children: [
|
|
30698
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30699
|
+
className: "error",
|
|
30700
|
+
children: error
|
|
30701
|
+
}),
|
|
30702
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30703
|
+
className: "editor-status",
|
|
30704
|
+
children: "Loading verify data\u2026"
|
|
30705
|
+
}),
|
|
30706
|
+
!loading && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, {
|
|
30707
|
+
children: [
|
|
30708
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30709
|
+
className: "verify-status-row",
|
|
30710
|
+
children: [
|
|
30711
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30712
|
+
className: "verify-status-main flex-row items-center gap-8",
|
|
30713
|
+
children: [
|
|
30714
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", {
|
|
30715
|
+
children: "Batch status"
|
|
30716
|
+
}),
|
|
30717
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, {
|
|
30718
|
+
status: batchState.status,
|
|
30719
|
+
children: batchState.status
|
|
30720
|
+
})
|
|
30721
|
+
]
|
|
30722
|
+
}),
|
|
30723
|
+
consistencyReport.sampleSize > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", {
|
|
30724
|
+
className: classNames("verify-verdict-badge", `verify-verdict-badge--${consistencyReport.verdict.toLowerCase()}`),
|
|
30725
|
+
children: consistencyReport.verdict
|
|
30726
|
+
})
|
|
30727
|
+
]
|
|
30728
|
+
}),
|
|
30729
|
+
batchState.status === "idle" && consistencyReport.sampleSize === 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Callout, {
|
|
30730
|
+
children: "Run a consistency batch to compute agreement, spread, and instability for the selected grader."
|
|
30731
|
+
}),
|
|
30732
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30733
|
+
className: "verify-metric-grid",
|
|
30734
|
+
children: [
|
|
30735
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30736
|
+
className: "verify-metric-card",
|
|
30737
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30738
|
+
className: "verify-sample-size-row",
|
|
30739
|
+
children: [
|
|
30740
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30741
|
+
className: "verify-sample-size-copy",
|
|
30742
|
+
children: [
|
|
30743
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30744
|
+
className: "verify-metric-label",
|
|
30745
|
+
children: "Sample size"
|
|
30746
|
+
}),
|
|
30747
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30748
|
+
className: "verify-metric-value",
|
|
30749
|
+
children: consistencyReport.sampleSize
|
|
30750
|
+
})
|
|
30751
|
+
]
|
|
30752
|
+
}),
|
|
30753
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30754
|
+
className: "verify-sample-scope-select",
|
|
30755
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Listbox, {
|
|
30756
|
+
value: reportScope,
|
|
30757
|
+
onChange: (value) => setReportScope(value),
|
|
30758
|
+
size: "small",
|
|
30759
|
+
popoverMatchTriggerWidth: false,
|
|
30760
|
+
popoverMinWidth: 320,
|
|
30761
|
+
popoverAlign: "right",
|
|
30762
|
+
options: [
|
|
30763
|
+
{
|
|
30764
|
+
value: "current_batch",
|
|
30765
|
+
label: `Current batch (${completedBatchRuns.length})`,
|
|
30766
|
+
triggerLabel: "Current batch",
|
|
30767
|
+
triggerMeta: null,
|
|
30768
|
+
meta: "Only runs from the latest batch launch"
|
|
30769
|
+
},
|
|
30770
|
+
{
|
|
30771
|
+
value: "all_matching",
|
|
30772
|
+
label: `All matching runs (${historicalCompletedRuns.length})`,
|
|
30773
|
+
triggerLabel: "All matching runs",
|
|
30774
|
+
triggerMeta: null,
|
|
30775
|
+
meta: "All runs matching selected scenario + grader"
|
|
30776
|
+
}
|
|
30777
|
+
]
|
|
30778
|
+
})
|
|
30779
|
+
})
|
|
30780
|
+
]
|
|
30781
|
+
})
|
|
30782
|
+
}),
|
|
30783
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30784
|
+
className: "verify-metric-card",
|
|
30785
|
+
children: [
|
|
30786
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30787
|
+
className: "verify-metric-label",
|
|
30788
|
+
children: "Agreement rate"
|
|
30789
|
+
}),
|
|
30790
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30791
|
+
className: "verify-metric-value",
|
|
30792
|
+
children: consistencyReport.agreementRate === null ? "\u2014" : `${Math.round(consistencyReport.agreementRate * 100)}%`
|
|
30793
|
+
})
|
|
30794
|
+
]
|
|
30795
|
+
}),
|
|
30796
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30797
|
+
className: "verify-metric-card",
|
|
30798
|
+
children: [
|
|
30799
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30800
|
+
className: "verify-metric-label",
|
|
30801
|
+
children: "Score spread (min/median/max)"
|
|
30802
|
+
}),
|
|
30803
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30804
|
+
className: "verify-metric-value verify-metric-value--compact",
|
|
30805
|
+
children: consistencyReport.scoreSpreadMin === null ? "\u2014" : `${consistencyReport.scoreSpreadMin} / ${consistencyReport.scoreSpreadMedian ?? "\u2014"} / ${consistencyReport.scoreSpreadMax ?? "\u2014"}`
|
|
30806
|
+
})
|
|
30807
|
+
]
|
|
30808
|
+
}),
|
|
30809
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30810
|
+
className: "verify-metric-card",
|
|
30811
|
+
children: [
|
|
30812
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30813
|
+
className: "verify-metric-label",
|
|
30814
|
+
children: "Instability count"
|
|
30815
|
+
}),
|
|
30816
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30817
|
+
className: "verify-metric-value",
|
|
30818
|
+
children: consistencyReport.instabilityCount
|
|
30819
|
+
})
|
|
30820
|
+
]
|
|
30821
|
+
})
|
|
30822
|
+
]
|
|
30823
|
+
}),
|
|
30824
|
+
consistencyReport.sampleSize > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Callout, {
|
|
30825
|
+
variant: consistencyReport.verdict === "FAIL" ? "danger" : consistencyReport.verdict === "WARN" ? "emphasis" : "muted",
|
|
30826
|
+
title: `Verdict: ${consistencyReport.verdict}`,
|
|
30827
|
+
children: consistencyReport.verdictReason
|
|
30828
|
+
}),
|
|
30829
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(Callout, {
|
|
30830
|
+
title: "Thresholds in code",
|
|
30831
|
+
children: [
|
|
30832
|
+
"Min sample size: ",
|
|
30833
|
+
VERIFY_CONSISTENCY_THRESHOLDS.minSampleSize,
|
|
30834
|
+
" ",
|
|
30835
|
+
"\xB7 PASS requires agreement \u2265 ",
|
|
30836
|
+
Math.round(VERIFY_CONSISTENCY_THRESHOLDS.pass.agreementMin * 100),
|
|
30837
|
+
"%, spread \u2264",
|
|
30838
|
+
" ",
|
|
30839
|
+
VERIFY_CONSISTENCY_THRESHOLDS.pass.maxSpread,
|
|
30840
|
+
", instability \u2264",
|
|
30841
|
+
" ",
|
|
30842
|
+
VERIFY_CONSISTENCY_THRESHOLDS.pass.maxInstabilityCount,
|
|
30843
|
+
" ",
|
|
30844
|
+
"\xB7 WARN allows agreement \u2265 ",
|
|
30845
|
+
Math.round(VERIFY_CONSISTENCY_THRESHOLDS.warn.agreementMin * 100),
|
|
30846
|
+
"%, spread \u2264",
|
|
30847
|
+
" ",
|
|
30848
|
+
VERIFY_CONSISTENCY_THRESHOLDS.warn.maxSpread,
|
|
30849
|
+
", instability \u2264",
|
|
30850
|
+
" ",
|
|
30851
|
+
VERIFY_CONSISTENCY_THRESHOLDS.warn.maxInstabilityCount,
|
|
30852
|
+
"."
|
|
30853
|
+
]
|
|
30854
|
+
}),
|
|
30855
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30856
|
+
className: "verify-section",
|
|
30857
|
+
children: [
|
|
30858
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30859
|
+
className: "verify-section-header",
|
|
30860
|
+
children: [
|
|
30861
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", {
|
|
30862
|
+
children: "Examples"
|
|
30863
|
+
}),
|
|
30864
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30865
|
+
className: "verify-section-controls",
|
|
30866
|
+
children: [
|
|
30867
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, {
|
|
30868
|
+
variant: inconsistentOnly ? "primary-deemph" : "secondary",
|
|
30869
|
+
size: "small",
|
|
30870
|
+
onClick: () => setInconsistentOnly((prev) => !prev),
|
|
30871
|
+
children: "Inconsistent"
|
|
30872
|
+
}),
|
|
30873
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30874
|
+
className: "verify-section-sort",
|
|
30875
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Listbox, {
|
|
30876
|
+
value: exampleSort,
|
|
30877
|
+
onChange: (value) => setExampleSort(value),
|
|
30878
|
+
size: "small",
|
|
30879
|
+
options: [
|
|
30880
|
+
{
|
|
30881
|
+
value: "default",
|
|
30882
|
+
label: "Sort: default"
|
|
30883
|
+
},
|
|
30884
|
+
{
|
|
30885
|
+
value: "delta_desc",
|
|
30886
|
+
label: "Sort: score delta"
|
|
30887
|
+
},
|
|
30888
|
+
{
|
|
30889
|
+
value: "agreement_asc",
|
|
30890
|
+
label: "Sort: agreement"
|
|
30891
|
+
},
|
|
30892
|
+
{
|
|
30893
|
+
value: "samples_desc",
|
|
30894
|
+
label: "Sort: sample size"
|
|
30895
|
+
},
|
|
30896
|
+
{
|
|
30897
|
+
value: "label_asc",
|
|
30898
|
+
label: "Sort: label"
|
|
30899
|
+
}
|
|
30900
|
+
]
|
|
30901
|
+
})
|
|
30902
|
+
})
|
|
30903
|
+
]
|
|
30904
|
+
})
|
|
30905
|
+
]
|
|
30906
|
+
}),
|
|
30907
|
+
displayedOutliers.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Callout, {
|
|
30908
|
+
children: consistencyReport.outliers.length === 0 ? `Examples will appear here as soon as at least one completed run is available in ${reportScopeLabel}.` : `No examples match the current filters in ${reportScopeLabel}.`
|
|
30909
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30910
|
+
className: "verify-outlier-list",
|
|
30911
|
+
children: displayedOutliers.map((outlier) => {
|
|
30912
|
+
const runLinks = (() => {
|
|
30913
|
+
if (!selectedSessionId) return [];
|
|
30914
|
+
const ids = [
|
|
30915
|
+
outlier.maxRunId,
|
|
30916
|
+
outlier.minRunId
|
|
30917
|
+
].filter((value) => Boolean(value));
|
|
30918
|
+
return [
|
|
30919
|
+
...new Set(ids)
|
|
30920
|
+
];
|
|
30921
|
+
})();
|
|
30922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30923
|
+
className: "verify-outlier-card",
|
|
30924
|
+
children: [
|
|
30925
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30926
|
+
className: "verify-outlier-header",
|
|
30927
|
+
children: [
|
|
30928
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", {
|
|
30929
|
+
children: outlier.label
|
|
30930
|
+
}),
|
|
30931
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30932
|
+
style: {
|
|
30933
|
+
display: "flex",
|
|
30934
|
+
alignItems: "center",
|
|
30935
|
+
gap: "8px"
|
|
30936
|
+
},
|
|
30937
|
+
children: [
|
|
30938
|
+
outlier.minScore === outlier.maxScore ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, {
|
|
30939
|
+
variant: scoreBadgeVariant(outlier.minScore),
|
|
30940
|
+
children: formatSignedScore(outlier.minScore)
|
|
30941
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30942
|
+
style: {
|
|
30943
|
+
display: "flex",
|
|
30944
|
+
alignItems: "center"
|
|
30945
|
+
},
|
|
30946
|
+
children: [
|
|
30947
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, {
|
|
30948
|
+
variant: scoreBadgeVariant(outlier.minScore),
|
|
30949
|
+
style: {
|
|
30950
|
+
borderTopRightRadius: 0,
|
|
30951
|
+
borderBottomRightRadius: 0
|
|
30952
|
+
},
|
|
30953
|
+
children: formatSignedScore(outlier.minScore)
|
|
30954
|
+
}),
|
|
30955
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, {
|
|
30956
|
+
variant: scoreBadgeVariant(outlier.maxScore),
|
|
30957
|
+
style: {
|
|
30958
|
+
marginLeft: "-1px",
|
|
30959
|
+
borderTopLeftRadius: 0,
|
|
30960
|
+
borderBottomLeftRadius: 0
|
|
30961
|
+
},
|
|
30962
|
+
children: formatSignedScore(outlier.maxScore)
|
|
30963
|
+
})
|
|
30964
|
+
]
|
|
30965
|
+
}),
|
|
30966
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, {
|
|
30967
|
+
variant: outlier.instability ? "error" : "completed",
|
|
30968
|
+
children: outlier.instability ? "Unstable" : "Stable"
|
|
30969
|
+
})
|
|
30970
|
+
]
|
|
30971
|
+
})
|
|
30972
|
+
]
|
|
30973
|
+
}),
|
|
30974
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30975
|
+
className: "flex-row items-center",
|
|
30976
|
+
children: [
|
|
30977
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30978
|
+
className: "flex-1 flex-column",
|
|
30979
|
+
children: [
|
|
30980
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
30981
|
+
className: "verify-outlier-meta",
|
|
30982
|
+
children: [
|
|
30983
|
+
"agreement ",
|
|
30984
|
+
outlier.agreementRate === null ? "\u2014" : `${Math.round(outlier.agreementRate * 100)}%`,
|
|
30985
|
+
" \xB7 delta ",
|
|
30986
|
+
outlier.scoreDelta ?? "\u2014",
|
|
30987
|
+
" ",
|
|
30988
|
+
"\xB7 samples ",
|
|
30989
|
+
outlier.sampleSize,
|
|
30990
|
+
outlier.passFlip ? " \xB7 pass/fail flip" : "",
|
|
30991
|
+
outlier.messageRefId ? ` \xB7 ref ${outlier.messageRefId}` : ""
|
|
30992
|
+
]
|
|
30993
|
+
}),
|
|
30994
|
+
runLinks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
30995
|
+
className: "verify-outlier-links",
|
|
30996
|
+
children: runLinks.map((runId) => {
|
|
30997
|
+
if (!selectedSessionId) return null;
|
|
30998
|
+
const href = buildGradePath(selectedSessionId, runId);
|
|
30999
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("a", {
|
|
31000
|
+
href,
|
|
31001
|
+
onClick: (event) => handleInternalLinkClick(event, href),
|
|
31002
|
+
children: [
|
|
31003
|
+
"Open grade run ",
|
|
31004
|
+
runId
|
|
31005
|
+
]
|
|
31006
|
+
}, runId);
|
|
31007
|
+
})
|
|
31008
|
+
})
|
|
31009
|
+
]
|
|
31010
|
+
}),
|
|
31011
|
+
(() => {
|
|
31012
|
+
const outlierChip = buildOutlierChip(outlier);
|
|
31013
|
+
const inChat = composerChipIds.has(outlierChip.chipId);
|
|
31014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", {
|
|
31015
|
+
className: "workbench-summary-actions",
|
|
31016
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, {
|
|
31017
|
+
variant: "secondary",
|
|
31018
|
+
size: "small",
|
|
31019
|
+
onClick: () => inChat ? removeComposerChip(outlierChip.chipId) : addComposerChip(outlierChip),
|
|
31020
|
+
disabled: !onComposerChipsChange,
|
|
31021
|
+
children: inChat ? "Remove from chat" : "Add to chat"
|
|
31022
|
+
})
|
|
31023
|
+
});
|
|
31024
|
+
})()
|
|
31025
|
+
]
|
|
31026
|
+
})
|
|
31027
|
+
]
|
|
31028
|
+
}, outlier.key);
|
|
31029
|
+
})
|
|
31030
|
+
})
|
|
31031
|
+
]
|
|
31032
|
+
}),
|
|
31033
|
+
batchState.requests.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
31034
|
+
className: "verify-section",
|
|
31035
|
+
children: [
|
|
31036
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", {
|
|
31037
|
+
children: "Batch requests"
|
|
31038
|
+
}),
|
|
31039
|
+
(batchState.startedAt || batchState.finishedAt) && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
31040
|
+
className: "verify-status-meta",
|
|
31041
|
+
children: [
|
|
31042
|
+
batchState.startedAt ? `started ${formatTimestampShort(batchState.startedAt)}` : "",
|
|
31043
|
+
batchState.finishedAt ? ` \xB7 finished ${formatTimestampShort(batchState.finishedAt)}` : ""
|
|
31044
|
+
]
|
|
31045
|
+
}),
|
|
31046
|
+
batchState.requested > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", {
|
|
31047
|
+
className: "verify-progress-row",
|
|
31048
|
+
children: [
|
|
31049
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", {
|
|
31050
|
+
children: [
|
|
31051
|
+
"Queued: ",
|
|
31052
|
+
queuedCount
|
|
31053
|
+
]
|
|
31054
|
+
}),
|
|
31055
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", {
|
|
31056
|
+
children: [
|
|
31057
|
+
"Running: ",
|
|
31058
|
+
batchState.active
|
|
31059
|
+
]
|
|
31060
|
+
}),
|
|
31061
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", {
|
|
31062
|
+
children: [
|
|
31063
|
+
"Completed: ",
|
|
31064
|
+
batchState.completed
|
|
31065
|
+
]
|
|
31066
|
+
}),
|
|
31067
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", {
|
|
31068
|
+
children: [
|
|
31069
|
+
"Failed: ",
|
|
31070
|
+
batchState.failed
|
|
31071
|
+
]
|
|
31072
|
+
})
|
|
31073
|
+
]
|
|
31074
|
+
}),
|
|
31075
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", {
|
|
31076
|
+
className: "verify-request-list",
|
|
31077
|
+
children: batchState.requests.map((request, index) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", {
|
|
31078
|
+
className: "verify-request-row",
|
|
31079
|
+
children: [
|
|
31080
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", {
|
|
31081
|
+
className: "verify-request-index",
|
|
31082
|
+
children: [
|
|
31083
|
+
"#",
|
|
31084
|
+
index + 1
|
|
31085
|
+
]
|
|
31086
|
+
}),
|
|
31087
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, {
|
|
31088
|
+
status: request.status === "queued" ? "idle" : request.status,
|
|
31089
|
+
children: request.status
|
|
31090
|
+
}),
|
|
31091
|
+
selectedSessionId && request.runId ? (() => {
|
|
31092
|
+
const href = buildGradePath(selectedSessionId, request.runId);
|
|
31093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("a", {
|
|
31094
|
+
href,
|
|
31095
|
+
onClick: (event) => handleInternalLinkClick(event, href),
|
|
31096
|
+
children: request.runId
|
|
31097
|
+
});
|
|
31098
|
+
})() : request.runId ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("code", {
|
|
31099
|
+
children: request.runId
|
|
31100
|
+
}) : null,
|
|
31101
|
+
request.error && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", {
|
|
31102
|
+
className: "verify-request-error",
|
|
31103
|
+
children: request.error
|
|
31104
|
+
})
|
|
31105
|
+
]
|
|
31106
|
+
}, request.requestId))
|
|
31107
|
+
})
|
|
31108
|
+
]
|
|
31109
|
+
})
|
|
31110
|
+
]
|
|
31111
|
+
})
|
|
31112
|
+
]
|
|
31113
|
+
})
|
|
31114
|
+
]
|
|
31115
|
+
})
|
|
31116
|
+
});
|
|
31117
|
+
}
|
|
31118
|
+
var VerifyPage_default = VerifyPage;
|
|
31119
|
+
|
|
31120
|
+
// simulator-ui/src/main.tsx
|
|
31121
|
+
var globalStyleEl = document.createElement("style");
|
|
31122
|
+
globalStyleEl.textContent = globalStyles;
|
|
31123
|
+
document.head.appendChild(globalStyleEl);
|
|
31124
|
+
function useSimulator() {
|
|
31125
|
+
const [connectionStatus, setConnectionStatus] = (0, import_react41.useState)("connecting");
|
|
31126
|
+
const [savedState, setSavedState] = (0, import_react41.useState)(null);
|
|
31127
|
+
const [traceEvents, setTraceEvents] = (0, import_react41.useState)([]);
|
|
31128
|
+
const [errors, setErrors] = (0, import_react41.useState)([]);
|
|
31129
|
+
const [streamText, setStreamText] = (0, import_react41.useState)("");
|
|
31130
|
+
const [isRunning, setIsRunning] = (0, import_react41.useState)(false);
|
|
31131
|
+
const [connectSeq, setConnectSeq] = (0, import_react41.useState)(0);
|
|
31132
|
+
(0, import_react41.useEffect)(() => {
|
|
31133
|
+
const streamId = SIMULATOR_STREAM_ID;
|
|
31134
|
+
const streamUrl = buildDurableStreamUrl(streamId, getDurableStreamOffset(streamId));
|
|
31135
|
+
const source = new EventSource(streamUrl);
|
|
31136
|
+
setConnectionStatus("connecting");
|
|
31137
|
+
source.onopen = () => {
|
|
31138
|
+
setConnectionStatus("connected");
|
|
31139
|
+
setErrors([]);
|
|
31140
|
+
};
|
|
31141
|
+
source.onerror = () => {
|
|
31142
|
+
setConnectionStatus("error");
|
|
31143
|
+
setErrors((prev) => prev.includes("Stream connection error") ? prev : [
|
|
31144
|
+
...prev,
|
|
31145
|
+
"Stream connection error"
|
|
31146
|
+
]);
|
|
31147
|
+
setIsRunning(false);
|
|
31148
|
+
setStreamText("");
|
|
31149
|
+
};
|
|
31150
|
+
const handleMessage = (event) => {
|
|
31151
|
+
let msg = null;
|
|
31152
|
+
try {
|
|
31153
|
+
msg = JSON.parse(event.data);
|
|
31154
|
+
} catch (err) {
|
|
31155
|
+
console.error("[sim] failed to parse stream event payload", err);
|
|
31156
|
+
return;
|
|
31157
|
+
}
|
|
31158
|
+
const parsedOffset = Number(event.lastEventId);
|
|
31159
|
+
if (Number.isFinite(parsedOffset)) {
|
|
31160
|
+
setDurableStreamOffset(streamId, parsedOffset + 1);
|
|
31161
|
+
}
|
|
31162
|
+
if (!msg || typeof msg !== "object") return;
|
|
31163
|
+
if (msg.type === "state") {
|
|
31164
|
+
setSavedState(msg.state);
|
|
31165
|
+
if (Array.isArray(msg.state.traces)) {
|
|
31166
|
+
setTraceEvents(msg.state.traces);
|
|
31167
|
+
}
|
|
31168
|
+
} else if (msg.type === "stream") {
|
|
31169
|
+
if (typeof msg.chunk === "string" && msg.chunk.length > 0) {
|
|
31170
|
+
setStreamText((prev) => prev + msg.chunk);
|
|
31171
|
+
}
|
|
31172
|
+
} else if (msg.type === "result") {
|
|
31173
|
+
setIsRunning(false);
|
|
31174
|
+
setStreamText("");
|
|
31175
|
+
} else if (msg.type === "trace" && msg.event) {
|
|
31176
|
+
setTraceEvents((prev) => [
|
|
31177
|
+
...prev,
|
|
31178
|
+
msg.event
|
|
31179
|
+
].slice(-200));
|
|
31180
|
+
} else if (msg.type === "error") {
|
|
31181
|
+
const message = msg.message ?? "Unknown error";
|
|
31182
|
+
setErrors((prev) => [
|
|
31183
|
+
...prev,
|
|
31184
|
+
message
|
|
31185
|
+
]);
|
|
31186
|
+
if (msg.runId || message !== "Run already in progress") {
|
|
31187
|
+
setIsRunning(false);
|
|
31188
|
+
}
|
|
31189
|
+
setStreamText("");
|
|
31190
|
+
}
|
|
31191
|
+
};
|
|
31192
|
+
const simulatorEventTypes = [
|
|
31193
|
+
"ready",
|
|
31194
|
+
"pong",
|
|
31195
|
+
"stream",
|
|
31196
|
+
"result",
|
|
31197
|
+
"trace",
|
|
31198
|
+
"state",
|
|
31199
|
+
"error"
|
|
31200
|
+
];
|
|
31201
|
+
for (const type of simulatorEventTypes) {
|
|
31202
|
+
source.addEventListener(type, handleMessage);
|
|
31203
|
+
}
|
|
31204
|
+
return () => {
|
|
31205
|
+
for (const type of simulatorEventTypes) {
|
|
31206
|
+
source.removeEventListener(type, handleMessage);
|
|
31207
|
+
}
|
|
31208
|
+
source.close();
|
|
31209
|
+
setConnectionStatus("closed");
|
|
31210
|
+
setIsRunning(false);
|
|
31211
|
+
setStreamText("");
|
|
31212
|
+
};
|
|
31213
|
+
}, [
|
|
29244
31214
|
connectSeq
|
|
29245
31215
|
]);
|
|
29246
|
-
const run = (0,
|
|
31216
|
+
const run = (0, import_react41.useCallback)(async (opts) => {
|
|
29247
31217
|
setIsRunning(true);
|
|
29248
31218
|
setStreamText("");
|
|
29249
31219
|
const sessionId = opts.resetState ? void 0 : savedState?.meta?.sessionId;
|
|
@@ -29278,7 +31248,7 @@ function useSimulator() {
|
|
|
29278
31248
|
}, [
|
|
29279
31249
|
savedState?.meta?.sessionId
|
|
29280
31250
|
]);
|
|
29281
|
-
const sendFeedback = (0,
|
|
31251
|
+
const sendFeedback = (0, import_react41.useCallback)(async (messageRefId, score, reason) => {
|
|
29282
31252
|
const sessionId = savedState?.meta?.sessionId;
|
|
29283
31253
|
if (!sessionId) return;
|
|
29284
31254
|
try {
|
|
@@ -29305,7 +31275,7 @@ function useSimulator() {
|
|
|
29305
31275
|
}, [
|
|
29306
31276
|
savedState?.meta?.sessionId
|
|
29307
31277
|
]);
|
|
29308
|
-
const loadSession = (0,
|
|
31278
|
+
const loadSession = (0, import_react41.useCallback)(async (sessionId) => {
|
|
29309
31279
|
try {
|
|
29310
31280
|
const res = await fetch("/api/simulator/load-session", {
|
|
29311
31281
|
method: "POST",
|
|
@@ -29334,7 +31304,7 @@ function useSimulator() {
|
|
|
29334
31304
|
]);
|
|
29335
31305
|
}
|
|
29336
31306
|
}, []);
|
|
29337
|
-
const saveNotes = (0,
|
|
31307
|
+
const saveNotes = (0, import_react41.useCallback)(async (text) => {
|
|
29338
31308
|
const sessionId = savedState?.meta?.sessionId;
|
|
29339
31309
|
if (!sessionId) return;
|
|
29340
31310
|
try {
|
|
@@ -29359,7 +31329,7 @@ function useSimulator() {
|
|
|
29359
31329
|
}, [
|
|
29360
31330
|
savedState?.meta?.sessionId
|
|
29361
31331
|
]);
|
|
29362
|
-
const saveSessionScore = (0,
|
|
31332
|
+
const saveSessionScore = (0, import_react41.useCallback)(async (score) => {
|
|
29363
31333
|
const sessionId = savedState?.meta?.sessionId;
|
|
29364
31334
|
if (!sessionId) return;
|
|
29365
31335
|
try {
|
|
@@ -29384,10 +31354,10 @@ function useSimulator() {
|
|
|
29384
31354
|
}, [
|
|
29385
31355
|
savedState?.meta?.sessionId
|
|
29386
31356
|
]);
|
|
29387
|
-
const reconnect = (0,
|
|
31357
|
+
const reconnect = (0, import_react41.useCallback)(() => {
|
|
29388
31358
|
setConnectSeq((prev) => prev + 1);
|
|
29389
31359
|
}, []);
|
|
29390
|
-
const resetLocal = (0,
|
|
31360
|
+
const resetLocal = (0, import_react41.useCallback)(() => {
|
|
29391
31361
|
setSavedState(null);
|
|
29392
31362
|
setTraceEvents([]);
|
|
29393
31363
|
setErrors([]);
|
|
@@ -29410,10 +31380,10 @@ function useSimulator() {
|
|
|
29410
31380
|
};
|
|
29411
31381
|
}
|
|
29412
31382
|
function useWorkspaces() {
|
|
29413
|
-
const [workspaces, setWorkspaces] = (0,
|
|
29414
|
-
const [loading, setLoading] = (0,
|
|
29415
|
-
const [error, setError] = (0,
|
|
29416
|
-
const byNewest = (0,
|
|
31383
|
+
const [workspaces, setWorkspaces] = (0, import_react41.useState)([]);
|
|
31384
|
+
const [loading, setLoading] = (0, import_react41.useState)(false);
|
|
31385
|
+
const [error, setError] = (0, import_react41.useState)(null);
|
|
31386
|
+
const byNewest = (0, import_react41.useCallback)((items) => {
|
|
29417
31387
|
return [
|
|
29418
31388
|
...items
|
|
29419
31389
|
].sort((a, b) => {
|
|
@@ -29424,7 +31394,7 @@ function useWorkspaces() {
|
|
|
29424
31394
|
return safeBTime - safeATime;
|
|
29425
31395
|
});
|
|
29426
31396
|
}, []);
|
|
29427
|
-
const refresh = (0,
|
|
31397
|
+
const refresh = (0, import_react41.useCallback)(async () => {
|
|
29428
31398
|
setLoading(true);
|
|
29429
31399
|
setError(null);
|
|
29430
31400
|
try {
|
|
@@ -29440,7 +31410,7 @@ function useWorkspaces() {
|
|
|
29440
31410
|
}, [
|
|
29441
31411
|
byNewest
|
|
29442
31412
|
]);
|
|
29443
|
-
const deleteWorkspace = (0,
|
|
31413
|
+
const deleteWorkspace = (0, import_react41.useCallback)(async (workspaceId) => {
|
|
29444
31414
|
setLoading(true);
|
|
29445
31415
|
setError(null);
|
|
29446
31416
|
try {
|
|
@@ -29463,7 +31433,7 @@ function useWorkspaces() {
|
|
|
29463
31433
|
}, [
|
|
29464
31434
|
refresh
|
|
29465
31435
|
]);
|
|
29466
|
-
const deleteAll = (0,
|
|
31436
|
+
const deleteAll = (0, import_react41.useCallback)(async (scope) => {
|
|
29467
31437
|
setLoading(true);
|
|
29468
31438
|
setError(null);
|
|
29469
31439
|
try {
|
|
@@ -29504,44 +31474,44 @@ function useWorkspaces() {
|
|
|
29504
31474
|
function RecentSessionsEmptyState(props) {
|
|
29505
31475
|
const { sessions, loading, error, onSelect, onOpenAll } = props;
|
|
29506
31476
|
const preview = sessions.slice(0, 4);
|
|
29507
|
-
return /* @__PURE__ */ (0,
|
|
31477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
29508
31478
|
className: "empty-state",
|
|
29509
31479
|
children: [
|
|
29510
|
-
/* @__PURE__ */ (0,
|
|
31480
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", {
|
|
29511
31481
|
children: "Start a new chat or load a previous session to review feedback."
|
|
29512
31482
|
}),
|
|
29513
|
-
loading && /* @__PURE__ */ (0,
|
|
31483
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", {
|
|
29514
31484
|
children: "Loading recent sessions\u2026"
|
|
29515
31485
|
}),
|
|
29516
|
-
error && /* @__PURE__ */ (0,
|
|
31486
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", {
|
|
29517
31487
|
className: "error",
|
|
29518
31488
|
children: error
|
|
29519
31489
|
}),
|
|
29520
|
-
!loading && !error && preview.length === 0 && /* @__PURE__ */ (0,
|
|
31490
|
+
!loading && !error && preview.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", {
|
|
29521
31491
|
children: "No saved sessions yet."
|
|
29522
31492
|
}),
|
|
29523
|
-
!loading && !error && preview.length > 0 && /* @__PURE__ */ (0,
|
|
31493
|
+
!loading && !error && preview.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
29524
31494
|
className: "recent-sessions",
|
|
29525
|
-
children: preview.map((session) => /* @__PURE__ */ (0,
|
|
31495
|
+
children: preview.map((session) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("button", {
|
|
29526
31496
|
type: "button",
|
|
29527
31497
|
className: "recent-session-button",
|
|
29528
31498
|
onClick: () => onSelect(session.id),
|
|
29529
31499
|
children: [
|
|
29530
|
-
/* @__PURE__ */ (0,
|
|
31500
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("strong", {
|
|
29531
31501
|
children: session.testBotName ?? session.deckSlug ?? session.deck ?? "session"
|
|
29532
31502
|
}),
|
|
29533
|
-
/* @__PURE__ */ (0,
|
|
31503
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", {
|
|
29534
31504
|
children: formatTimestamp(session.createdAt)
|
|
29535
31505
|
}),
|
|
29536
|
-
/* @__PURE__ */ (0,
|
|
31506
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("code", {
|
|
29537
31507
|
children: session.id
|
|
29538
31508
|
})
|
|
29539
31509
|
]
|
|
29540
31510
|
}, session.id))
|
|
29541
31511
|
}),
|
|
29542
|
-
/* @__PURE__ */ (0,
|
|
31512
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
29543
31513
|
className: "empty-state-actions",
|
|
29544
|
-
children: /* @__PURE__ */ (0,
|
|
31514
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, {
|
|
29545
31515
|
variant: "ghost",
|
|
29546
31516
|
onClick: onOpenAll,
|
|
29547
31517
|
children: "View all sessions"
|
|
@@ -29560,35 +31530,35 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29560
31530
|
const sessionBasePath = rootPath === "/" ? WORKSPACES_BASE_PATH : rootPath;
|
|
29561
31531
|
const normalizedSessionBase = normalizeBasePath(sessionBasePath);
|
|
29562
31532
|
const newSessionPath = `${normalizedSessionBase === "" ? WORKSPACES_BASE_PATH : normalizedSessionBase}/new`.replace(/\/{2,}/g, "/");
|
|
29563
|
-
const buildSessionUrl = (0,
|
|
31533
|
+
const buildSessionUrl = (0, import_react41.useCallback)((sessionId2) => `${normalizedSessionBase === "" ? WORKSPACES_BASE_PATH : normalizedSessionBase}/${encodeURIComponent(sessionId2)}/debug`.replace(/\/{2,}/g, "/"), [
|
|
29564
31534
|
normalizedSessionBase
|
|
29565
31535
|
]);
|
|
29566
|
-
const [message, setMessage] = (0,
|
|
29567
|
-
const [pendingReset, setPendingReset] = (0,
|
|
29568
|
-
const [initValue, setInitValue] = (0,
|
|
29569
|
-
const [initDirty, setInitDirty] = (0,
|
|
29570
|
-
const [initMode, setInitMode] = (0,
|
|
29571
|
-
const [initJsonText, setInitJsonText] = (0,
|
|
29572
|
-
const [initJsonError, setInitJsonError] = (0,
|
|
29573
|
-
const [initOpen, setInitOpen] = (0,
|
|
29574
|
-
const [jsonErrors, setJsonErrors] = (0,
|
|
29575
|
-
const [pendingSessionId, setPendingSessionId] = (0,
|
|
29576
|
-
const appliedSessionIdRef = (0,
|
|
29577
|
-
const externalSessionIdRef = (0,
|
|
29578
|
-
const initializedRef = (0,
|
|
29579
|
-
const [noteDraft, setNoteDraft] = (0,
|
|
29580
|
-
const [noteStatus, setNoteStatus] = (0,
|
|
29581
|
-
const pendingNoteRef = (0,
|
|
29582
|
-
const [scoreStatus, setScoreStatus] = (0,
|
|
29583
|
-
const pendingScoreRef = (0,
|
|
29584
|
-
(0,
|
|
31536
|
+
const [message, setMessage] = (0, import_react41.useState)("");
|
|
31537
|
+
const [pendingReset, setPendingReset] = (0, import_react41.useState)(false);
|
|
31538
|
+
const [initValue, setInitValue] = (0, import_react41.useState)(void 0);
|
|
31539
|
+
const [initDirty, setInitDirty] = (0, import_react41.useState)(false);
|
|
31540
|
+
const [initMode, setInitMode] = (0, import_react41.useState)("form");
|
|
31541
|
+
const [initJsonText, setInitJsonText] = (0, import_react41.useState)("");
|
|
31542
|
+
const [initJsonError, setInitJsonError] = (0, import_react41.useState)(null);
|
|
31543
|
+
const [initOpen, setInitOpen] = (0, import_react41.useState)(false);
|
|
31544
|
+
const [jsonErrors, setJsonErrors] = (0, import_react41.useState)({});
|
|
31545
|
+
const [pendingSessionId, setPendingSessionId] = (0, import_react41.useState)(null);
|
|
31546
|
+
const appliedSessionIdRef = (0, import_react41.useRef)(null);
|
|
31547
|
+
const externalSessionIdRef = (0, import_react41.useRef)(null);
|
|
31548
|
+
const initializedRef = (0, import_react41.useRef)(false);
|
|
31549
|
+
const [noteDraft, setNoteDraft] = (0, import_react41.useState)("");
|
|
31550
|
+
const [noteStatus, setNoteStatus] = (0, import_react41.useState)("idle");
|
|
31551
|
+
const pendingNoteRef = (0, import_react41.useRef)(null);
|
|
31552
|
+
const [scoreStatus, setScoreStatus] = (0, import_react41.useState)("idle");
|
|
31553
|
+
const pendingScoreRef = (0, import_react41.useRef)(null);
|
|
31554
|
+
(0, import_react41.useEffect)(() => {
|
|
29585
31555
|
if (simulator.connectionStatus === "connecting") {
|
|
29586
31556
|
appliedSessionIdRef.current = null;
|
|
29587
31557
|
}
|
|
29588
31558
|
}, [
|
|
29589
31559
|
simulator.connectionStatus
|
|
29590
31560
|
]);
|
|
29591
|
-
(0,
|
|
31561
|
+
(0, import_react41.useEffect)(() => {
|
|
29592
31562
|
refresh();
|
|
29593
31563
|
}, [
|
|
29594
31564
|
refresh
|
|
@@ -29598,7 +31568,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29598
31568
|
const schemaError = httpSchema.schemaResponse?.error ?? httpSchema.error ?? void 0;
|
|
29599
31569
|
const conversationStarted = Boolean(simulator.savedState && simulator.savedState.messages.length > 0);
|
|
29600
31570
|
const initEditable = Boolean(schema) && (!conversationStarted || pendingReset);
|
|
29601
|
-
const lockedInitValue = (0,
|
|
31571
|
+
const lockedInitValue = (0, import_react41.useMemo)(() => {
|
|
29602
31572
|
const fromTraces = extractInitFromTraces(simulator.savedState?.traces);
|
|
29603
31573
|
if (fromTraces !== void 0) return fromTraces;
|
|
29604
31574
|
return schemaDefaults ?? deriveInitialFromSchema(schema);
|
|
@@ -29607,7 +31577,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29607
31577
|
schemaDefaults,
|
|
29608
31578
|
schema
|
|
29609
31579
|
]);
|
|
29610
|
-
(0,
|
|
31580
|
+
(0, import_react41.useEffect)(() => {
|
|
29611
31581
|
if (!schema) return;
|
|
29612
31582
|
if (initDirty) return;
|
|
29613
31583
|
if (schemaDefaults !== void 0) {
|
|
@@ -29620,7 +31590,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29620
31590
|
schemaDefaults,
|
|
29621
31591
|
initDirty
|
|
29622
31592
|
]);
|
|
29623
|
-
(0,
|
|
31593
|
+
(0, import_react41.useEffect)(() => {
|
|
29624
31594
|
if (initMode !== "json") return;
|
|
29625
31595
|
if (initDirty) return;
|
|
29626
31596
|
try {
|
|
@@ -29633,19 +31603,19 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29633
31603
|
initValue,
|
|
29634
31604
|
initDirty
|
|
29635
31605
|
]);
|
|
29636
|
-
(0,
|
|
31606
|
+
(0, import_react41.useEffect)(() => {
|
|
29637
31607
|
if (initEditable) {
|
|
29638
31608
|
setInitOpen(true);
|
|
29639
31609
|
}
|
|
29640
31610
|
}, [
|
|
29641
31611
|
initEditable
|
|
29642
31612
|
]);
|
|
29643
|
-
const messages = (0,
|
|
31613
|
+
const messages = (0, import_react41.useMemo)(() => {
|
|
29644
31614
|
return buildConversationEntries(simulator.savedState);
|
|
29645
31615
|
}, [
|
|
29646
31616
|
simulator.savedState
|
|
29647
31617
|
]);
|
|
29648
|
-
const missingRequired = (0,
|
|
31618
|
+
const missingRequired = (0, import_react41.useMemo)(() => {
|
|
29649
31619
|
if (!schema || !initEditable) return [];
|
|
29650
31620
|
return findMissingRequiredFields(schema, initValue);
|
|
29651
31621
|
}, [
|
|
@@ -29653,13 +31623,13 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29653
31623
|
initEditable,
|
|
29654
31624
|
initValue
|
|
29655
31625
|
]);
|
|
29656
|
-
const jsonErrorCount = (0,
|
|
31626
|
+
const jsonErrorCount = (0, import_react41.useMemo)(() => {
|
|
29657
31627
|
return Object.values(jsonErrors).filter((v) => typeof v === "string" && v).length;
|
|
29658
31628
|
}, [
|
|
29659
31629
|
jsonErrors
|
|
29660
31630
|
]);
|
|
29661
31631
|
const canStartWithInit = Boolean(schema) && initEditable && missingRequired.length === 0 && jsonErrorCount === 0;
|
|
29662
|
-
const resetInitValue = (0,
|
|
31632
|
+
const resetInitValue = (0, import_react41.useCallback)(() => {
|
|
29663
31633
|
setInitJsonError(null);
|
|
29664
31634
|
setJsonErrors((prev) => ({
|
|
29665
31635
|
...prev,
|
|
@@ -29677,7 +31647,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29677
31647
|
schema,
|
|
29678
31648
|
schemaDefaults
|
|
29679
31649
|
]);
|
|
29680
|
-
const startNewChat = (0,
|
|
31650
|
+
const startNewChat = (0, import_react41.useCallback)((opts) => {
|
|
29681
31651
|
const shouldPush = opts?.pushHistory ?? true;
|
|
29682
31652
|
if (shouldPush) {
|
|
29683
31653
|
if (opts?.replace) {
|
|
@@ -29707,14 +31677,14 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29707
31677
|
resetInitValue,
|
|
29708
31678
|
newSessionPath
|
|
29709
31679
|
]);
|
|
29710
|
-
const adoptSessionFromPath = (0,
|
|
31680
|
+
const adoptSessionFromPath = (0, import_react41.useCallback)((sessionId2) => {
|
|
29711
31681
|
appliedSessionIdRef.current = null;
|
|
29712
31682
|
setPendingSessionId(sessionId2);
|
|
29713
31683
|
setPendingReset(false);
|
|
29714
31684
|
setInitOpen(false);
|
|
29715
31685
|
setInitDirty(true);
|
|
29716
31686
|
}, []);
|
|
29717
|
-
const navigateToSession = (0,
|
|
31687
|
+
const navigateToSession = (0, import_react41.useCallback)((sessionId2, opts) => {
|
|
29718
31688
|
const url = buildSessionUrl(sessionId2);
|
|
29719
31689
|
if (opts?.replace) {
|
|
29720
31690
|
window.history.replaceState({}, "", url);
|
|
@@ -29726,7 +31696,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29726
31696
|
adoptSessionFromPath,
|
|
29727
31697
|
buildSessionUrl
|
|
29728
31698
|
]);
|
|
29729
|
-
(0,
|
|
31699
|
+
(0, import_react41.useEffect)(() => {
|
|
29730
31700
|
if (initializedRef.current) return;
|
|
29731
31701
|
initializedRef.current = true;
|
|
29732
31702
|
const initialSession = getWorkspaceIdFromPath(void 0, sessionBasePath) ?? getWorkspaceIdFromPath();
|
|
@@ -29744,7 +31714,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29744
31714
|
startNewChat,
|
|
29745
31715
|
sessionBasePath
|
|
29746
31716
|
]);
|
|
29747
|
-
(0,
|
|
31717
|
+
(0, import_react41.useEffect)(() => {
|
|
29748
31718
|
if (!activeWorkspaceId) {
|
|
29749
31719
|
externalSessionIdRef.current = null;
|
|
29750
31720
|
return;
|
|
@@ -29756,7 +31726,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29756
31726
|
activeWorkspaceId,
|
|
29757
31727
|
adoptSessionFromPath
|
|
29758
31728
|
]);
|
|
29759
|
-
(0,
|
|
31729
|
+
(0, import_react41.useEffect)(() => {
|
|
29760
31730
|
const handler = () => {
|
|
29761
31731
|
const sessionFromPath = getWorkspaceIdFromPath(void 0, sessionBasePath) ?? getWorkspaceIdFromPath();
|
|
29762
31732
|
if (sessionFromPath) {
|
|
@@ -29774,7 +31744,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29774
31744
|
startNewChat,
|
|
29775
31745
|
sessionBasePath
|
|
29776
31746
|
]);
|
|
29777
|
-
(0,
|
|
31747
|
+
(0, import_react41.useEffect)(() => {
|
|
29778
31748
|
if (!pendingSessionId) return;
|
|
29779
31749
|
if (simulator.connectionStatus !== "connected") return;
|
|
29780
31750
|
if (appliedSessionIdRef.current === pendingSessionId) return;
|
|
@@ -29789,7 +31759,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29789
31759
|
const serverNotesUpdatedAt = simulator.savedState?.notes?.updatedAt;
|
|
29790
31760
|
const serverScore = simulator.savedState?.conversationScore?.score ?? null;
|
|
29791
31761
|
const serverScoreUpdatedAt = simulator.savedState?.conversationScore?.updatedAt;
|
|
29792
|
-
(0,
|
|
31762
|
+
(0, import_react41.useEffect)(() => {
|
|
29793
31763
|
if (pendingNoteRef.current !== null) {
|
|
29794
31764
|
if (serverNotesText === pendingNoteRef.current) {
|
|
29795
31765
|
pendingNoteRef.current = null;
|
|
@@ -29802,7 +31772,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29802
31772
|
}, [
|
|
29803
31773
|
serverNotesText
|
|
29804
31774
|
]);
|
|
29805
|
-
(0,
|
|
31775
|
+
(0, import_react41.useEffect)(() => {
|
|
29806
31776
|
if (noteStatus !== "dirty") return;
|
|
29807
31777
|
const handle = window.setTimeout(() => {
|
|
29808
31778
|
setNoteStatus("saving");
|
|
@@ -29815,7 +31785,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29815
31785
|
noteDraft,
|
|
29816
31786
|
simulator
|
|
29817
31787
|
]);
|
|
29818
|
-
(0,
|
|
31788
|
+
(0, import_react41.useEffect)(() => {
|
|
29819
31789
|
if (pendingScoreRef.current !== null) {
|
|
29820
31790
|
if (serverScore === pendingScoreRef.current) {
|
|
29821
31791
|
pendingScoreRef.current = null;
|
|
@@ -29831,7 +31801,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29831
31801
|
}, [
|
|
29832
31802
|
serverScore
|
|
29833
31803
|
]);
|
|
29834
|
-
const handleSend = (0,
|
|
31804
|
+
const handleSend = (0, import_react41.useCallback)(() => {
|
|
29835
31805
|
const trimmed = message.trim();
|
|
29836
31806
|
if (schema && initEditable) {
|
|
29837
31807
|
if (!canStartWithInit) return;
|
|
@@ -29871,12 +31841,12 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29871
31841
|
canStartWithInit,
|
|
29872
31842
|
initValue
|
|
29873
31843
|
]);
|
|
29874
|
-
const handleScore = (0,
|
|
31844
|
+
const handleScore = (0, import_react41.useCallback)((refId, score, reason) => {
|
|
29875
31845
|
simulator.sendFeedback(refId, score, reason);
|
|
29876
31846
|
}, [
|
|
29877
31847
|
simulator
|
|
29878
31848
|
]);
|
|
29879
|
-
const handleReason = (0,
|
|
31849
|
+
const handleReason = (0, import_react41.useCallback)((refId, score, reason) => {
|
|
29880
31850
|
simulator.sendFeedback(refId, score, reason);
|
|
29881
31851
|
}, [
|
|
29882
31852
|
simulator
|
|
@@ -29886,16 +31856,16 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29886
31856
|
const sessionPermalink = sessionId ? buildSessionUrl(sessionId) : null;
|
|
29887
31857
|
const sessionStatePath = typeof runMeta.sessionStatePath === "string" ? runMeta.sessionStatePath : typeof runMeta.sessionDir === "string" ? `${runMeta.sessionDir}/state.json` : void 0;
|
|
29888
31858
|
const currentSessionScore = pendingScoreRef.current !== null ? pendingScoreRef.current : serverScore;
|
|
29889
|
-
(0,
|
|
31859
|
+
(0, import_react41.useEffect)(() => {
|
|
29890
31860
|
if (!setNavActions) return;
|
|
29891
|
-
setNavActions(/* @__PURE__ */ (0,
|
|
31861
|
+
setNavActions(/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, {
|
|
29892
31862
|
children: [
|
|
29893
|
-
/* @__PURE__ */ (0,
|
|
31863
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, {
|
|
29894
31864
|
variant: "secondary",
|
|
29895
31865
|
onClick: () => startNewChat(),
|
|
29896
31866
|
children: "New chat"
|
|
29897
31867
|
}),
|
|
29898
|
-
/* @__PURE__ */ (0,
|
|
31868
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
29899
31869
|
className: `status-indicator ${simulator.connectionStatus}`,
|
|
29900
31870
|
children: simulator.connectionStatus
|
|
29901
31871
|
})
|
|
@@ -29909,7 +31879,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29909
31879
|
simulator.connectionStatus,
|
|
29910
31880
|
startNewChat
|
|
29911
31881
|
]);
|
|
29912
|
-
const deckSessions = (0,
|
|
31882
|
+
const deckSessions = (0, import_react41.useMemo)(() => {
|
|
29913
31883
|
return workspaces.filter((session) => {
|
|
29914
31884
|
if (!session) return false;
|
|
29915
31885
|
if (typeof session.deck === "string") {
|
|
@@ -29928,22 +31898,22 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
29928
31898
|
normalizedDeckPath,
|
|
29929
31899
|
repoRootPath
|
|
29930
31900
|
]);
|
|
29931
|
-
const recentSessionsEmpty = /* @__PURE__ */ (0,
|
|
31901
|
+
const recentSessionsEmpty = /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(RecentSessionsEmptyState, {
|
|
29932
31902
|
sessions: deckSessions,
|
|
29933
31903
|
loading: workspacesLoading,
|
|
29934
31904
|
error: workspacesError,
|
|
29935
31905
|
onSelect: (id) => navigateToSession(id),
|
|
29936
31906
|
onOpenAll: onOpenSessionsDrawer
|
|
29937
31907
|
});
|
|
29938
|
-
return /* @__PURE__ */ (0,
|
|
31908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(PageShell, {
|
|
29939
31909
|
children: [
|
|
29940
|
-
/* @__PURE__ */ (0,
|
|
31910
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(PageGrid, {
|
|
29941
31911
|
as: "main",
|
|
29942
31912
|
className: "app-main",
|
|
29943
31913
|
children: [
|
|
29944
|
-
/* @__PURE__ */ (0,
|
|
31914
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ConversationView, {
|
|
29945
31915
|
messages,
|
|
29946
|
-
header: schema ? /* @__PURE__ */ (0,
|
|
31916
|
+
header: schema ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(InitPanel, {
|
|
29947
31917
|
schema,
|
|
29948
31918
|
value: initValue,
|
|
29949
31919
|
lockedValue: lockedInitValue,
|
|
@@ -30003,18 +31973,18 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
30003
31973
|
onScore: handleScore,
|
|
30004
31974
|
onReasonChange: handleReason
|
|
30005
31975
|
}),
|
|
30006
|
-
/* @__PURE__ */ (0,
|
|
31976
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TraceList, {
|
|
30007
31977
|
traces: simulator.traceEvents
|
|
30008
31978
|
})
|
|
30009
31979
|
]
|
|
30010
31980
|
}),
|
|
30011
|
-
/* @__PURE__ */ (0,
|
|
31981
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("footer", {
|
|
30012
31982
|
className: "composer",
|
|
30013
31983
|
children: [
|
|
30014
|
-
/* @__PURE__ */ (0,
|
|
31984
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30015
31985
|
className: "composer-inputs",
|
|
30016
31986
|
children: [
|
|
30017
|
-
/* @__PURE__ */ (0,
|
|
31987
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("textarea", {
|
|
30018
31988
|
className: "message-input",
|
|
30019
31989
|
"data-testid": "debug-message-input",
|
|
30020
31990
|
placeholder: schema && initEditable ? "Optional first message (init will be sent too)" : "Optional message (assistant can start)",
|
|
@@ -30027,23 +31997,23 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
30027
31997
|
}
|
|
30028
31998
|
}
|
|
30029
31999
|
}),
|
|
30030
|
-
/* @__PURE__ */ (0,
|
|
32000
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30031
32001
|
className: "notes-inline",
|
|
30032
32002
|
children: [
|
|
30033
|
-
/* @__PURE__ */ (0,
|
|
32003
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("header", {
|
|
30034
32004
|
children: [
|
|
30035
|
-
/* @__PURE__ */ (0,
|
|
32005
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("label", {
|
|
30036
32006
|
htmlFor: "session-notes",
|
|
30037
32007
|
children: "Session notes"
|
|
30038
32008
|
}),
|
|
30039
|
-
/* @__PURE__ */ (0,
|
|
32009
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30040
32010
|
className: "rating-controls",
|
|
30041
32011
|
children: [
|
|
30042
|
-
/* @__PURE__ */ (0,
|
|
32012
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", {
|
|
30043
32013
|
className: "rating-label",
|
|
30044
32014
|
children: "Overall score"
|
|
30045
32015
|
}),
|
|
30046
|
-
SCORE_VALUES.map((value) => /* @__PURE__ */ (0,
|
|
32016
|
+
SCORE_VALUES.map((value) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", {
|
|
30047
32017
|
type: "button",
|
|
30048
32018
|
className: classNames("rating-button", currentSessionScore === value && "active"),
|
|
30049
32019
|
onClick: () => {
|
|
@@ -30057,7 +32027,7 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
30057
32027
|
})
|
|
30058
32028
|
]
|
|
30059
32029
|
}),
|
|
30060
|
-
/* @__PURE__ */ (0,
|
|
32030
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("textarea", {
|
|
30061
32031
|
id: "session-notes",
|
|
30062
32032
|
value: noteDraft,
|
|
30063
32033
|
onChange: (e) => {
|
|
@@ -30066,14 +32036,14 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
30066
32036
|
},
|
|
30067
32037
|
placeholder: "Add context or TODOs..."
|
|
30068
32038
|
}),
|
|
30069
|
-
/* @__PURE__ */ (0,
|
|
32039
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30070
32040
|
className: "notes-inline-status",
|
|
30071
|
-
children: /* @__PURE__ */ (0,
|
|
32041
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", {
|
|
30072
32042
|
className: classNames("state", noteStatus === "saving" && "saving", noteStatus === "dirty" && "unsaved", noteStatus === "idle" && "idle", noteStatus === "saved" && "saved"),
|
|
30073
32043
|
children: noteStatus === "saving" ? "Saving\u2026" : noteStatus === "dirty" ? "Unsaved changes\u2026" : noteStatus === "saved" ? serverNotesUpdatedAt ? `Saved ${formatTimestamp(serverNotesUpdatedAt)}` : "Saved" : "No notes yet."
|
|
30074
32044
|
})
|
|
30075
32045
|
}),
|
|
30076
|
-
/* @__PURE__ */ (0,
|
|
32046
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30077
32047
|
className: "rating-status",
|
|
30078
32048
|
children: [
|
|
30079
32049
|
"Overall score:",
|
|
@@ -30087,52 +32057,52 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
30087
32057
|
})
|
|
30088
32058
|
]
|
|
30089
32059
|
}),
|
|
30090
|
-
pendingReset && /* @__PURE__ */ (0,
|
|
32060
|
+
pendingReset && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30091
32061
|
className: "reset-note",
|
|
30092
32062
|
children: "Next message will start a new chat."
|
|
30093
32063
|
}),
|
|
30094
|
-
/* @__PURE__ */ (0,
|
|
32064
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30095
32065
|
className: "composer-actions",
|
|
30096
32066
|
children: [
|
|
30097
|
-
/* @__PURE__ */ (0,
|
|
32067
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, {
|
|
30098
32068
|
variant: "primary",
|
|
30099
32069
|
onClick: handleSend,
|
|
30100
32070
|
disabled: schema && initEditable && !canStartWithInit,
|
|
30101
32071
|
"data-testid": "debug-send",
|
|
30102
32072
|
children: schema && initEditable ? "Start chat" : "Send"
|
|
30103
32073
|
}),
|
|
30104
|
-
/* @__PURE__ */ (0,
|
|
32074
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, {
|
|
30105
32075
|
variant: "secondary",
|
|
30106
32076
|
onClick: simulator.reconnect,
|
|
30107
32077
|
children: "Reconnect"
|
|
30108
32078
|
})
|
|
30109
32079
|
]
|
|
30110
32080
|
}),
|
|
30111
|
-
simulator.errors.map((err, idx) => /* @__PURE__ */ (0,
|
|
32081
|
+
simulator.errors.map((err, idx) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30112
32082
|
className: "error",
|
|
30113
32083
|
children: err
|
|
30114
32084
|
}, idx)),
|
|
30115
|
-
sessionId && /* @__PURE__ */ (0,
|
|
32085
|
+
sessionId && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30116
32086
|
className: "session-meta",
|
|
30117
32087
|
children: [
|
|
30118
32088
|
"Session: ",
|
|
30119
|
-
sessionPermalink ? /* @__PURE__ */ (0,
|
|
32089
|
+
sessionPermalink ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("a", {
|
|
30120
32090
|
href: sessionPermalink,
|
|
30121
32091
|
className: "session-link",
|
|
30122
32092
|
title: "Open session permalink",
|
|
30123
|
-
children: /* @__PURE__ */ (0,
|
|
32093
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("code", {
|
|
30124
32094
|
children: sessionId
|
|
30125
32095
|
})
|
|
30126
|
-
}) : /* @__PURE__ */ (0,
|
|
32096
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("code", {
|
|
30127
32097
|
children: sessionId
|
|
30128
32098
|
})
|
|
30129
32099
|
]
|
|
30130
32100
|
}),
|
|
30131
|
-
sessionStatePath && /* @__PURE__ */ (0,
|
|
32101
|
+
sessionStatePath && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30132
32102
|
className: "session-meta session-path",
|
|
30133
32103
|
children: [
|
|
30134
32104
|
"State file: ",
|
|
30135
|
-
/* @__PURE__ */ (0,
|
|
32105
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("code", {
|
|
30136
32106
|
children: sessionStatePath
|
|
30137
32107
|
})
|
|
30138
32108
|
]
|
|
@@ -30144,18 +32114,18 @@ function SimulatorApp({ basePath, setNavActions, workspacesApi, onOpenSessionsDr
|
|
|
30144
32114
|
}
|
|
30145
32115
|
function App() {
|
|
30146
32116
|
const simulatorBasePath = WORKSPACES_BASE_PATH;
|
|
30147
|
-
const [path, setPath] = (0,
|
|
30148
|
-
const [bundleStamp, setBundleStamp] = (0,
|
|
30149
|
-
const [navActions, setNavActions] = (0,
|
|
30150
|
-
const [sessionsDrawerOpen, setSessionsDrawerOpen] = (0,
|
|
30151
|
-
const [workbenchDrawerOpen, setWorkbenchDrawerOpen] = (0,
|
|
30152
|
-
const [workbenchComposerChips, setWorkbenchComposerChips] = (0,
|
|
30153
|
-
const [workspaceRunIds, setWorkspaceRunIds] = (0,
|
|
32117
|
+
const [path, setPath] = (0, import_react41.useState)(() => normalizeAppPath(window.location.pathname));
|
|
32118
|
+
const [bundleStamp, setBundleStamp] = (0, import_react41.useState)(null);
|
|
32119
|
+
const [navActions, setNavActions] = (0, import_react41.useState)(null);
|
|
32120
|
+
const [sessionsDrawerOpen, setSessionsDrawerOpen] = (0, import_react41.useState)(false);
|
|
32121
|
+
const [workbenchDrawerOpen, setWorkbenchDrawerOpen] = (0, import_react41.useState)(true);
|
|
32122
|
+
const [workbenchComposerChips, setWorkbenchComposerChips] = (0, import_react41.useState)([]);
|
|
32123
|
+
const [workspaceRunIds, setWorkspaceRunIds] = (0, import_react41.useState)({
|
|
30154
32124
|
testRunId: null,
|
|
30155
32125
|
gradeRunId: null
|
|
30156
32126
|
});
|
|
30157
32127
|
const workspacesApi = useWorkspaces();
|
|
30158
|
-
const [testBotResetToken, setTestBotResetToken] = (0,
|
|
32128
|
+
const [testBotResetToken, setTestBotResetToken] = (0, import_react41.useState)(0);
|
|
30159
32129
|
const pathRoute = getWorkspaceRouteFromPath(path);
|
|
30160
32130
|
const livePath = window.location.pathname.replace(/\/+$/, "") || "/";
|
|
30161
32131
|
const liveRoute = getWorkspaceRouteFromPath(livePath);
|
|
@@ -30164,23 +32134,23 @@ function App() {
|
|
|
30164
32134
|
const activeWorkspaceId = routeRequestsNewWorkspace ? null : routeState?.workspaceId ?? workspaceIdFromWindow;
|
|
30165
32135
|
const requestedTestRunId = routeState?.tab === "test" ? routeState.testRunId ?? null : null;
|
|
30166
32136
|
const requestedGradeRunId = routeState?.tab === "grade" ? routeState.gradeRunId ?? null : null;
|
|
30167
|
-
const lastWorkspaceIdRef = (0,
|
|
30168
|
-
const [workbenchSessionDetail, setWorkbenchSessionDetail] = (0,
|
|
30169
|
-
const [workbenchSessionDetailError, setWorkbenchSessionDetailError] = (0,
|
|
30170
|
-
const [workbenchSessionDetailLoading, setWorkbenchSessionDetailLoading] = (0,
|
|
30171
|
-
const workbenchSessionDetailRequestRef = (0,
|
|
30172
|
-
const workbenchSessionRetryRef = (0,
|
|
30173
|
-
const workbenchRefreshTimeoutRef = (0,
|
|
30174
|
-
const activeWorkspaceIdRef = (0,
|
|
30175
|
-
const workspaceInitRef = (0,
|
|
30176
|
-
(0,
|
|
32137
|
+
const lastWorkspaceIdRef = (0, import_react41.useRef)(null);
|
|
32138
|
+
const [workbenchSessionDetail, setWorkbenchSessionDetail] = (0, import_react41.useState)(null);
|
|
32139
|
+
const [workbenchSessionDetailError, setWorkbenchSessionDetailError] = (0, import_react41.useState)(null);
|
|
32140
|
+
const [workbenchSessionDetailLoading, setWorkbenchSessionDetailLoading] = (0, import_react41.useState)(false);
|
|
32141
|
+
const workbenchSessionDetailRequestRef = (0, import_react41.useRef)(0);
|
|
32142
|
+
const workbenchSessionRetryRef = (0, import_react41.useRef)({});
|
|
32143
|
+
const workbenchRefreshTimeoutRef = (0, import_react41.useRef)(null);
|
|
32144
|
+
const activeWorkspaceIdRef = (0, import_react41.useRef)(activeWorkspaceId);
|
|
32145
|
+
const workspaceInitRef = (0, import_react41.useRef)(false);
|
|
32146
|
+
(0, import_react41.useEffect)(() => {
|
|
30177
32147
|
if (activeWorkspaceId) {
|
|
30178
32148
|
lastWorkspaceIdRef.current = activeWorkspaceId;
|
|
30179
32149
|
}
|
|
30180
32150
|
}, [
|
|
30181
32151
|
activeWorkspaceId
|
|
30182
32152
|
]);
|
|
30183
|
-
(0,
|
|
32153
|
+
(0, import_react41.useEffect)(() => {
|
|
30184
32154
|
if (!activeWorkspaceId) {
|
|
30185
32155
|
setWorkbenchComposerChips([]);
|
|
30186
32156
|
return;
|
|
@@ -30189,7 +32159,7 @@ function App() {
|
|
|
30189
32159
|
}, [
|
|
30190
32160
|
activeWorkspaceId
|
|
30191
32161
|
]);
|
|
30192
|
-
(0,
|
|
32162
|
+
(0, import_react41.useEffect)(() => {
|
|
30193
32163
|
const syncPath = () => setPath(normalizeAppPath(window.location.pathname));
|
|
30194
32164
|
const historyObj = window.history;
|
|
30195
32165
|
const originalPushState = historyObj.pushState.bind(historyObj);
|
|
@@ -30211,7 +32181,7 @@ function App() {
|
|
|
30211
32181
|
window.removeEventListener("locationchange", syncPath);
|
|
30212
32182
|
};
|
|
30213
32183
|
}, []);
|
|
30214
|
-
const loadWorkbenchSessionDetail = (0,
|
|
32184
|
+
const loadWorkbenchSessionDetail = (0, import_react41.useCallback)(async (sessionId) => {
|
|
30215
32185
|
const requestId = ++workbenchSessionDetailRequestRef.current;
|
|
30216
32186
|
const shouldApply = () => requestId === workbenchSessionDetailRequestRef.current && activeWorkspaceIdRef.current === sessionId;
|
|
30217
32187
|
try {
|
|
@@ -30253,7 +32223,7 @@ function App() {
|
|
|
30253
32223
|
}
|
|
30254
32224
|
}
|
|
30255
32225
|
}, []);
|
|
30256
|
-
const scheduleWorkbenchRefresh = (0,
|
|
32226
|
+
const scheduleWorkbenchRefresh = (0, import_react41.useCallback)(() => {
|
|
30257
32227
|
if (!activeWorkspaceId) return;
|
|
30258
32228
|
if (workbenchRefreshTimeoutRef.current) {
|
|
30259
32229
|
window.clearTimeout(workbenchRefreshTimeoutRef.current);
|
|
@@ -30268,7 +32238,7 @@ function App() {
|
|
|
30268
32238
|
activeWorkspaceId,
|
|
30269
32239
|
loadWorkbenchSessionDetail
|
|
30270
32240
|
]);
|
|
30271
|
-
(0,
|
|
32241
|
+
(0, import_react41.useEffect)(() => {
|
|
30272
32242
|
activeWorkspaceIdRef.current = activeWorkspaceId;
|
|
30273
32243
|
if (workbenchRefreshTimeoutRef.current) {
|
|
30274
32244
|
window.clearTimeout(workbenchRefreshTimeoutRef.current);
|
|
@@ -30277,14 +32247,14 @@ function App() {
|
|
|
30277
32247
|
}, [
|
|
30278
32248
|
activeWorkspaceId
|
|
30279
32249
|
]);
|
|
30280
|
-
(0,
|
|
32250
|
+
(0, import_react41.useEffect)(() => {
|
|
30281
32251
|
return () => {
|
|
30282
32252
|
if (workbenchRefreshTimeoutRef.current) {
|
|
30283
32253
|
window.clearTimeout(workbenchRefreshTimeoutRef.current);
|
|
30284
32254
|
}
|
|
30285
32255
|
};
|
|
30286
32256
|
}, []);
|
|
30287
|
-
(0,
|
|
32257
|
+
(0, import_react41.useEffect)(() => {
|
|
30288
32258
|
if (!activeWorkspaceId) {
|
|
30289
32259
|
setWorkbenchSessionDetail(null);
|
|
30290
32260
|
setWorkbenchSessionDetailError(null);
|
|
@@ -30297,14 +32267,14 @@ function App() {
|
|
|
30297
32267
|
activeWorkspaceId,
|
|
30298
32268
|
loadWorkbenchSessionDetail
|
|
30299
32269
|
]);
|
|
30300
|
-
const handleFeedbackPersisted = (0,
|
|
32270
|
+
const handleFeedbackPersisted = (0, import_react41.useCallback)((workspaceId) => {
|
|
30301
32271
|
if (!workspaceId) return;
|
|
30302
32272
|
if (activeWorkspaceIdRef.current !== workspaceId) return;
|
|
30303
32273
|
scheduleWorkbenchRefresh();
|
|
30304
32274
|
}, [
|
|
30305
32275
|
scheduleWorkbenchRefresh
|
|
30306
32276
|
]);
|
|
30307
|
-
const applyFlagsUpdate = (0,
|
|
32277
|
+
const applyFlagsUpdate = (0, import_react41.useCallback)((flags) => {
|
|
30308
32278
|
setWorkbenchSessionDetail((prev) => {
|
|
30309
32279
|
if (!prev) return prev;
|
|
30310
32280
|
return {
|
|
@@ -30319,7 +32289,7 @@ function App() {
|
|
|
30319
32289
|
}, [
|
|
30320
32290
|
scheduleWorkbenchRefresh
|
|
30321
32291
|
]);
|
|
30322
|
-
const optimisticToggleFlag = (0,
|
|
32292
|
+
const optimisticToggleFlag = (0, import_react41.useCallback)((item) => {
|
|
30323
32293
|
setWorkbenchSessionDetail((prev) => {
|
|
30324
32294
|
if (!prev) return prev;
|
|
30325
32295
|
const meta = prev.meta ?? {};
|
|
@@ -30344,7 +32314,7 @@ function App() {
|
|
|
30344
32314
|
};
|
|
30345
32315
|
});
|
|
30346
32316
|
}, []);
|
|
30347
|
-
const optimisticFlagReason = (0,
|
|
32317
|
+
const optimisticFlagReason = (0, import_react41.useCallback)((refId, reason) => {
|
|
30348
32318
|
setWorkbenchSessionDetail((prev) => {
|
|
30349
32319
|
if (!prev) return prev;
|
|
30350
32320
|
const meta = prev.meta ?? {};
|
|
@@ -30362,7 +32332,7 @@ function App() {
|
|
|
30362
32332
|
};
|
|
30363
32333
|
});
|
|
30364
32334
|
}, []);
|
|
30365
|
-
(0,
|
|
32335
|
+
(0, import_react41.useEffect)(() => {
|
|
30366
32336
|
const loadBundleStamp = async () => {
|
|
30367
32337
|
try {
|
|
30368
32338
|
const res = await fetch("/ui/bundle.js", {
|
|
@@ -30378,36 +32348,36 @@ function App() {
|
|
|
30378
32348
|
};
|
|
30379
32349
|
loadBundleStamp();
|
|
30380
32350
|
}, []);
|
|
30381
|
-
const navigate = (0,
|
|
32351
|
+
const navigate = (0, import_react41.useCallback)((next) => {
|
|
30382
32352
|
if (next === path) return;
|
|
30383
32353
|
window.history.pushState({}, "", next);
|
|
30384
32354
|
setPath(next);
|
|
30385
32355
|
}, [
|
|
30386
32356
|
path
|
|
30387
32357
|
]);
|
|
30388
|
-
const replacePath = (0,
|
|
32358
|
+
const replacePath = (0, import_react41.useCallback)((next) => {
|
|
30389
32359
|
if (next === path) return;
|
|
30390
32360
|
window.history.replaceState({}, "", next);
|
|
30391
32361
|
setPath(next);
|
|
30392
32362
|
}, [
|
|
30393
32363
|
path
|
|
30394
32364
|
]);
|
|
30395
|
-
const handleAppPathChange = (0,
|
|
32365
|
+
const handleAppPathChange = (0, import_react41.useCallback)((next) => {
|
|
30396
32366
|
setPath(normalizeAppPath(next));
|
|
30397
32367
|
}, []);
|
|
30398
|
-
const handleReplaceTestBotSession = (0,
|
|
32368
|
+
const handleReplaceTestBotSession = (0, import_react41.useCallback)((workspaceId, runId) => replacePath(buildTestPath(workspaceId, runId)), [
|
|
30399
32369
|
replacePath
|
|
30400
32370
|
]);
|
|
30401
|
-
const handleResetTestBotSession = (0,
|
|
32371
|
+
const handleResetTestBotSession = (0, import_react41.useCallback)(() => replacePath(buildTestPath(activeWorkspaceId ?? void 0)), [
|
|
30402
32372
|
activeWorkspaceId,
|
|
30403
32373
|
replacePath
|
|
30404
32374
|
]);
|
|
30405
|
-
const handleWorkspaceChange = (0,
|
|
32375
|
+
const handleWorkspaceChange = (0, import_react41.useCallback)((workspaceId) => {
|
|
30406
32376
|
replacePath(buildWorkspacePath("build", workspaceId));
|
|
30407
32377
|
}, [
|
|
30408
32378
|
replacePath
|
|
30409
32379
|
]);
|
|
30410
|
-
(0,
|
|
32380
|
+
(0, import_react41.useEffect)(() => {
|
|
30411
32381
|
if (!buildTabEnabled && path === "/build") {
|
|
30412
32382
|
replacePath(DOCS_PATH);
|
|
30413
32383
|
}
|
|
@@ -30415,17 +32385,42 @@ function App() {
|
|
|
30415
32385
|
path,
|
|
30416
32386
|
replacePath
|
|
30417
32387
|
]);
|
|
32388
|
+
(0, import_react41.useEffect)(() => {
|
|
32389
|
+
if (verifyTabEnabled) return;
|
|
32390
|
+
const route = getWorkspaceRouteFromPath(path);
|
|
32391
|
+
if (route?.tab !== "verify") return;
|
|
32392
|
+
const fallback = route.workspaceId ? buildGradePath(route.workspaceId) : DEFAULT_GRADE_PATH;
|
|
32393
|
+
replacePath(fallback);
|
|
32394
|
+
}, [
|
|
32395
|
+
path,
|
|
32396
|
+
replacePath,
|
|
32397
|
+
verifyTabEnabled
|
|
32398
|
+
]);
|
|
30418
32399
|
const isDocs = path === DOCS_PATH;
|
|
30419
32400
|
const routeTab = liveRoute?.tab ?? pathRoute?.tab;
|
|
30420
32401
|
const isBuild = buildTabEnabled && (routeTab === "build" || path === "/build");
|
|
30421
32402
|
const isTestBot = !isDocs && (routeTab === "test" || /\/test$/.test(path));
|
|
30422
32403
|
const isGrade = !isDocs && routeTab === "grade";
|
|
30423
|
-
const
|
|
30424
|
-
|
|
32404
|
+
const isVerify = !isDocs && verifyTabEnabled && routeTab === "verify";
|
|
32405
|
+
let currentPage;
|
|
32406
|
+
if (isDocs) {
|
|
32407
|
+
currentPage = "docs";
|
|
32408
|
+
} else if (isBuild) {
|
|
32409
|
+
currentPage = "build";
|
|
32410
|
+
} else if (isTestBot) {
|
|
32411
|
+
currentPage = "test";
|
|
32412
|
+
} else if (isGrade) {
|
|
32413
|
+
currentPage = "grade";
|
|
32414
|
+
} else if (isVerify) {
|
|
32415
|
+
currentPage = "verify";
|
|
32416
|
+
} else {
|
|
32417
|
+
currentPage = "debug";
|
|
32418
|
+
}
|
|
32419
|
+
(0, import_react41.useEffect)(() => {
|
|
30425
32420
|
if (activeWorkspaceId || lastWorkspaceIdRef.current) return;
|
|
30426
32421
|
if (!routeRequestsNewWorkspace) return;
|
|
30427
32422
|
if (workspaceInitRef.current) return;
|
|
30428
|
-
if (currentPage !== "build" && currentPage !== "test" && currentPage !== "grade") {
|
|
32423
|
+
if (currentPage !== "build" && currentPage !== "test" && currentPage !== "grade" && currentPage !== "verify") {
|
|
30429
32424
|
return;
|
|
30430
32425
|
}
|
|
30431
32426
|
workspaceInitRef.current = true;
|
|
@@ -30434,7 +32429,22 @@ function App() {
|
|
|
30434
32429
|
}).then(async (res) => {
|
|
30435
32430
|
const data = await res.json().catch(() => ({}));
|
|
30436
32431
|
if (!res.ok || typeof data.workspaceId !== "string") return;
|
|
30437
|
-
|
|
32432
|
+
let nextPath;
|
|
32433
|
+
switch (currentPage) {
|
|
32434
|
+
case "test":
|
|
32435
|
+
nextPath = buildWorkspacePath("test", data.workspaceId);
|
|
32436
|
+
break;
|
|
32437
|
+
case "grade":
|
|
32438
|
+
nextPath = buildGradePath(data.workspaceId);
|
|
32439
|
+
break;
|
|
32440
|
+
case "verify":
|
|
32441
|
+
nextPath = buildWorkspacePath("verify", data.workspaceId);
|
|
32442
|
+
break;
|
|
32443
|
+
case "build":
|
|
32444
|
+
default:
|
|
32445
|
+
nextPath = buildWorkspacePath("build", data.workspaceId);
|
|
32446
|
+
break;
|
|
32447
|
+
}
|
|
30438
32448
|
replacePath(nextPath);
|
|
30439
32449
|
}).finally(() => {
|
|
30440
32450
|
workspaceInitRef.current = false;
|
|
@@ -30445,9 +32455,9 @@ function App() {
|
|
|
30445
32455
|
replacePath,
|
|
30446
32456
|
routeRequestsNewWorkspace
|
|
30447
32457
|
]);
|
|
30448
|
-
const resolveNavWorkspaceId = (0,
|
|
32458
|
+
const resolveNavWorkspaceId = (0, import_react41.useCallback)(() => {
|
|
30449
32459
|
const normalizedPath = (window.location.pathname || "/").replace(/\/+$/, "") || "/";
|
|
30450
|
-
const directMatch = normalizedPath.match(/^\/workspaces\/([^/]+)\/(?:debug|build|test|grade)(?:\/[^/]+)?$/);
|
|
32460
|
+
const directMatch = normalizedPath.match(/^\/workspaces\/([^/]+)\/(?:debug|build|test|grade|verify)(?:\/[^/]+)?$/);
|
|
30451
32461
|
if (directMatch?.[1] && directMatch[1] !== "new") {
|
|
30452
32462
|
return decodeURIComponent(directMatch[1]);
|
|
30453
32463
|
}
|
|
@@ -30455,7 +32465,7 @@ function App() {
|
|
|
30455
32465
|
}, [
|
|
30456
32466
|
activeWorkspaceId
|
|
30457
32467
|
]);
|
|
30458
|
-
const resolveNavPath = (0,
|
|
32468
|
+
const resolveNavPath = (0, import_react41.useCallback)((next) => {
|
|
30459
32469
|
if (next === "docs") return DOCS_PATH;
|
|
30460
32470
|
const workspaceId = resolveNavWorkspaceId();
|
|
30461
32471
|
if (next === "build") return buildWorkspacePath("build", workspaceId);
|
|
@@ -30465,21 +32475,44 @@ function App() {
|
|
|
30465
32475
|
if (next === "grade") {
|
|
30466
32476
|
return workspaceId ? buildGradePath(workspaceId, workspaceRunIds.gradeRunId ?? void 0) : DEFAULT_GRADE_PATH;
|
|
30467
32477
|
}
|
|
32478
|
+
if (next === "verify") {
|
|
32479
|
+
return workspaceId ? buildVerifyPath(workspaceId) : DEFAULT_VERIFY_PATH;
|
|
32480
|
+
}
|
|
30468
32481
|
return buildWorkspacePath("debug", workspaceId);
|
|
30469
32482
|
}, [
|
|
32483
|
+
DEFAULT_VERIFY_PATH,
|
|
30470
32484
|
resolveNavWorkspaceId,
|
|
30471
32485
|
workspaceRunIds.gradeRunId,
|
|
30472
32486
|
workspaceRunIds.testRunId
|
|
30473
32487
|
]);
|
|
30474
|
-
const handleSelectSession = (0,
|
|
30475
|
-
|
|
32488
|
+
const handleSelectSession = (0, import_react41.useCallback)((sessionId) => {
|
|
32489
|
+
let nextPath;
|
|
32490
|
+
switch (currentPage) {
|
|
32491
|
+
case "docs":
|
|
32492
|
+
case "test":
|
|
32493
|
+
nextPath = buildWorkspacePath("test", sessionId);
|
|
32494
|
+
break;
|
|
32495
|
+
case "grade":
|
|
32496
|
+
nextPath = buildGradePath(sessionId);
|
|
32497
|
+
break;
|
|
32498
|
+
case "verify":
|
|
32499
|
+
nextPath = buildVerifyPath(sessionId);
|
|
32500
|
+
break;
|
|
32501
|
+
case "build":
|
|
32502
|
+
nextPath = buildWorkspacePath("build", sessionId);
|
|
32503
|
+
break;
|
|
32504
|
+
case "debug":
|
|
32505
|
+
default:
|
|
32506
|
+
nextPath = buildWorkspacePath("debug", sessionId);
|
|
32507
|
+
break;
|
|
32508
|
+
}
|
|
30476
32509
|
navigate(nextPath);
|
|
30477
32510
|
setSessionsDrawerOpen(false);
|
|
30478
32511
|
}, [
|
|
30479
32512
|
currentPage,
|
|
30480
32513
|
navigate
|
|
30481
32514
|
]);
|
|
30482
|
-
(0,
|
|
32515
|
+
(0, import_react41.useEffect)(() => {
|
|
30483
32516
|
if (sessionsDrawerOpen) {
|
|
30484
32517
|
workspacesApi.refresh();
|
|
30485
32518
|
}
|
|
@@ -30487,7 +32520,7 @@ function App() {
|
|
|
30487
32520
|
workspacesApi.refresh,
|
|
30488
32521
|
sessionsDrawerOpen
|
|
30489
32522
|
]);
|
|
30490
|
-
const deckSessions = (0,
|
|
32523
|
+
const deckSessions = (0, import_react41.useMemo)(() => {
|
|
30491
32524
|
if (workspaceIdFromWindow) {
|
|
30492
32525
|
return workspacesApi.workspaces;
|
|
30493
32526
|
}
|
|
@@ -30510,7 +32543,7 @@ function App() {
|
|
|
30510
32543
|
repoRootPath,
|
|
30511
32544
|
workspaceIdFromWindow
|
|
30512
32545
|
]);
|
|
30513
|
-
const handleDeleteAll = (0,
|
|
32546
|
+
const handleDeleteAll = (0, import_react41.useCallback)(async () => {
|
|
30514
32547
|
await workspacesApi.deleteAll(deckSessions);
|
|
30515
32548
|
setTestBotResetToken((prev) => prev + 1);
|
|
30516
32549
|
setSessionsDrawerOpen(false);
|
|
@@ -30519,7 +32552,7 @@ function App() {
|
|
|
30519
32552
|
deckSessions,
|
|
30520
32553
|
workspacesApi.deleteAll
|
|
30521
32554
|
]);
|
|
30522
|
-
const handleDeleteSession = (0,
|
|
32555
|
+
const handleDeleteSession = (0, import_react41.useCallback)(async (sessionId) => {
|
|
30523
32556
|
await workspacesApi.deleteWorkspace(sessionId);
|
|
30524
32557
|
if (sessionId === activeWorkspaceId) {
|
|
30525
32558
|
window.location.assign(DEFAULT_TEST_PATH);
|
|
@@ -30528,11 +32561,12 @@ function App() {
|
|
|
30528
32561
|
activeWorkspaceId,
|
|
30529
32562
|
workspacesApi.deleteWorkspace
|
|
30530
32563
|
]);
|
|
30531
|
-
const
|
|
32564
|
+
const handleAddErrorToWorkbench = (0, import_react41.useCallback)((payload) => {
|
|
30532
32565
|
const resolvedWorkspaceId = payload.workspaceId ?? activeWorkspaceId ?? void 0;
|
|
32566
|
+
const source = payload.source ?? "scenario_run_error";
|
|
30533
32567
|
const nextChip = {
|
|
30534
|
-
chipId: `error:${resolvedWorkspaceId ?? ""}:${payload.runId ?? ""}:${payload.error}`,
|
|
30535
|
-
source
|
|
32568
|
+
chipId: `error:${source}:${resolvedWorkspaceId ?? ""}:${payload.runId ?? ""}:${payload.error}`,
|
|
32569
|
+
source,
|
|
30536
32570
|
workspaceId: resolvedWorkspaceId,
|
|
30537
32571
|
runId: payload.runId,
|
|
30538
32572
|
error: payload.error,
|
|
@@ -30559,30 +32593,97 @@ function App() {
|
|
|
30559
32593
|
}, [
|
|
30560
32594
|
activeWorkspaceId
|
|
30561
32595
|
]);
|
|
30562
|
-
|
|
32596
|
+
const pageContent = (0, import_react41.useMemo)(() => {
|
|
32597
|
+
switch (currentPage) {
|
|
32598
|
+
case "docs":
|
|
32599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(DocsPage, {});
|
|
32600
|
+
case "build":
|
|
32601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(BuildPage, {
|
|
32602
|
+
setNavActions
|
|
32603
|
+
});
|
|
32604
|
+
case "debug":
|
|
32605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(SimulatorApp, {
|
|
32606
|
+
basePath: simulatorBasePath,
|
|
32607
|
+
setNavActions,
|
|
32608
|
+
workspacesApi,
|
|
32609
|
+
onOpenSessionsDrawer: () => setSessionsDrawerOpen(true),
|
|
32610
|
+
activeWorkspaceId
|
|
32611
|
+
});
|
|
32612
|
+
case "test":
|
|
32613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TestBotPage, {
|
|
32614
|
+
onReplaceTestBotSession: handleReplaceTestBotSession,
|
|
32615
|
+
onResetTestBotSession: handleResetTestBotSession,
|
|
32616
|
+
activeWorkspaceId,
|
|
32617
|
+
requestedRunId: requestedTestRunId,
|
|
32618
|
+
resetToken: testBotResetToken,
|
|
32619
|
+
setNavActions,
|
|
32620
|
+
onFeedbackPersisted: handleFeedbackPersisted,
|
|
32621
|
+
onAddErrorToWorkbench: handleAddErrorToWorkbench
|
|
32622
|
+
});
|
|
32623
|
+
case "verify":
|
|
32624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(VerifyPage_default, {
|
|
32625
|
+
setNavActions,
|
|
32626
|
+
onAppPathChange: handleAppPathChange,
|
|
32627
|
+
activeWorkspaceId,
|
|
32628
|
+
composerChips: workbenchComposerChips,
|
|
32629
|
+
onComposerChipsChange: setWorkbenchComposerChips
|
|
32630
|
+
});
|
|
32631
|
+
case "grade":
|
|
32632
|
+
default:
|
|
32633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(GradePage_default, {
|
|
32634
|
+
setNavActions,
|
|
32635
|
+
onAppPathChange: handleAppPathChange,
|
|
32636
|
+
activeWorkspaceId,
|
|
32637
|
+
requestedGradeRunId,
|
|
32638
|
+
onFlagsUpdate: applyFlagsUpdate,
|
|
32639
|
+
onOptimisticToggleFlag: optimisticToggleFlag,
|
|
32640
|
+
onOptimisticFlagReason: optimisticFlagReason,
|
|
32641
|
+
onAddErrorToWorkbench: handleAddErrorToWorkbench
|
|
32642
|
+
});
|
|
32643
|
+
}
|
|
32644
|
+
}, [
|
|
32645
|
+
activeWorkspaceId,
|
|
32646
|
+
applyFlagsUpdate,
|
|
32647
|
+
currentPage,
|
|
32648
|
+
handleAddErrorToWorkbench,
|
|
32649
|
+
handleAppPathChange,
|
|
32650
|
+
handleFeedbackPersisted,
|
|
32651
|
+
handleReplaceTestBotSession,
|
|
32652
|
+
handleResetTestBotSession,
|
|
32653
|
+
optimisticFlagReason,
|
|
32654
|
+
optimisticToggleFlag,
|
|
32655
|
+
requestedGradeRunId,
|
|
32656
|
+
requestedTestRunId,
|
|
32657
|
+
setNavActions,
|
|
32658
|
+
simulatorBasePath,
|
|
32659
|
+
testBotResetToken,
|
|
32660
|
+
workbenchComposerChips,
|
|
32661
|
+
workspacesApi
|
|
32662
|
+
]);
|
|
32663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(WorkspaceProvider, {
|
|
30563
32664
|
workspaceId: activeWorkspaceId,
|
|
30564
32665
|
onWorkspaceChange: handleWorkspaceChange,
|
|
30565
32666
|
requestedTestRunId: routeState?.tab === "test" ? requestedTestRunId : void 0,
|
|
30566
32667
|
requestedGradeRunId: routeState?.tab === "grade" ? requestedGradeRunId : void 0,
|
|
30567
32668
|
onRoutingStateChange: setWorkspaceRunIds,
|
|
30568
|
-
children: /* @__PURE__ */ (0,
|
|
32669
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, {
|
|
30569
32670
|
children: [
|
|
30570
|
-
/* @__PURE__ */ (0,
|
|
32671
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30571
32672
|
className: "app-frame",
|
|
30572
|
-
children: /* @__PURE__ */ (0,
|
|
32673
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30573
32674
|
className: "app-root",
|
|
30574
32675
|
children: [
|
|
30575
|
-
/* @__PURE__ */ (0,
|
|
32676
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30576
32677
|
className: "top-nav",
|
|
30577
32678
|
children: [
|
|
30578
|
-
/* @__PURE__ */ (0,
|
|
32679
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30579
32680
|
className: "top-nav-left",
|
|
30580
|
-
children: /* @__PURE__ */ (0,
|
|
32681
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, {
|
|
30581
32682
|
variant: sessionsDrawerOpen ? "primary-deemph" : "ghost",
|
|
30582
32683
|
className: classNames("sessions-toggle", sessionsDrawerOpen && "active"),
|
|
30583
32684
|
onClick: () => setSessionsDrawerOpen(true),
|
|
30584
32685
|
"data-testid": "nav-sessions",
|
|
30585
|
-
children: /* @__PURE__ */ (0,
|
|
32686
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, {
|
|
30586
32687
|
name: "hamburgerMenu",
|
|
30587
32688
|
size: 17,
|
|
30588
32689
|
style: {
|
|
@@ -30591,7 +32692,7 @@ function App() {
|
|
|
30591
32692
|
})
|
|
30592
32693
|
})
|
|
30593
32694
|
}),
|
|
30594
|
-
/* @__PURE__ */ (0,
|
|
32695
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Tabs, {
|
|
30595
32696
|
className: "top-nav-buttons",
|
|
30596
32697
|
activeId: currentPage,
|
|
30597
32698
|
onChange: (next) => navigate(resolveNavPath(next)),
|
|
@@ -30622,6 +32723,14 @@ function App() {
|
|
|
30622
32723
|
testId: "nav-grade",
|
|
30623
32724
|
href: resolveNavPath("grade")
|
|
30624
32725
|
},
|
|
32726
|
+
...verifyTabEnabled ? [
|
|
32727
|
+
{
|
|
32728
|
+
id: "verify",
|
|
32729
|
+
label: "Verify",
|
|
32730
|
+
testId: "nav-verify",
|
|
32731
|
+
href: resolveNavPath("verify")
|
|
32732
|
+
}
|
|
32733
|
+
] : [],
|
|
30625
32734
|
{
|
|
30626
32735
|
id: "debug",
|
|
30627
32736
|
label: "Debug",
|
|
@@ -30630,27 +32739,27 @@ function App() {
|
|
|
30630
32739
|
}
|
|
30631
32740
|
]
|
|
30632
32741
|
}),
|
|
30633
|
-
/* @__PURE__ */ (0,
|
|
32742
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30634
32743
|
className: "top-nav-center",
|
|
30635
|
-
children: /* @__PURE__ */ (0,
|
|
32744
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", {
|
|
30636
32745
|
className: "top-nav-deck",
|
|
30637
32746
|
title: deckPath,
|
|
30638
32747
|
children: deckLabel
|
|
30639
32748
|
})
|
|
30640
32749
|
}),
|
|
30641
|
-
/* @__PURE__ */ (0,
|
|
32750
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30642
32751
|
className: "top-nav-right",
|
|
30643
|
-
children: /* @__PURE__ */ (0,
|
|
32752
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30644
32753
|
className: "top-nav-actions",
|
|
30645
32754
|
children: [
|
|
30646
32755
|
navActions,
|
|
30647
|
-
/* @__PURE__ */ (0,
|
|
32756
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, {
|
|
30648
32757
|
variant: workbenchDrawerOpen ? "primary-deemph" : "ghost",
|
|
30649
32758
|
className: classNames("workbench-toggle", workbenchDrawerOpen && "active"),
|
|
30650
32759
|
onClick: () => setWorkbenchDrawerOpen((prev) => !prev),
|
|
30651
32760
|
"aria-label": workbenchDrawerOpen ? "Close workbench drawer" : "Open workbench drawer",
|
|
30652
32761
|
"data-testid": "nav-workbench",
|
|
30653
|
-
children: /* @__PURE__ */ (0,
|
|
32762
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, {
|
|
30654
32763
|
name: "chat",
|
|
30655
32764
|
size: 16,
|
|
30656
32765
|
style: {
|
|
@@ -30663,39 +32772,14 @@ function App() {
|
|
|
30663
32772
|
})
|
|
30664
32773
|
]
|
|
30665
32774
|
}),
|
|
30666
|
-
/* @__PURE__ */ (0,
|
|
32775
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", {
|
|
30667
32776
|
className: "app-content-frame",
|
|
30668
32777
|
children: [
|
|
30669
|
-
/* @__PURE__ */ (0,
|
|
32778
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", {
|
|
30670
32779
|
className: "page-shell",
|
|
30671
|
-
children:
|
|
30672
|
-
setNavActions
|
|
30673
|
-
}) : currentPage === "debug" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(SimulatorApp, {
|
|
30674
|
-
basePath: simulatorBasePath,
|
|
30675
|
-
setNavActions,
|
|
30676
|
-
workspacesApi,
|
|
30677
|
-
onOpenSessionsDrawer: () => setSessionsDrawerOpen(true),
|
|
30678
|
-
activeWorkspaceId
|
|
30679
|
-
}) : currentPage === "test" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(TestBotPage, {
|
|
30680
|
-
onReplaceTestBotSession: handleReplaceTestBotSession,
|
|
30681
|
-
onResetTestBotSession: handleResetTestBotSession,
|
|
30682
|
-
activeWorkspaceId,
|
|
30683
|
-
requestedRunId: requestedTestRunId,
|
|
30684
|
-
resetToken: testBotResetToken,
|
|
30685
|
-
setNavActions,
|
|
30686
|
-
onFeedbackPersisted: handleFeedbackPersisted,
|
|
30687
|
-
onAddScenarioErrorToWorkbench: handleAddScenarioErrorToWorkbench
|
|
30688
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(GradePage_default, {
|
|
30689
|
-
setNavActions,
|
|
30690
|
-
onAppPathChange: handleAppPathChange,
|
|
30691
|
-
activeWorkspaceId,
|
|
30692
|
-
requestedGradeRunId,
|
|
30693
|
-
onFlagsUpdate: applyFlagsUpdate,
|
|
30694
|
-
onOptimisticToggleFlag: optimisticToggleFlag,
|
|
30695
|
-
onOptimisticFlagReason: optimisticFlagReason
|
|
30696
|
-
})
|
|
32780
|
+
children: pageContent
|
|
30697
32781
|
}),
|
|
30698
|
-
workbenchDrawerOpen && /* @__PURE__ */ (0,
|
|
32782
|
+
workbenchDrawerOpen && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(WorkbenchDrawer, {
|
|
30699
32783
|
open: workbenchDrawerOpen,
|
|
30700
32784
|
onClose: () => setWorkbenchDrawerOpen(false),
|
|
30701
32785
|
loading: workbenchSessionDetailLoading,
|
|
@@ -30710,7 +32794,7 @@ function App() {
|
|
|
30710
32794
|
]
|
|
30711
32795
|
})
|
|
30712
32796
|
}),
|
|
30713
|
-
/* @__PURE__ */ (0,
|
|
32797
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AppDrawer, {
|
|
30714
32798
|
open: sessionsDrawerOpen,
|
|
30715
32799
|
workspaces: deckSessions,
|
|
30716
32800
|
loading: workspacesApi.loading,
|
|
@@ -30727,8 +32811,8 @@ function App() {
|
|
|
30727
32811
|
})
|
|
30728
32812
|
});
|
|
30729
32813
|
}
|
|
30730
|
-
(0, import_client.createRoot)(document.getElementById("root")).render(/* @__PURE__ */ (0,
|
|
30731
|
-
children: /* @__PURE__ */ (0,
|
|
32814
|
+
(0, import_client.createRoot)(document.getElementById("root")).render(/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react41.default.StrictMode, {
|
|
32815
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(App, {})
|
|
30732
32816
|
}));
|
|
30733
32817
|
/**
|
|
30734
32818
|
* @license React
|