sunpeak 0.20.35 → 0.20.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/bin/commands/inspect.mjs +241 -48
- package/bin/commands/test-init.mjs +61 -44
- package/bin/lib/eval/eval-runner.mjs +49 -1
- package/bin/lib/eval/eval-types.d.mts +27 -0
- package/bin/lib/eval/model-registry.mjs +6 -3
- package/bin/lib/test/test-fixtures.d.mts +9 -1
- package/bin/lib/test/test-fixtures.mjs +25 -7
- package/dist/chatgpt/index.cjs +1 -1
- package/dist/chatgpt/index.js +1 -1
- package/dist/claude/index.cjs +1 -1
- package/dist/claude/index.js +1 -1
- package/dist/embed.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/inspector/app-types.d.ts +6 -4
- package/dist/inspector/index.cjs +1 -1
- package/dist/inspector/index.js +1 -1
- package/dist/inspector/inspector.d.ts +12 -4
- package/dist/inspector/simple-sidebar.d.ts +20 -6
- package/dist/inspector/use-inspector-state.d.ts +32 -0
- package/dist/{inspector-D0TWNx_T.js → inspector-C6n8zap3.js} +432 -171
- package/dist/{inspector-D0TWNx_T.js.map → inspector-C6n8zap3.js.map} +1 -1
- package/dist/{inspector-DQ_vv1wj.cjs → inspector-DOmiG64-.cjs} +432 -171
- package/dist/{inspector-DQ_vv1wj.cjs.map → inspector-DOmiG64-.cjs.map} +1 -1
- package/dist/style.css +18 -14
- package/package.json +1 -1
- package/template/dist/albums/albums.html +1 -1
- package/template/dist/albums/albums.json +1 -1
- package/template/dist/carousel/carousel.html +1 -1
- package/template/dist/carousel/carousel.json +1 -1
- package/template/dist/map/map.html +1 -1
- package/template/dist/map/map.json +1 -1
- package/template/dist/review/review.html +1 -1
- package/template/dist/review/review.json +1 -1
- package/template/tests/e2e/visual.spec.ts +0 -8
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-chatgpt-darwin.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-chatgpt-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-claude-darwin.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-fullscreen-claude-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-chatgpt-darwin.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-chatgpt-linux.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-claude-darwin.png +0 -0
- package/template/tests/e2e/visual.spec.ts-snapshots/albums-page-light-claude-linux.png +0 -0
|
@@ -6435,6 +6435,7 @@ function IframeResource({ src, scriptSrc, html, hostContext, toolInput, toolInpu
|
|
|
6435
6435
|
var DEFAULT_THEME = "dark";
|
|
6436
6436
|
var DEFAULT_DISPLAY_MODE = "inline";
|
|
6437
6437
|
var DEFAULT_PLATFORM = "desktop";
|
|
6438
|
+
var DEFAULT_SIDEBAR_WIDTH$1 = 260;
|
|
6438
6439
|
/**
|
|
6439
6440
|
* Parse URL params for initial inspector values.
|
|
6440
6441
|
* Supported params:
|
|
@@ -6538,6 +6539,9 @@ var VALID_SCREEN_WIDTHS = new Set([
|
|
|
6538
6539
|
"tablet",
|
|
6539
6540
|
"full"
|
|
6540
6541
|
]);
|
|
6542
|
+
function isSafeStoredString(value) {
|
|
6543
|
+
return typeof value === "string" && value.length <= 200 && !/[\u0000-\u001f\u007f]/.test(value);
|
|
6544
|
+
}
|
|
6541
6545
|
function sanitizeStoredPrefs(raw) {
|
|
6542
6546
|
if (!raw || typeof raw !== "object") return {};
|
|
6543
6547
|
const obj = raw;
|
|
@@ -6545,6 +6549,8 @@ function sanitizeStoredPrefs(raw) {
|
|
|
6545
6549
|
if (typeof obj.theme === "string" && VALID_THEMES.has(obj.theme)) prefs.theme = obj.theme;
|
|
6546
6550
|
if (typeof obj.locale === "string") prefs.locale = obj.locale;
|
|
6547
6551
|
if (typeof obj.displayMode === "string" && VALID_DISPLAY_MODES.has(obj.displayMode)) prefs.displayMode = obj.displayMode;
|
|
6552
|
+
if (typeof obj.containerHeight === "number" && Number.isFinite(obj.containerHeight)) prefs.containerHeight = obj.containerHeight;
|
|
6553
|
+
if (typeof obj.containerWidth === "number" && Number.isFinite(obj.containerWidth)) prefs.containerWidth = obj.containerWidth;
|
|
6548
6554
|
if (typeof obj.containerMaxHeight === "number" && Number.isFinite(obj.containerMaxHeight)) prefs.containerMaxHeight = obj.containerMaxHeight;
|
|
6549
6555
|
if (typeof obj.containerMaxWidth === "number" && Number.isFinite(obj.containerMaxWidth)) prefs.containerMaxWidth = obj.containerMaxWidth;
|
|
6550
6556
|
if (obj.safeAreaInsets && typeof obj.safeAreaInsets === "object") {
|
|
@@ -6561,6 +6567,12 @@ function sanitizeStoredPrefs(raw) {
|
|
|
6561
6567
|
if (typeof obj.hover === "boolean") prefs.hover = obj.hover;
|
|
6562
6568
|
if (typeof obj.touch === "boolean") prefs.touch = obj.touch;
|
|
6563
6569
|
if (typeof obj.screenWidth === "string" && VALID_SCREEN_WIDTHS.has(obj.screenWidth)) prefs.screenWidth = obj.screenWidth;
|
|
6570
|
+
if (typeof obj.sidebarWidth === "number" && Number.isFinite(obj.sidebarWidth)) prefs.sidebarWidth = Math.max(DEFAULT_SIDEBAR_WIDTH$1, Math.round(obj.sidebarWidth));
|
|
6571
|
+
if (typeof obj.rightSidebarWidth === "number" && Number.isFinite(obj.rightSidebarWidth)) prefs.rightSidebarWidth = Math.max(DEFAULT_SIDEBAR_WIDTH$1, Math.round(obj.rightSidebarWidth));
|
|
6572
|
+
if (typeof obj.timeZone === "string") prefs.timeZone = obj.timeZone;
|
|
6573
|
+
if (typeof obj.prodResources === "boolean") prefs.prodResources = obj.prodResources;
|
|
6574
|
+
if (isSafeStoredString(obj.modelProvider)) prefs.modelProvider = obj.modelProvider;
|
|
6575
|
+
if (isSafeStoredString(obj.modelId)) prefs.modelId = obj.modelId;
|
|
6564
6576
|
return prefs;
|
|
6565
6577
|
}
|
|
6566
6578
|
function readStoredPrefs() {
|
|
@@ -6573,6 +6585,12 @@ function readStoredPrefs() {
|
|
|
6573
6585
|
return {};
|
|
6574
6586
|
}
|
|
6575
6587
|
}
|
|
6588
|
+
function writeStoredPrefs(prefs) {
|
|
6589
|
+
if (typeof window === "undefined") return;
|
|
6590
|
+
try {
|
|
6591
|
+
localStorage.setItem(PREFS_KEY, JSON.stringify(prefs));
|
|
6592
|
+
} catch {}
|
|
6593
|
+
}
|
|
6576
6594
|
function deriveContainerDimensions({ displayMode, containerHeight, containerWidth, containerMaxHeight, containerMaxWidth, measuredContentWidth, viewportHeight = 800, viewportWidth = 1280 }) {
|
|
6577
6595
|
if (containerHeight != null || containerWidth != null || containerMaxHeight != null || containerMaxWidth != null) return {
|
|
6578
6596
|
...containerHeight != null ? { height: containerHeight } : {},
|
|
@@ -6591,36 +6609,38 @@ function deriveContainerDimensions({ displayMode, containerHeight, containerWidt
|
|
|
6591
6609
|
if (measuredContentWidth != null) return { maxWidth: measuredContentWidth };
|
|
6592
6610
|
}
|
|
6593
6611
|
function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolDataOnSimulationChange = false }) {
|
|
6594
|
-
const simulationNames = Object.keys(simulations).
|
|
6612
|
+
const simulationNames = Object.keys(simulations).sort((a, b) => {
|
|
6595
6613
|
const simA = simulations[a];
|
|
6596
6614
|
const simB = simulations[b];
|
|
6597
|
-
const resourceLabelA = simA.resource.title || simA.resource.name;
|
|
6598
|
-
const resourceLabelB = simB.resource.title || simB.resource.name;
|
|
6599
|
-
const labelA = `${resourceLabelA}
|
|
6600
|
-
const labelB = `${resourceLabelB}
|
|
6615
|
+
const resourceLabelA = simA.resource ? `${simA.resource.title || simA.resource.name}: ` : "";
|
|
6616
|
+
const resourceLabelB = simB.resource ? `${simB.resource.title || simB.resource.name}: ` : "";
|
|
6617
|
+
const labelA = `${resourceLabelA}${simA.tool.title || simA.tool.name}`;
|
|
6618
|
+
const labelB = `${resourceLabelB}${simB.tool.title || simB.tool.name}`;
|
|
6601
6619
|
return labelA.localeCompare(labelB);
|
|
6602
6620
|
});
|
|
6621
|
+
const defaultSimulationName = simulationNames.find((name) => !!simulations[name]?.resource) ?? simulationNames[0] ?? "";
|
|
6603
6622
|
const urlParams = (0, react.useMemo)(() => parseUrlParams(), []);
|
|
6604
6623
|
const autoRun = urlParams.autoRun === true;
|
|
6605
6624
|
const storedPrefs = (0, react.useMemo)(() => autoRun ? {} : readStoredPrefs(), [autoRun]);
|
|
6606
6625
|
const [screenWidth, setScreenWidth] = (0, react.useState)(storedPrefs.screenWidth ?? "full");
|
|
6626
|
+
const [sidebarWidth, setSidebarWidth] = (0, react.useState)(storedPrefs.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH$1);
|
|
6627
|
+
const [rightSidebarWidth, setRightSidebarWidth] = (0, react.useState)(storedPrefs.rightSidebarWidth ?? DEFAULT_SIDEBAR_WIDTH$1);
|
|
6607
6628
|
const isMobileWidth = (width) => width === "mobile-s" || width === "mobile-l";
|
|
6608
6629
|
const [activeHost, setActiveHost] = (0, react.useState)(urlParams.host ?? storedPrefs.activeHost ?? defaultHost);
|
|
6609
6630
|
const [selectedSimulationName, setSelectedSimulationName] = (0, react.useState)((0, react.useMemo)(() => {
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
return urlParams.simulation in simulations ? urlParams.simulation : defaultName;
|
|
6631
|
+
if (!urlParams.simulation) return defaultSimulationName;
|
|
6632
|
+
return urlParams.simulation in simulations ? urlParams.simulation : defaultSimulationName;
|
|
6613
6633
|
}, [
|
|
6614
6634
|
urlParams.simulation,
|
|
6615
6635
|
simulations,
|
|
6616
|
-
|
|
6636
|
+
defaultSimulationName
|
|
6617
6637
|
]));
|
|
6618
6638
|
const selectedSim = simulations[selectedSimulationName];
|
|
6619
6639
|
const [theme, setTheme] = (0, react.useState)(urlParams.theme ?? storedPrefs.theme ?? DEFAULT_THEME);
|
|
6620
6640
|
const [displayMode, _setDisplayMode] = (0, react.useState)(urlParams.displayMode ?? storedPrefs.displayMode ?? DEFAULT_DISPLAY_MODE);
|
|
6621
6641
|
const [locale, setLocale] = (0, react.useState)(urlParams.locale ?? storedPrefs.locale ?? "en-US");
|
|
6622
|
-
const [containerHeight, setContainerHeight] = (0, react.useState)(
|
|
6623
|
-
const [containerWidth, setContainerWidth] = (0, react.useState)(
|
|
6642
|
+
const [containerHeight, setContainerHeight] = (0, react.useState)(storedPrefs.containerHeight);
|
|
6643
|
+
const [containerWidth, setContainerWidth] = (0, react.useState)(storedPrefs.containerWidth);
|
|
6624
6644
|
const [containerMaxHeight, setContainerMaxHeight] = (0, react.useState)(urlParams.containerMaxHeight ?? storedPrefs.containerMaxHeight);
|
|
6625
6645
|
const [containerMaxWidth, setContainerMaxWidth] = (0, react.useState)(urlParams.containerMaxWidth ?? storedPrefs.containerMaxWidth);
|
|
6626
6646
|
const [platform, setPlatform] = (0, react.useState)(urlParams.platform ?? storedPrefs.platform ?? DEFAULT_PLATFORM);
|
|
@@ -6632,7 +6652,7 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6632
6652
|
left: 0,
|
|
6633
6653
|
right: 0
|
|
6634
6654
|
});
|
|
6635
|
-
const [timeZone, setTimeZone] = (0, react.useState)(() => Intl.DateTimeFormat().resolvedOptions().timeZone);
|
|
6655
|
+
const [timeZone, setTimeZone] = (0, react.useState)(() => storedPrefs.timeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone);
|
|
6636
6656
|
const isFirstRender = (0, react.useRef)(true);
|
|
6637
6657
|
(0, react.useEffect)(() => {
|
|
6638
6658
|
if (isFirstRender.current) {
|
|
@@ -6640,27 +6660,32 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6640
6660
|
return;
|
|
6641
6661
|
}
|
|
6642
6662
|
if (autoRun) return;
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6663
|
+
writeStoredPrefs({
|
|
6664
|
+
...readStoredPrefs(),
|
|
6665
|
+
theme,
|
|
6666
|
+
locale,
|
|
6667
|
+
displayMode,
|
|
6668
|
+
containerHeight,
|
|
6669
|
+
containerWidth,
|
|
6670
|
+
containerMaxHeight,
|
|
6671
|
+
containerMaxWidth,
|
|
6672
|
+
safeAreaInsets,
|
|
6673
|
+
activeHost,
|
|
6674
|
+
platform,
|
|
6675
|
+
hover,
|
|
6676
|
+
touch,
|
|
6677
|
+
screenWidth,
|
|
6678
|
+
sidebarWidth,
|
|
6679
|
+
rightSidebarWidth,
|
|
6680
|
+
timeZone
|
|
6681
|
+
});
|
|
6659
6682
|
}, [
|
|
6660
6683
|
autoRun,
|
|
6661
6684
|
theme,
|
|
6662
6685
|
locale,
|
|
6663
6686
|
displayMode,
|
|
6687
|
+
containerHeight,
|
|
6688
|
+
containerWidth,
|
|
6664
6689
|
containerMaxHeight,
|
|
6665
6690
|
containerMaxWidth,
|
|
6666
6691
|
safeAreaInsets,
|
|
@@ -6668,7 +6693,10 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6668
6693
|
platform,
|
|
6669
6694
|
hover,
|
|
6670
6695
|
touch,
|
|
6671
|
-
screenWidth
|
|
6696
|
+
screenWidth,
|
|
6697
|
+
sidebarWidth,
|
|
6698
|
+
rightSidebarWidth,
|
|
6699
|
+
timeZone
|
|
6672
6700
|
]);
|
|
6673
6701
|
const [measuredContentWidth, setMeasuredContentWidth] = (0, react.useState)(void 0);
|
|
6674
6702
|
const handleContentWidthChange = (0, react.useCallback)((width) => {
|
|
@@ -6753,6 +6781,8 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6753
6781
|
}
|
|
6754
6782
|
if (editingField !== "modelContext") {
|
|
6755
6783
|
setModelContext(null);
|
|
6784
|
+
setModelAppContext(null);
|
|
6785
|
+
setModelContextJson("null");
|
|
6756
6786
|
setModelContextError("");
|
|
6757
6787
|
}
|
|
6758
6788
|
}, [
|
|
@@ -6829,6 +6859,10 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6829
6859
|
setActiveHost,
|
|
6830
6860
|
screenWidth,
|
|
6831
6861
|
setScreenWidth,
|
|
6862
|
+
sidebarWidth,
|
|
6863
|
+
setSidebarWidth,
|
|
6864
|
+
rightSidebarWidth,
|
|
6865
|
+
setRightSidebarWidth,
|
|
6832
6866
|
theme,
|
|
6833
6867
|
setTheme,
|
|
6834
6868
|
displayMode,
|
|
@@ -7059,9 +7093,10 @@ var useThemeContext = () => {
|
|
|
7059
7093
|
if (context === void 0) throw new Error("useThemeContext must be used within a ThemeProvider");
|
|
7060
7094
|
return context;
|
|
7061
7095
|
};
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7096
|
+
function clampSidebarWidth(rawWidth, viewportWidth) {
|
|
7097
|
+
const maxWidth = Math.floor(viewportWidth / 3);
|
|
7098
|
+
return Math.max(260, Math.min(maxWidth, rawWidth));
|
|
7099
|
+
}
|
|
7065
7100
|
function ChevronRightIcon() {
|
|
7066
7101
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
7067
7102
|
width: "1em",
|
|
@@ -7075,19 +7110,34 @@ function ChevronRightIcon() {
|
|
|
7075
7110
|
})
|
|
7076
7111
|
});
|
|
7077
7112
|
}
|
|
7078
|
-
function SimpleSidebar({ children, controls, headerRight, rootRef, fillParent = false }) {
|
|
7113
|
+
function SimpleSidebar({ children, controls, rightControls, sidebarWidth, rightSidebarWidth, onSidebarWidthChange, onRightSidebarWidthChange, headerRight, rootRef, fillParent = false }) {
|
|
7079
7114
|
const [isDrawerOpen, setIsDrawerOpen] = react.useState(false);
|
|
7080
|
-
const [
|
|
7115
|
+
const [internalSidebarWidth, setInternalSidebarWidth] = react.useState(260);
|
|
7116
|
+
const [internalRightSidebarWidth, setInternalRightSidebarWidth] = react.useState(260);
|
|
7081
7117
|
const [isResizing, setIsResizing] = react.useState(false);
|
|
7118
|
+
const [isResizingRight, setIsResizingRight] = react.useState(false);
|
|
7119
|
+
const effectiveSidebarWidth = sidebarWidth ?? internalSidebarWidth;
|
|
7120
|
+
const effectiveRightSidebarWidth = rightSidebarWidth ?? internalRightSidebarWidth;
|
|
7121
|
+
const setSidebarWidth = react.useCallback((width) => {
|
|
7122
|
+
setInternalSidebarWidth(width);
|
|
7123
|
+
onSidebarWidthChange?.(width);
|
|
7124
|
+
}, [onSidebarWidthChange]);
|
|
7125
|
+
const setRightSidebarWidth = react.useCallback((width) => {
|
|
7126
|
+
setInternalRightSidebarWidth(width);
|
|
7127
|
+
onRightSidebarWidthChange?.(width);
|
|
7128
|
+
}, [onRightSidebarWidthChange]);
|
|
7082
7129
|
const handleMouseDown = react.useCallback((e) => {
|
|
7083
7130
|
e.preventDefault();
|
|
7084
7131
|
setIsResizing(true);
|
|
7085
7132
|
}, []);
|
|
7133
|
+
const handleRightMouseDown = react.useCallback((e) => {
|
|
7134
|
+
e.preventDefault();
|
|
7135
|
+
setIsResizingRight(true);
|
|
7136
|
+
}, []);
|
|
7086
7137
|
react.useEffect(() => {
|
|
7087
7138
|
if (!isResizing) return;
|
|
7088
7139
|
const handleMouseMove = (e) => {
|
|
7089
|
-
|
|
7090
|
-
setSidebarWidth(Math.min(maxWidth, Math.max(DEFAULT_SIDEBAR_WIDTH, e.clientX)));
|
|
7140
|
+
setSidebarWidth(clampSidebarWidth(e.clientX, window.innerWidth));
|
|
7091
7141
|
};
|
|
7092
7142
|
const handleMouseUp = () => {
|
|
7093
7143
|
setIsResizing(false);
|
|
@@ -7098,12 +7148,27 @@ function SimpleSidebar({ children, controls, headerRight, rootRef, fillParent =
|
|
|
7098
7148
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
7099
7149
|
document.removeEventListener("mouseup", handleMouseUp);
|
|
7100
7150
|
};
|
|
7101
|
-
}, [isResizing]);
|
|
7151
|
+
}, [isResizing, setSidebarWidth]);
|
|
7152
|
+
react.useEffect(() => {
|
|
7153
|
+
if (!isResizingRight) return;
|
|
7154
|
+
const handleMouseMove = (e) => {
|
|
7155
|
+
setRightSidebarWidth(clampSidebarWidth(window.innerWidth - e.clientX, window.innerWidth));
|
|
7156
|
+
};
|
|
7157
|
+
const handleMouseUp = () => {
|
|
7158
|
+
setIsResizingRight(false);
|
|
7159
|
+
};
|
|
7160
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
7161
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
7162
|
+
return () => {
|
|
7163
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
7164
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
7165
|
+
};
|
|
7166
|
+
}, [isResizingRight, setRightSidebarWidth]);
|
|
7102
7167
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7103
7168
|
ref: rootRef,
|
|
7104
7169
|
className: `sunpeak-inspector-root flex ${fillParent ? "h-full w-full" : "h-screen w-full"} overflow-hidden relative`,
|
|
7105
7170
|
children: [
|
|
7106
|
-
isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "fixed inset-0 z-50 cursor-col-resize" }),
|
|
7171
|
+
(isResizing || isResizingRight) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "fixed inset-0 z-50 cursor-col-resize" }),
|
|
7107
7172
|
isDrawerOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7108
7173
|
className: "md:hidden fixed inset-0 bg-black/50 z-40 pointer-events-auto",
|
|
7109
7174
|
onClick: (e) => {
|
|
@@ -7119,7 +7184,7 @@ function SimpleSidebar({ children, controls, headerRight, rootRef, fillParent =
|
|
|
7119
7184
|
${isDrawerOpen ? "max-md:translate-x-0" : "max-md:-translate-x-full"}
|
|
7120
7185
|
`,
|
|
7121
7186
|
style: {
|
|
7122
|
-
width:
|
|
7187
|
+
width: effectiveSidebarWidth,
|
|
7123
7188
|
borderRight: "1px solid var(--color-border-primary)"
|
|
7124
7189
|
},
|
|
7125
7190
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -7172,19 +7237,69 @@ function SimpleSidebar({ children, controls, headerRight, rootRef, fillParent =
|
|
|
7172
7237
|
"aria-label": "Open sidebar",
|
|
7173
7238
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRightIcon, {})
|
|
7174
7239
|
}), children]
|
|
7240
|
+
}),
|
|
7241
|
+
rightControls && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
7242
|
+
className: "relative hidden md:flex flex-col bg-sidebar",
|
|
7243
|
+
style: {
|
|
7244
|
+
width: effectiveRightSidebarWidth,
|
|
7245
|
+
borderLeft: "1px solid var(--color-border-primary)"
|
|
7246
|
+
},
|
|
7247
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7248
|
+
className: "flex-1 min-h-0 overflow-y-auto px-3 pb-3 pt-2",
|
|
7249
|
+
children: rightControls
|
|
7250
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7251
|
+
onMouseDown: handleRightMouseDown,
|
|
7252
|
+
className: "hidden md:block absolute top-0 left-0 w-1 h-full cursor-col-resize hover:bg-black/10 dark:hover:bg-white/10 active:bg-black/20 dark:active:bg-white/20 transition-colors"
|
|
7253
|
+
})]
|
|
7175
7254
|
})
|
|
7176
7255
|
]
|
|
7177
7256
|
});
|
|
7178
7257
|
}
|
|
7179
7258
|
var DOCS_BASE_URL$1 = "https://sunpeak.ai/docs";
|
|
7180
|
-
function HelpIcon({ tooltip, docsPath }) {
|
|
7259
|
+
function HelpIcon({ tooltip, docsPath, placement = "right" }) {
|
|
7260
|
+
const linkRef = react.useRef(null);
|
|
7261
|
+
const [isTooltipVisible, setIsTooltipVisible] = react.useState(false);
|
|
7262
|
+
const [tooltipPosition, setTooltipPosition] = react.useState({
|
|
7263
|
+
left: 0,
|
|
7264
|
+
top: 0
|
|
7265
|
+
});
|
|
7266
|
+
const tooltipOffset = 8;
|
|
7267
|
+
const tooltipTransform = placement === "left" ? "translate(-100%, -50%)" : "translateY(-50%)";
|
|
7268
|
+
const setTooltipFromPoint = react.useCallback((clientX, clientY) => {
|
|
7269
|
+
setTooltipPosition({
|
|
7270
|
+
left: placement === "left" ? clientX - tooltipOffset : clientX + tooltipOffset,
|
|
7271
|
+
top: clientY
|
|
7272
|
+
});
|
|
7273
|
+
}, [placement]);
|
|
7274
|
+
const setTooltipFromIcon = react.useCallback(() => {
|
|
7275
|
+
const rect = linkRef.current?.getBoundingClientRect();
|
|
7276
|
+
if (!rect) return;
|
|
7277
|
+
setTooltipPosition({
|
|
7278
|
+
left: placement === "left" ? rect.left - tooltipOffset : rect.right + tooltipOffset,
|
|
7279
|
+
top: rect.top + rect.height / 2
|
|
7280
|
+
});
|
|
7281
|
+
}, [placement]);
|
|
7181
7282
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
7283
|
+
ref: linkRef,
|
|
7182
7284
|
href: `${DOCS_BASE_URL$1}/${docsPath}`,
|
|
7183
7285
|
target: "_blank",
|
|
7184
7286
|
rel: "noopener noreferrer",
|
|
7185
7287
|
"aria-label": tooltip,
|
|
7186
7288
|
className: "group relative inline-flex items-center justify-center no-underline flex-shrink-0 transition-colors",
|
|
7187
7289
|
style: { color: "var(--color-text-tertiary, var(--color-text-secondary))" },
|
|
7290
|
+
onMouseEnter: (e) => {
|
|
7291
|
+
setIsTooltipVisible(true);
|
|
7292
|
+
setTooltipFromPoint(e.clientX, e.clientY);
|
|
7293
|
+
},
|
|
7294
|
+
onMouseMove: (e) => {
|
|
7295
|
+
setTooltipFromPoint(e.clientX, e.clientY);
|
|
7296
|
+
},
|
|
7297
|
+
onMouseLeave: () => setIsTooltipVisible(false),
|
|
7298
|
+
onFocus: () => {
|
|
7299
|
+
setIsTooltipVisible(true);
|
|
7300
|
+
setTooltipFromIcon();
|
|
7301
|
+
},
|
|
7302
|
+
onBlur: () => setIsTooltipVisible(false),
|
|
7188
7303
|
onClick: (e) => e.stopPropagation(),
|
|
7189
7304
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
7190
7305
|
width: "12",
|
|
@@ -7210,8 +7325,11 @@ function HelpIcon({ tooltip, docsPath }) {
|
|
|
7210
7325
|
})]
|
|
7211
7326
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7212
7327
|
"aria-hidden": "true",
|
|
7213
|
-
className:
|
|
7328
|
+
className: `pointer-events-none fixed z-[1000] whitespace-nowrap rounded px-2 py-1 text-[11px] font-normal leading-tight ${isTooltipVisible ? "block" : "hidden"}`,
|
|
7214
7329
|
style: {
|
|
7330
|
+
left: tooltipPosition.left,
|
|
7331
|
+
top: tooltipPosition.top,
|
|
7332
|
+
transform: tooltipTransform,
|
|
7215
7333
|
backgroundColor: "var(--color-text-primary)",
|
|
7216
7334
|
color: "var(--color-background-primary)"
|
|
7217
7335
|
},
|
|
@@ -7219,7 +7337,7 @@ function HelpIcon({ tooltip, docsPath }) {
|
|
|
7219
7337
|
})]
|
|
7220
7338
|
});
|
|
7221
7339
|
}
|
|
7222
|
-
function SidebarControl({ label, children, tooltip, docsPath, "data-testid": testId }) {
|
|
7340
|
+
function SidebarControl({ label, children, tooltip, tooltipPlacement, docsPath, "data-testid": testId }) {
|
|
7223
7341
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7224
7342
|
className: "space-y-1",
|
|
7225
7343
|
"data-testid": testId,
|
|
@@ -7228,15 +7346,17 @@ function SidebarControl({ label, children, tooltip, docsPath, "data-testid": tes
|
|
|
7228
7346
|
style: { color: "var(--color-text-secondary)" },
|
|
7229
7347
|
children: [label, tooltip && docsPath && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HelpIcon, {
|
|
7230
7348
|
tooltip,
|
|
7231
|
-
docsPath
|
|
7349
|
+
docsPath,
|
|
7350
|
+
placement: tooltipPlacement
|
|
7232
7351
|
})]
|
|
7233
7352
|
}), children]
|
|
7234
7353
|
});
|
|
7235
7354
|
}
|
|
7236
|
-
function SidebarCollapsibleControl({ label, children, defaultCollapsed = true, tooltip, docsPath, "data-testid": testId }) {
|
|
7355
|
+
function SidebarCollapsibleControl({ label, children, defaultCollapsed = true, className, contentClassName, style, tooltip, tooltipPlacement, docsPath, "data-testid": testId }) {
|
|
7237
7356
|
const [isCollapsed, setIsCollapsed] = react.useState(defaultCollapsed);
|
|
7238
7357
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7239
|
-
className: "space-y-1",
|
|
7358
|
+
className: className ? `space-y-1 ${className}` : "space-y-1",
|
|
7359
|
+
style: isCollapsed ? void 0 : style,
|
|
7240
7360
|
"data-testid": testId,
|
|
7241
7361
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7242
7362
|
onClick: () => setIsCollapsed(!isCollapsed),
|
|
@@ -7247,13 +7367,17 @@ function SidebarCollapsibleControl({ label, children, defaultCollapsed = true, t
|
|
|
7247
7367
|
className: "inline-flex items-center gap-1",
|
|
7248
7368
|
children: [label, tooltip && docsPath && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HelpIcon, {
|
|
7249
7369
|
tooltip,
|
|
7250
|
-
docsPath
|
|
7370
|
+
docsPath,
|
|
7371
|
+
placement: tooltipPlacement
|
|
7251
7372
|
})]
|
|
7252
7373
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7253
7374
|
className: "text-[8px]",
|
|
7254
7375
|
children: isCollapsed ? "▶" : "▼"
|
|
7255
7376
|
})]
|
|
7256
|
-
}), !isCollapsed &&
|
|
7377
|
+
}), !isCollapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7378
|
+
className: contentClassName,
|
|
7379
|
+
children
|
|
7380
|
+
})]
|
|
7257
7381
|
});
|
|
7258
7382
|
}
|
|
7259
7383
|
var formElementStyle = {
|
|
@@ -7328,7 +7452,7 @@ function SidebarInput({ value, onChange, applyOnBlur = false, autoComplete, plac
|
|
|
7328
7452
|
}
|
|
7329
7453
|
});
|
|
7330
7454
|
}
|
|
7331
|
-
function SidebarCheckbox({ checked, onChange, label, tooltip, docsPath }) {
|
|
7455
|
+
function SidebarCheckbox({ checked, onChange, label, tooltip, tooltipPlacement, docsPath }) {
|
|
7332
7456
|
const id = react.useId();
|
|
7333
7457
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7334
7458
|
className: "flex items-center gap-1.5",
|
|
@@ -7348,24 +7472,25 @@ function SidebarCheckbox({ checked, onChange, label, tooltip, docsPath }) {
|
|
|
7348
7472
|
}),
|
|
7349
7473
|
tooltip && docsPath && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HelpIcon, {
|
|
7350
7474
|
tooltip,
|
|
7351
|
-
docsPath
|
|
7475
|
+
docsPath,
|
|
7476
|
+
placement: tooltipPlacement
|
|
7352
7477
|
})
|
|
7353
7478
|
]
|
|
7354
7479
|
});
|
|
7355
7480
|
}
|
|
7356
|
-
function SidebarTextarea({ value, onChange, onFocus, onBlur, placeholder, maxRows = 8, error, "data-testid": testId }) {
|
|
7481
|
+
function SidebarTextarea({ value, onChange, onFocus, onBlur, placeholder, maxRows = 8, fill = false, error, "data-testid": testId }) {
|
|
7357
7482
|
const contentRows = value?.split("\n").length ?? 1;
|
|
7358
7483
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7359
|
-
className: "space-y-0.5",
|
|
7484
|
+
className: fill ? "flex h-full min-h-0 flex-col gap-0.5" : "space-y-0.5",
|
|
7360
7485
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
7361
7486
|
value,
|
|
7362
7487
|
onChange: (e) => onChange(e.target.value),
|
|
7363
7488
|
onFocus,
|
|
7364
7489
|
onBlur,
|
|
7365
7490
|
placeholder,
|
|
7366
|
-
rows: Math.min(contentRows, maxRows),
|
|
7491
|
+
rows: fill ? void 0 : Math.min(contentRows, maxRows),
|
|
7367
7492
|
"data-testid": testId,
|
|
7368
|
-
className:
|
|
7493
|
+
className: `w-full text-[10px] font-mono rounded-md px-2 py-1.5 outline-none ${fill ? "h-full min-h-0 flex-1 resize-none" : "resize-y"}`,
|
|
7369
7494
|
style: {
|
|
7370
7495
|
...formElementStyle,
|
|
7371
7496
|
cursor: "text",
|
|
@@ -7454,10 +7579,9 @@ function flattenAppToSimulations(app) {
|
|
|
7454
7579
|
}
|
|
7455
7580
|
for (const appTool of app.tools) {
|
|
7456
7581
|
const uri = getOutputTemplate(appTool.tool._meta);
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
const mcpResource = toMcpResource(resource);
|
|
7582
|
+
const resource = uri ? resourcesByUri.get(uri) : void 0;
|
|
7583
|
+
if (uri && !resource) console.warn(`[Inspector] Tool '${appTool.tool.name}' references unknown resource URI '${uri}'. The tool remains callable but has no UI to render.`);
|
|
7584
|
+
const mcpResource = resource ? toMcpResource(resource) : void 0;
|
|
7461
7585
|
const sims = appTool.simulations && appTool.simulations.length > 0 ? appTool.simulations : [{ name: appTool.tool.name }];
|
|
7462
7586
|
for (const sim of sims) {
|
|
7463
7587
|
const key = `${appTool.tool.name}__${sim.name}`;
|
|
@@ -7465,10 +7589,12 @@ function flattenAppToSimulations(app) {
|
|
|
7465
7589
|
result[key] = {
|
|
7466
7590
|
name: key,
|
|
7467
7591
|
displayName: sim.name,
|
|
7468
|
-
|
|
7592
|
+
...resource ? {
|
|
7593
|
+
resourceHtml: resource.html,
|
|
7594
|
+
resource: mcpResource
|
|
7595
|
+
} : {},
|
|
7469
7596
|
userMessage: sim.userMessage,
|
|
7470
7597
|
tool: appTool.tool,
|
|
7471
|
-
resource: mcpResource,
|
|
7472
7598
|
toolInput: sim.toolInput,
|
|
7473
7599
|
toolResult: sim.toolResult,
|
|
7474
7600
|
serverTools: sim.serverTools
|
|
@@ -7483,12 +7609,16 @@ var DOCS_BASE_URL = "https://sunpeak.ai/docs";
|
|
|
7483
7609
|
var DEFAULT_MODEL_PROVIDERS = [{
|
|
7484
7610
|
id: "openai",
|
|
7485
7611
|
label: "OpenAI",
|
|
7486
|
-
defaultModel: "gpt-
|
|
7612
|
+
defaultModel: "gpt-5.5"
|
|
7487
7613
|
}, {
|
|
7488
7614
|
id: "anthropic",
|
|
7489
7615
|
label: "Anthropic",
|
|
7490
|
-
defaultModel: "claude-
|
|
7616
|
+
defaultModel: "claude-sonnet-4-20250514"
|
|
7491
7617
|
}];
|
|
7618
|
+
function createModelConversationId() {
|
|
7619
|
+
const random = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2);
|
|
7620
|
+
return `model-chat-${Date.now()}-${random}`;
|
|
7621
|
+
}
|
|
7492
7622
|
function splitCssArgs(value) {
|
|
7493
7623
|
const args = [];
|
|
7494
7624
|
let depth = 0;
|
|
@@ -7544,7 +7674,6 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7544
7674
|
const toolMap = react.useMemo(() => {
|
|
7545
7675
|
const map = /* @__PURE__ */ new Map();
|
|
7546
7676
|
for (const [simName, sim] of Object.entries(simulations)) {
|
|
7547
|
-
if (!sim.resource) continue;
|
|
7548
7677
|
const toolName = sim.tool.name;
|
|
7549
7678
|
if (!map.has(toolName)) map.set(toolName, {
|
|
7550
7679
|
tool: sim.tool,
|
|
@@ -7553,6 +7682,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7553
7682
|
fixtureSimNames: []
|
|
7554
7683
|
});
|
|
7555
7684
|
const info = map.get(toolName);
|
|
7685
|
+
if (!info.resource && sim.resource) info.resource = sim.resource;
|
|
7556
7686
|
info.simNames.push(simName);
|
|
7557
7687
|
if (hasFixtureData(sim)) info.fixtureSimNames.push(simName);
|
|
7558
7688
|
}
|
|
@@ -7565,6 +7695,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7565
7695
|
const labelB = infoB.tool.title || b;
|
|
7566
7696
|
return labelA.localeCompare(labelB);
|
|
7567
7697
|
}), [toolMap]);
|
|
7698
|
+
const defaultToolName = react.useMemo(() => toolNames.find((name) => !!toolMap.get(name)?.resource) ?? toolNames[0] ?? "", [toolMap, toolNames]);
|
|
7568
7699
|
const initUrlParams = react.useMemo(() => {
|
|
7569
7700
|
if (typeof window === "undefined") return {
|
|
7570
7701
|
tool: null,
|
|
@@ -7580,17 +7711,18 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7580
7711
|
autoRun: params.get("autoRun") === "true"
|
|
7581
7712
|
};
|
|
7582
7713
|
}, []);
|
|
7714
|
+
const storedPrefs = react.useMemo(() => initUrlParams.autoRun ? {} : readStoredPrefs(), [initUrlParams.autoRun]);
|
|
7583
7715
|
const [selectedToolName, setSelectedToolName] = react.useState(() => {
|
|
7584
7716
|
if (initUrlParams.tool && toolMap.has(initUrlParams.tool)) return initUrlParams.tool;
|
|
7585
7717
|
if (initUrlParams.simulation) {
|
|
7586
7718
|
for (const [toolName, info] of toolMap) if (info.simNames.includes(initUrlParams.simulation)) return toolName;
|
|
7587
7719
|
}
|
|
7588
|
-
return
|
|
7720
|
+
return defaultToolName;
|
|
7589
7721
|
});
|
|
7590
7722
|
const prevToolNamesRef = react.useRef(toolNames);
|
|
7591
7723
|
if (prevToolNamesRef.current !== toolNames) {
|
|
7592
7724
|
prevToolNamesRef.current = toolNames;
|
|
7593
|
-
if (toolNames.length > 0 && !toolMap.has(selectedToolName)) setSelectedToolName(
|
|
7725
|
+
if (toolNames.length > 0 && !toolMap.has(selectedToolName)) setSelectedToolName(defaultToolName);
|
|
7594
7726
|
}
|
|
7595
7727
|
const selectedToolInfo = toolMap.get(selectedToolName);
|
|
7596
7728
|
const [activeSimulationName, setActiveSimulationName] = react.useState(() => {
|
|
@@ -7614,6 +7746,12 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7614
7746
|
defaultHost,
|
|
7615
7747
|
preserveToolDataOnSimulationChange: isLiveMcpRender
|
|
7616
7748
|
});
|
|
7749
|
+
const resetAppContextForSelectionChange = () => {
|
|
7750
|
+
state.setModelContext(null);
|
|
7751
|
+
state.setModelAppContext(null);
|
|
7752
|
+
state.setModelContextJson("null");
|
|
7753
|
+
state.setModelContextError("");
|
|
7754
|
+
};
|
|
7617
7755
|
const [serverUrl, setServerUrl] = react.useState(mcpServerUrl ?? "");
|
|
7618
7756
|
const [authType, setAuthType] = react.useState("none");
|
|
7619
7757
|
const [bearerToken, setBearerToken] = react.useState("");
|
|
@@ -7623,13 +7761,12 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7623
7761
|
const [oauthStatus, setOauthStatus] = react.useState("none");
|
|
7624
7762
|
const [oauthError, setOauthError] = react.useState();
|
|
7625
7763
|
const connection = useMcpConnection(isEmbedded ? void 0 : mcpServerUrl || void 0, inspectorApiBaseUrl);
|
|
7626
|
-
const [prodResources, setProdResources] = react.useState(state.urlProdResources ?? defaultProdResources);
|
|
7764
|
+
const [prodResources, setProdResources] = react.useState(state.urlProdResources ?? storedPrefs.prodResources ?? defaultProdResources);
|
|
7627
7765
|
const showSidebar = state.urlSidebar !== false;
|
|
7628
7766
|
const showDevOverlay = state.urlDevOverlay !== false;
|
|
7629
7767
|
const [isRunning, setIsRunning] = react.useState(false);
|
|
7630
7768
|
const [hasRun, setHasRun] = react.useState(false);
|
|
7631
7769
|
const [showCheck, setShowCheck] = react.useState(false);
|
|
7632
|
-
const prodResourcesId = react.useId();
|
|
7633
7770
|
const [serverPreviewGeneration, setServerPreviewGeneration] = react.useState(0);
|
|
7634
7771
|
const checkTimerRef = react.useRef(void 0);
|
|
7635
7772
|
const oauthCleanupRef = react.useRef(void 0);
|
|
@@ -7646,6 +7783,15 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7646
7783
|
if (requested && modelProviderOptions.some((provider) => provider.id === requested)) return requested;
|
|
7647
7784
|
return modelProviderOptions[0]?.id ?? "openai";
|
|
7648
7785
|
}, [modelChat?.defaultProvider, modelProviderOptions]);
|
|
7786
|
+
const initialModelProvider = react.useMemo(() => {
|
|
7787
|
+
const stored = storedPrefs.modelProvider;
|
|
7788
|
+
if (stored && modelProviderOptions.some((provider) => provider.id === stored)) return stored;
|
|
7789
|
+
return defaultModelProvider;
|
|
7790
|
+
}, [
|
|
7791
|
+
defaultModelProvider,
|
|
7792
|
+
modelProviderOptions,
|
|
7793
|
+
storedPrefs.modelProvider
|
|
7794
|
+
]);
|
|
7649
7795
|
const getDefaultModelId = react.useCallback((provider) => {
|
|
7650
7796
|
const option = modelProviderOptions.find((item) => item.id === provider);
|
|
7651
7797
|
const candidates = [
|
|
@@ -7657,8 +7803,20 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7657
7803
|
if (providerModels.length === 0) return candidates.find(Boolean) ?? "";
|
|
7658
7804
|
return candidates.find((model) => model && providerModels.includes(model)) ?? providerModels[0];
|
|
7659
7805
|
}, [modelChat?.defaultModel, modelProviderOptions]);
|
|
7660
|
-
const
|
|
7661
|
-
|
|
7806
|
+
const getInitialModelId = react.useCallback((provider) => {
|
|
7807
|
+
const stored = storedPrefs.modelId;
|
|
7808
|
+
if (storedPrefs.modelProvider && storedPrefs.modelProvider !== provider) return getDefaultModelId(provider);
|
|
7809
|
+
const providerModels = modelProviderOptions.find((item) => item.id === provider)?.models ?? [];
|
|
7810
|
+
if (stored && (providerModels.length === 0 || providerModels.includes(stored))) return stored;
|
|
7811
|
+
return getDefaultModelId(provider);
|
|
7812
|
+
}, [
|
|
7813
|
+
getDefaultModelId,
|
|
7814
|
+
modelProviderOptions,
|
|
7815
|
+
storedPrefs.modelId,
|
|
7816
|
+
storedPrefs.modelProvider
|
|
7817
|
+
]);
|
|
7818
|
+
const [modelProvider, setModelProvider] = react.useState(initialModelProvider);
|
|
7819
|
+
const [modelId, setModelId] = react.useState(() => getInitialModelId(initialModelProvider));
|
|
7662
7820
|
const [apiKeyDraft, setApiKeyDraft] = react.useState("");
|
|
7663
7821
|
const [keyStatus, setKeyStatus] = react.useState({ hasKey: false });
|
|
7664
7822
|
const [isKeyStatusLoading, setIsKeyStatusLoading] = react.useState(usesApiKeyUi);
|
|
@@ -7667,9 +7825,36 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7667
7825
|
const [chatInput, setChatInput] = react.useState("");
|
|
7668
7826
|
const [isChatting, setIsChatting] = react.useState(false);
|
|
7669
7827
|
const [chatStatus, setChatStatus] = react.useState("");
|
|
7828
|
+
const modelConversationIdRef = react.useRef(createModelConversationId());
|
|
7670
7829
|
const currentModelProvider = react.useMemo(() => modelProviderOptions.find((provider) => provider.id === modelProvider), [modelProvider, modelProviderOptions]);
|
|
7671
7830
|
const selectedProviderModelOptions = react.useMemo(() => currentModelProvider?.models ?? [], [currentModelProvider?.models]);
|
|
7672
|
-
const modelCallableTools = react.useMemo(() =>
|
|
7831
|
+
const modelCallableTools = react.useMemo(() => {
|
|
7832
|
+
const map = /* @__PURE__ */ new Map();
|
|
7833
|
+
for (const sim of Object.values(simulations)) {
|
|
7834
|
+
if (!isToolVisibleToModel(sim.tool) || map.has(sim.tool.name)) continue;
|
|
7835
|
+
map.set(sim.tool.name, sim.tool);
|
|
7836
|
+
}
|
|
7837
|
+
return Array.from(map.values());
|
|
7838
|
+
}, [simulations]);
|
|
7839
|
+
const isFirstInspectorPrefsRender = react.useRef(true);
|
|
7840
|
+
react.useEffect(() => {
|
|
7841
|
+
if (isFirstInspectorPrefsRender.current) {
|
|
7842
|
+
isFirstInspectorPrefsRender.current = false;
|
|
7843
|
+
return;
|
|
7844
|
+
}
|
|
7845
|
+
if (initUrlParams.autoRun) return;
|
|
7846
|
+
writeStoredPrefs({
|
|
7847
|
+
...readStoredPrefs(),
|
|
7848
|
+
prodResources,
|
|
7849
|
+
modelProvider,
|
|
7850
|
+
modelId
|
|
7851
|
+
});
|
|
7852
|
+
}, [
|
|
7853
|
+
initUrlParams.autoRun,
|
|
7854
|
+
modelId,
|
|
7855
|
+
modelProvider,
|
|
7856
|
+
prodResources
|
|
7857
|
+
]);
|
|
7673
7858
|
react.useEffect(() => {
|
|
7674
7859
|
setServerUrl(mcpServerUrl ?? "");
|
|
7675
7860
|
}, [mcpServerUrl]);
|
|
@@ -7779,6 +7964,13 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7779
7964
|
usesApiKeyUi,
|
|
7780
7965
|
usesLocalModelEndpoints
|
|
7781
7966
|
]);
|
|
7967
|
+
const handleResetModelConversation = react.useCallback(() => {
|
|
7968
|
+
modelConversationIdRef.current = createModelConversationId();
|
|
7969
|
+
setChatMessages([]);
|
|
7970
|
+
setChatInput("");
|
|
7971
|
+
setChatStatus("");
|
|
7972
|
+
setIsChatting(false);
|
|
7973
|
+
}, []);
|
|
7782
7974
|
react.useEffect(() => {
|
|
7783
7975
|
state.setSelectedSimulationName(effectiveSimulationName);
|
|
7784
7976
|
}, [effectiveSimulationName]);
|
|
@@ -8039,15 +8231,18 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8039
8231
|
state.setToolResultJson("");
|
|
8040
8232
|
state.setToolResultError("");
|
|
8041
8233
|
setHasRun(false);
|
|
8234
|
+
const requestConversationId = modelConversationIdRef.current;
|
|
8042
8235
|
try {
|
|
8043
8236
|
const messages = nextMessages.map((message) => ({
|
|
8044
8237
|
role: message.role,
|
|
8045
|
-
content: message.content
|
|
8046
|
-
}));
|
|
8238
|
+
content: message.content.trim()
|
|
8239
|
+
})).filter((message) => message.content.length > 0);
|
|
8047
8240
|
let data;
|
|
8048
8241
|
if (modelChatHandler) data = await modelChatHandler({
|
|
8242
|
+
conversationId: requestConversationId,
|
|
8049
8243
|
provider: modelProvider,
|
|
8050
8244
|
modelId,
|
|
8245
|
+
host: state.activeHost,
|
|
8051
8246
|
messages,
|
|
8052
8247
|
tools: modelCallableTools,
|
|
8053
8248
|
appContext: state.modelAppContext ?? void 0
|
|
@@ -8058,8 +8253,10 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8058
8253
|
method: "POST",
|
|
8059
8254
|
headers: { "Content-Type": "application/json" },
|
|
8060
8255
|
body: JSON.stringify({
|
|
8256
|
+
conversationId: requestConversationId,
|
|
8061
8257
|
provider: modelProvider,
|
|
8062
8258
|
modelId,
|
|
8259
|
+
host: state.activeHost,
|
|
8063
8260
|
messages,
|
|
8064
8261
|
appContext: state.modelAppContext ?? void 0
|
|
8065
8262
|
})
|
|
@@ -8068,6 +8265,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8068
8265
|
if (!res.ok || data.error) throw new Error(data.error ?? `Model request failed (${res.status})`);
|
|
8069
8266
|
}
|
|
8070
8267
|
if (data.error) throw new Error(data.error);
|
|
8268
|
+
if (requestConversationId !== modelConversationIdRef.current) return;
|
|
8071
8269
|
let rendersApp = false;
|
|
8072
8270
|
const toolCalls = data.toolCalls ?? [];
|
|
8073
8271
|
for (let index = toolCalls.length - 1; index >= 0; index--) {
|
|
@@ -8089,7 +8287,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8089
8287
|
const assistantMessage = {
|
|
8090
8288
|
id: `assistant-${Date.now()}`,
|
|
8091
8289
|
role: "assistant",
|
|
8092
|
-
content: data.text ?? (
|
|
8290
|
+
content: data.text ?? (rendersApp ? "I called the MCP tool and rendered the app below." : toolCalls.length > 0 ? "I called the MCP tool." : "The model returned an empty response."),
|
|
8093
8291
|
toolCalls: toolCalls.map((call) => ({
|
|
8094
8292
|
name: call.name,
|
|
8095
8293
|
arguments: call.arguments,
|
|
@@ -8105,6 +8303,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8105
8303
|
});
|
|
8106
8304
|
setChatStatus("");
|
|
8107
8305
|
} catch (err) {
|
|
8306
|
+
if (requestConversationId !== modelConversationIdRef.current) return;
|
|
8108
8307
|
const message = err instanceof Error ? err.message : String(err);
|
|
8109
8308
|
setChatMessages((messages) => [...messages, {
|
|
8110
8309
|
id: `assistant-error-${Date.now()}`,
|
|
@@ -8113,7 +8312,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8113
8312
|
}]);
|
|
8114
8313
|
setChatStatus(message);
|
|
8115
8314
|
} finally {
|
|
8116
|
-
setIsChatting(false);
|
|
8315
|
+
if (requestConversationId === modelConversationIdRef.current) setIsChatting(false);
|
|
8117
8316
|
}
|
|
8118
8317
|
}, [
|
|
8119
8318
|
canUseModelChat,
|
|
@@ -8309,10 +8508,19 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8309
8508
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8310
8509
|
className: "text-sm text-center max-w-xs",
|
|
8311
8510
|
style: { color: "var(--color-text-secondary)" },
|
|
8312
|
-
children: isEmbedded ? "No tools
|
|
8511
|
+
children: isEmbedded ? "No tools in this app" : isError ? "Could not connect to MCP server" : isConnected ? "No tools found on this server" : serverUrl ? "Connecting…" : "Enter an MCP server URL to get started"
|
|
8313
8512
|
})
|
|
8314
8513
|
});
|
|
8315
|
-
} else if (
|
|
8514
|
+
} else if (!selectedToolInfo?.resource) content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8515
|
+
className: "h-full w-full flex items-center justify-center",
|
|
8516
|
+
style: { background: iframeBg },
|
|
8517
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8518
|
+
className: "text-sm text-center max-w-xs",
|
|
8519
|
+
style: { color: "var(--color-text-secondary)" },
|
|
8520
|
+
children: "Tool does not render a UI"
|
|
8521
|
+
})
|
|
8522
|
+
});
|
|
8523
|
+
else if (showEmptyState) content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8316
8524
|
className: "h-full w-full flex items-center justify-center",
|
|
8317
8525
|
style: { background: iframeBg },
|
|
8318
8526
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -8436,31 +8644,9 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8436
8644
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M0 0L10 6L0 12V0Z" })
|
|
8437
8645
|
}), "Run"]
|
|
8438
8646
|
}) : void 0;
|
|
8439
|
-
const
|
|
8440
|
-
className: "flex
|
|
8441
|
-
|
|
8442
|
-
children: [
|
|
8443
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
8444
|
-
id: prodResourcesId,
|
|
8445
|
-
type: "checkbox",
|
|
8446
|
-
checked: prodResources,
|
|
8447
|
-
onChange: (event) => setProdResources(event.currentTarget.checked),
|
|
8448
|
-
className: "h-3.5 w-3.5 accent-[var(--color-text-primary)]"
|
|
8449
|
-
}),
|
|
8450
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8451
|
-
htmlFor: prodResourcesId,
|
|
8452
|
-
className: "cursor-pointer select-none",
|
|
8453
|
-
children: "Prod Resources"
|
|
8454
|
-
}),
|
|
8455
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HelpIcon, {
|
|
8456
|
-
tooltip: "Load resources from dist/ builds instead of HMR",
|
|
8457
|
-
docsPath: "app-framework/cli/dev#prod-tools-and-prod-resources-flags"
|
|
8458
|
-
})
|
|
8459
|
-
]
|
|
8460
|
-
}) : null;
|
|
8461
|
-
const headerAction = runButton || headerProdResourcesControl ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8462
|
-
className: "flex min-w-0 items-center gap-2",
|
|
8463
|
-
children: [runButton, headerProdResourcesControl]
|
|
8647
|
+
const headerAction = runButton ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8648
|
+
className: "flex min-w-0 items-center",
|
|
8649
|
+
children: runButton
|
|
8464
8650
|
}) : void 0;
|
|
8465
8651
|
const conversationContent = ShellConversation ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShellConversation, {
|
|
8466
8652
|
screenWidth: state.screenWidth,
|
|
@@ -8483,6 +8669,11 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8483
8669
|
children: content
|
|
8484
8670
|
}) : content;
|
|
8485
8671
|
const rootSizing = isEmbedded ? "h-full w-full" : "h-screen w-screen";
|
|
8672
|
+
const getJsonPanelFlexGrow = (value) => {
|
|
8673
|
+
const text = value || "";
|
|
8674
|
+
const lineCount = text.split("\n").length;
|
|
8675
|
+
return Math.max(1, Math.min(8, lineCount + Math.floor(text.length / 500)));
|
|
8676
|
+
};
|
|
8486
8677
|
if (!showSidebar) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeProvider, {
|
|
8487
8678
|
theme: state.theme,
|
|
8488
8679
|
applyTheme,
|
|
@@ -8498,6 +8689,10 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8498
8689
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SimpleSidebar, {
|
|
8499
8690
|
rootRef,
|
|
8500
8691
|
fillParent: isEmbedded,
|
|
8692
|
+
sidebarWidth: state.sidebarWidth,
|
|
8693
|
+
rightSidebarWidth: state.rightSidebarWidth,
|
|
8694
|
+
onSidebarWidthChange: state.setSidebarWidth,
|
|
8695
|
+
onRightSidebarWidthChange: state.setRightSidebarWidth,
|
|
8501
8696
|
controls: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8502
8697
|
className: "space-y-1",
|
|
8503
8698
|
children: [
|
|
@@ -8522,7 +8717,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8522
8717
|
})
|
|
8523
8718
|
}), !demoMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
8524
8719
|
label: "Authentication",
|
|
8525
|
-
defaultCollapsed:
|
|
8720
|
+
defaultCollapsed: false,
|
|
8526
8721
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8527
8722
|
className: "space-y-1",
|
|
8528
8723
|
children: [
|
|
@@ -8606,70 +8801,6 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8606
8801
|
]
|
|
8607
8802
|
})
|
|
8608
8803
|
}, `auth-${authType === "none" ? "none" : "active"}`)] }),
|
|
8609
|
-
canUseModelChat && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
8610
|
-
label: "Model Chat",
|
|
8611
|
-
defaultCollapsed: true,
|
|
8612
|
-
tooltip: "Talk to this MCP server through a model",
|
|
8613
|
-
docsPath: "testing/evals",
|
|
8614
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8615
|
-
className: "space-y-2",
|
|
8616
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8617
|
-
className: "grid grid-cols-2 gap-2",
|
|
8618
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarControl, {
|
|
8619
|
-
label: "Provider",
|
|
8620
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSelect, {
|
|
8621
|
-
value: modelProvider,
|
|
8622
|
-
onChange: handleModelProviderChange,
|
|
8623
|
-
options: modelProviderOptions.map((provider) => ({
|
|
8624
|
-
value: provider.id,
|
|
8625
|
-
label: provider.label ?? provider.id
|
|
8626
|
-
}))
|
|
8627
|
-
})
|
|
8628
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarControl, {
|
|
8629
|
-
label: "Model",
|
|
8630
|
-
children: selectedProviderModelOptions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSelect, {
|
|
8631
|
-
value: modelId,
|
|
8632
|
-
onChange: setModelId,
|
|
8633
|
-
options: selectedProviderModelOptions.map((model) => ({
|
|
8634
|
-
value: model,
|
|
8635
|
-
label: model
|
|
8636
|
-
}))
|
|
8637
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
|
|
8638
|
-
value: modelId,
|
|
8639
|
-
onChange: setModelId,
|
|
8640
|
-
applyOnBlur: true,
|
|
8641
|
-
placeholder: getDefaultModelId(modelProvider)
|
|
8642
|
-
})
|
|
8643
|
-
})]
|
|
8644
|
-
}), usesApiKeyUi && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(SidebarControl, {
|
|
8645
|
-
label: "API Key",
|
|
8646
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8647
|
-
className: "flex gap-1",
|
|
8648
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
|
|
8649
|
-
type: "password",
|
|
8650
|
-
autoComplete: "new-password",
|
|
8651
|
-
value: apiKeyDraft,
|
|
8652
|
-
onChange: setApiKeyDraft,
|
|
8653
|
-
placeholder: keyStatus.hasKey ? "Saved locally" : `Paste ${modelProvider} key`
|
|
8654
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8655
|
-
type: "button",
|
|
8656
|
-
onClick: handleSaveApiKey,
|
|
8657
|
-
disabled: isKeyStatusLoading || !apiKeyDraft && !keyStatus.hasKey,
|
|
8658
|
-
className: "h-7 rounded-md px-2 text-xs font-medium transition-opacity disabled:opacity-40",
|
|
8659
|
-
style: {
|
|
8660
|
-
backgroundColor: "var(--color-text-primary)",
|
|
8661
|
-
color: "var(--color-background-primary)"
|
|
8662
|
-
},
|
|
8663
|
-
children: apiKeyDraft ? "Save" : "Clear"
|
|
8664
|
-
})]
|
|
8665
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8666
|
-
className: "mt-1 text-[9px]",
|
|
8667
|
-
style: { color: "var(--color-text-secondary)" },
|
|
8668
|
-
children: keyMessage || (isKeyStatusLoading ? "Checking saved key..." : keyStatus.hasKey ? `Key saved ${keyStatus.storage ?? "locally"}` : "Paste a key or use one already saved on this machine")
|
|
8669
|
-
})]
|
|
8670
|
-
})]
|
|
8671
|
-
})
|
|
8672
|
-
}),
|
|
8673
8804
|
hasTools && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8674
8805
|
className: "grid grid-cols-2 gap-2",
|
|
8675
8806
|
"data-testid": "tool-simulation-row",
|
|
@@ -8682,6 +8813,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8682
8813
|
value: selectedToolName,
|
|
8683
8814
|
onChange: (value) => {
|
|
8684
8815
|
setIsLiveMcpRender(false);
|
|
8816
|
+
resetAppContextForSelectionChange();
|
|
8685
8817
|
setSelectedToolName(value);
|
|
8686
8818
|
},
|
|
8687
8819
|
options: toolNames.map((name) => {
|
|
@@ -8714,6 +8846,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8714
8846
|
onChange: (value) => {
|
|
8715
8847
|
if (value === "__live__") return;
|
|
8716
8848
|
setIsLiveMcpRender(false);
|
|
8849
|
+
resetAppContextForSelectionChange();
|
|
8717
8850
|
setActiveSimulationName(value === "__none__" ? null : value);
|
|
8718
8851
|
},
|
|
8719
8852
|
options: [
|
|
@@ -8775,6 +8908,116 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8775
8908
|
})
|
|
8776
8909
|
})]
|
|
8777
8910
|
}),
|
|
8911
|
+
!hideInspectorModes && !demoMode && !isEmbedded && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8912
|
+
className: "py-1",
|
|
8913
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCheckbox, {
|
|
8914
|
+
checked: prodResources,
|
|
8915
|
+
onChange: setProdResources,
|
|
8916
|
+
label: "Prod Resources",
|
|
8917
|
+
tooltip: "Load resources from dist/ builds instead of HMR",
|
|
8918
|
+
docsPath: "app-framework/cli/dev#prod-tools-and-prod-resources-flags"
|
|
8919
|
+
})
|
|
8920
|
+
}),
|
|
8921
|
+
canUseModelChat && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
8922
|
+
label: "Model Chat",
|
|
8923
|
+
defaultCollapsed: false,
|
|
8924
|
+
tooltip: "Talk to this MCP server through a model",
|
|
8925
|
+
docsPath: "testing/evals",
|
|
8926
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8927
|
+
className: "space-y-1",
|
|
8928
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8929
|
+
className: "grid grid-cols-[0.7fr_minmax(0,1fr)_1.75rem] items-end gap-2",
|
|
8930
|
+
children: [
|
|
8931
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarControl, {
|
|
8932
|
+
label: "Provider",
|
|
8933
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSelect, {
|
|
8934
|
+
value: modelProvider,
|
|
8935
|
+
onChange: handleModelProviderChange,
|
|
8936
|
+
options: modelProviderOptions.map((provider) => ({
|
|
8937
|
+
value: provider.id,
|
|
8938
|
+
label: provider.label ?? provider.id
|
|
8939
|
+
}))
|
|
8940
|
+
})
|
|
8941
|
+
}),
|
|
8942
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarControl, {
|
|
8943
|
+
label: "Model",
|
|
8944
|
+
children: selectedProviderModelOptions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSelect, {
|
|
8945
|
+
value: modelId,
|
|
8946
|
+
onChange: setModelId,
|
|
8947
|
+
options: selectedProviderModelOptions.map((model) => ({
|
|
8948
|
+
value: model,
|
|
8949
|
+
label: model
|
|
8950
|
+
}))
|
|
8951
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
|
|
8952
|
+
value: modelId,
|
|
8953
|
+
onChange: setModelId,
|
|
8954
|
+
applyOnBlur: true,
|
|
8955
|
+
placeholder: getDefaultModelId(modelProvider)
|
|
8956
|
+
})
|
|
8957
|
+
}),
|
|
8958
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8959
|
+
className: "group relative flex h-7 items-center self-end",
|
|
8960
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8961
|
+
type: "button",
|
|
8962
|
+
onClick: handleResetModelConversation,
|
|
8963
|
+
disabled: chatMessages.length === 0 && !isChatting && !chatStatus,
|
|
8964
|
+
"aria-label": "Reset model conversation",
|
|
8965
|
+
"aria-describedby": "reset-model-conversation-tooltip",
|
|
8966
|
+
title: "Reset conversation",
|
|
8967
|
+
className: "flex h-7 w-7 cursor-pointer items-center justify-center rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-40",
|
|
8968
|
+
style: {
|
|
8969
|
+
backgroundColor: "var(--color-background-primary)",
|
|
8970
|
+
color: "var(--color-text-primary)"
|
|
8971
|
+
},
|
|
8972
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
8973
|
+
width: "18",
|
|
8974
|
+
height: "18",
|
|
8975
|
+
viewBox: "0 0 24 24",
|
|
8976
|
+
fill: "currentColor",
|
|
8977
|
+
"aria-hidden": "true",
|
|
8978
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-8 3.58-8 8s3.58 8 8 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h8V3z" })
|
|
8979
|
+
})
|
|
8980
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8981
|
+
id: "reset-model-conversation-tooltip",
|
|
8982
|
+
role: "tooltip",
|
|
8983
|
+
className: "pointer-events-none absolute right-0 top-full z-[1000] mt-1 hidden whitespace-nowrap rounded px-2 py-1 text-[11px] font-normal leading-tight group-focus-within:block group-hover:block",
|
|
8984
|
+
style: {
|
|
8985
|
+
backgroundColor: "var(--color-text-primary)",
|
|
8986
|
+
color: "var(--color-background-primary)"
|
|
8987
|
+
},
|
|
8988
|
+
children: "Reset conversation"
|
|
8989
|
+
})]
|
|
8990
|
+
})
|
|
8991
|
+
]
|
|
8992
|
+
}), usesApiKeyUi && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(SidebarControl, {
|
|
8993
|
+
label: "API Key",
|
|
8994
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8995
|
+
className: "flex gap-1",
|
|
8996
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
|
|
8997
|
+
type: "password",
|
|
8998
|
+
autoComplete: "new-password",
|
|
8999
|
+
value: apiKeyDraft,
|
|
9000
|
+
onChange: setApiKeyDraft,
|
|
9001
|
+
placeholder: keyStatus.hasKey ? "Saved locally" : `Paste ${modelProvider} key`
|
|
9002
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9003
|
+
type: "button",
|
|
9004
|
+
onClick: handleSaveApiKey,
|
|
9005
|
+
disabled: isKeyStatusLoading || !apiKeyDraft && !keyStatus.hasKey,
|
|
9006
|
+
className: "h-7 rounded-md px-2 text-xs font-medium transition-opacity disabled:opacity-40",
|
|
9007
|
+
style: {
|
|
9008
|
+
backgroundColor: "var(--color-text-primary)",
|
|
9009
|
+
color: "var(--color-background-primary)"
|
|
9010
|
+
},
|
|
9011
|
+
children: apiKeyDraft ? "Save" : "Clear"
|
|
9012
|
+
})]
|
|
9013
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9014
|
+
className: "mt-1 text-[9px]",
|
|
9015
|
+
style: { color: "var(--color-text-secondary)" },
|
|
9016
|
+
children: keyMessage || (isKeyStatusLoading ? "Checking saved key..." : keyStatus.hasKey ? `Key saved ${keyStatus.storage ?? "locally"}` : "Paste a key or use one already saved on this machine")
|
|
9017
|
+
})]
|
|
9018
|
+
})]
|
|
9019
|
+
})
|
|
9020
|
+
}),
|
|
8778
9021
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
8779
9022
|
label: "Host Context",
|
|
8780
9023
|
defaultCollapsed: false,
|
|
@@ -9037,14 +9280,24 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9037
9280
|
})
|
|
9038
9281
|
]
|
|
9039
9282
|
})
|
|
9040
|
-
})
|
|
9283
|
+
})
|
|
9284
|
+
]
|
|
9285
|
+
}),
|
|
9286
|
+
rightControls: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9287
|
+
className: "flex h-full min-h-0 flex-col gap-3",
|
|
9288
|
+
children: [
|
|
9041
9289
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
9042
9290
|
label: "App Context",
|
|
9043
|
-
defaultCollapsed:
|
|
9291
|
+
defaultCollapsed: false,
|
|
9044
9292
|
tooltip: "App-provided context shared with the model",
|
|
9045
9293
|
docsPath: "app-framework/hooks/use-app-state",
|
|
9294
|
+
className: "flex min-h-0 flex-col",
|
|
9295
|
+
contentClassName: "min-h-0 flex-1",
|
|
9296
|
+
style: { flex: `${getJsonPanelFlexGrow(state.modelContextJson)} 1 0` },
|
|
9297
|
+
tooltipPlacement: "left",
|
|
9046
9298
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarTextarea, {
|
|
9047
9299
|
value: state.modelContextJson,
|
|
9300
|
+
"data-testid": "app-context-textarea",
|
|
9048
9301
|
onChange: (json) => state.validateJSON(json, state.setModelContextJson, state.setModelContextError),
|
|
9049
9302
|
onFocus: () => state.setEditingField("modelContext"),
|
|
9050
9303
|
onBlur: () => state.commitJSON(state.modelContextJson, state.setModelContextError, (parsed) => {
|
|
@@ -9055,7 +9308,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9055
9308
|
});
|
|
9056
9309
|
}),
|
|
9057
9310
|
error: state.modelContextError,
|
|
9058
|
-
|
|
9311
|
+
fill: true
|
|
9059
9312
|
})
|
|
9060
9313
|
}),
|
|
9061
9314
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
@@ -9063,6 +9316,10 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9063
9316
|
defaultCollapsed: false,
|
|
9064
9317
|
tooltip: "Arguments passed to the tool",
|
|
9065
9318
|
docsPath: "app-framework/hooks/use-tool-data",
|
|
9319
|
+
className: "flex min-h-0 flex-col",
|
|
9320
|
+
contentClassName: "min-h-0 flex-1",
|
|
9321
|
+
style: { flex: `${getJsonPanelFlexGrow(state.toolInputJson)} 1 0` },
|
|
9322
|
+
tooltipPlacement: "left",
|
|
9066
9323
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarTextarea, {
|
|
9067
9324
|
value: state.toolInputJson,
|
|
9068
9325
|
"data-testid": "tool-input-textarea",
|
|
@@ -9070,7 +9327,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9070
9327
|
onFocus: () => state.setEditingField("toolInput"),
|
|
9071
9328
|
onBlur: () => state.commitJSON(state.toolInputJson, state.setToolInputError, (parsed) => state.setToolInput(parsed ?? {})),
|
|
9072
9329
|
error: state.toolInputError,
|
|
9073
|
-
|
|
9330
|
+
fill: true
|
|
9074
9331
|
})
|
|
9075
9332
|
}),
|
|
9076
9333
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
|
|
@@ -9079,6 +9336,10 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9079
9336
|
tooltip: "Structured content returned by the tool",
|
|
9080
9337
|
docsPath: "app-framework/hooks/use-tool-data",
|
|
9081
9338
|
"data-testid": "tool-result-section",
|
|
9339
|
+
className: "flex min-h-0 flex-col",
|
|
9340
|
+
contentClassName: "min-h-0 flex-1",
|
|
9341
|
+
style: { flex: `${getJsonPanelFlexGrow(state.toolResultJson)} 1 0` },
|
|
9342
|
+
tooltipPlacement: "left",
|
|
9082
9343
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarTextarea, {
|
|
9083
9344
|
value: state.toolResultJson,
|
|
9084
9345
|
"data-testid": "tool-result-textarea",
|
|
@@ -9096,7 +9357,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9096
9357
|
}
|
|
9097
9358
|
}),
|
|
9098
9359
|
error: state.toolResultError,
|
|
9099
|
-
|
|
9360
|
+
fill: true
|
|
9100
9361
|
})
|
|
9101
9362
|
})
|
|
9102
9363
|
]
|
|
@@ -9258,4 +9519,4 @@ Object.defineProperty(exports, "useThemeContext", {
|
|
|
9258
9519
|
}
|
|
9259
9520
|
});
|
|
9260
9521
|
|
|
9261
|
-
//# sourceMappingURL=inspector-
|
|
9522
|
+
//# sourceMappingURL=inspector-DOmiG64-.cjs.map
|