sunpeak 0.20.36 → 0.20.47
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 +291 -64
- package/bin/commands/test-init.mjs +6 -0
- package/bin/lib/eval/eval-runner.mjs +53 -1
- package/bin/lib/eval/eval-types.d.mts +27 -0
- package/bin/lib/eval/model-registry.mjs +2 -2
- 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/hooks/tool-data-store.d.ts +26 -0
- package/dist/hooks/use-tool-data.d.ts +3 -9
- package/dist/host/chatgpt/index.cjs +1 -1
- package/dist/host/chatgpt/index.js +1 -1
- package/dist/index.cjs +35 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +35 -21
- package/dist/index.js.map +1 -1
- package/dist/inspector/index.cjs +1 -1
- package/dist/inspector/index.js +1 -1
- package/dist/inspector/inspector.d.ts +7 -0
- package/dist/inspector/use-inspector-state.d.ts +28 -0
- package/dist/{inspector-CiuT_2yA.js → inspector-BSha-CAW.js} +216 -75
- package/dist/inspector-BSha-CAW.js.map +1 -0
- package/dist/{inspector-BNWla95w.cjs → inspector-Chhc2GNO.cjs} +216 -75
- package/dist/inspector-Chhc2GNO.cjs.map +1 -0
- package/dist/lib/utils.d.ts +8 -7
- package/dist/mcp/index.cjs +5 -3
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +5 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server.d.ts +12 -1
- package/dist/style.css +22 -0
- package/dist/{use-app-Duar2Ipu.js → use-app-CtKy52kw.js} +62 -1
- package/dist/use-app-CtKy52kw.js.map +1 -0
- package/dist/{use-app-DUdnDLP5.cjs → use-app-xaiN0HAd.cjs} +62 -1
- package/dist/use-app-xaiN0HAd.cjs.map +1 -0
- package/package.json +8 -8
- package/template/dist/albums/albums.html +3 -3
- package/template/dist/albums/albums.json +1 -1
- package/template/dist/carousel/carousel.html +3 -3
- package/template/dist/carousel/carousel.json +1 -1
- package/template/dist/map/map.html +4 -4
- package/template/dist/map/map.json +1 -1
- package/template/dist/review/review.html +3 -3
- package/template/dist/review/review.json +1 -1
- package/template/node_modules/.bin/tsc +2 -2
- package/template/node_modules/.bin/tsserver +2 -2
- package/template/node_modules/.bin/vitest +2 -2
- package/template/node_modules/.vite/deps/_metadata.json +3 -3
- package/template/node_modules/.vite-mcp/deps/_metadata.json +20 -20
- package/template/node_modules/.vite-mcp/deps/vitest.js +7 -7
- package/template/node_modules/.vite-mcp/deps/vitest.js.map +1 -1
- package/template/package.json +1 -1
- 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/tsconfig.json +2 -0
- package/dist/inspector-BNWla95w.cjs.map +0 -1
- package/dist/inspector-CiuT_2yA.js.map +0 -1
- package/dist/use-app-DUdnDLP5.cjs.map +0 -1
- package/dist/use-app-Duar2Ipu.js.map +0 -1
|
@@ -3480,20 +3480,50 @@ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
|
|
|
3480
3480
|
function cn(...inputs) {
|
|
3481
3481
|
return twMerge(clsx(inputs));
|
|
3482
3482
|
}
|
|
3483
|
+
function currentPageIsLoopback() {
|
|
3484
|
+
if (typeof window === "undefined") return true;
|
|
3485
|
+
return isLocalNetworkHostname(window.location.hostname);
|
|
3486
|
+
}
|
|
3487
|
+
function normalizeHostname(hostname) {
|
|
3488
|
+
return hostname.toLowerCase().replace(/^\[(.*)\]$/, "$1");
|
|
3489
|
+
}
|
|
3490
|
+
function isLocalNetworkHostname(hostname) {
|
|
3491
|
+
const host = normalizeHostname(hostname);
|
|
3492
|
+
if (host === "localhost" || host === "0.0.0.0" || host === "::1") return true;
|
|
3493
|
+
if (host.startsWith("127.")) return true;
|
|
3494
|
+
const ipv4 = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
3495
|
+
if (ipv4) {
|
|
3496
|
+
const octets = ipv4.slice(1).map(Number);
|
|
3497
|
+
if (octets.some((octet) => octet < 0 || octet > 255)) return false;
|
|
3498
|
+
const [a, b] = octets;
|
|
3499
|
+
return a === 10 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 169 && b === 254;
|
|
3500
|
+
}
|
|
3501
|
+
return host.startsWith("fc") || host.startsWith("fd") || host.startsWith("fe80:");
|
|
3502
|
+
}
|
|
3483
3503
|
/**
|
|
3484
3504
|
* Returns true when `icon` is safe to use as the `src` of an `<img>` rendered
|
|
3485
|
-
* inside the inspector chrome. Accepts http
|
|
3486
|
-
*
|
|
3487
|
-
*
|
|
3488
|
-
*
|
|
3489
|
-
*
|
|
3490
|
-
*
|
|
3491
|
-
* text
|
|
3505
|
+
* inside the inspector chrome. Accepts https URLs, local http URLs while the
|
|
3506
|
+
* inspector itself is running locally, and `data:image/*` URIs for raster image
|
|
3507
|
+
* types only. SVG data URIs are rejected because they can include
|
|
3508
|
+
* `<script>`/event handlers that execute when the document parses the inline
|
|
3509
|
+
* document (the `<img>` tag itself does not run scripts in modern browsers,
|
|
3510
|
+
* but adjacent <object>/<embed>/<iframe> renders would). Anything else (emoji,
|
|
3511
|
+
* plain text, javascript:, file:, etc.) falls through to the text-rendering
|
|
3512
|
+
* path that already handles emoji icons.
|
|
3492
3513
|
*/
|
|
3493
3514
|
function isAllowedIconUrl(icon) {
|
|
3494
|
-
if (
|
|
3495
|
-
|
|
3496
|
-
|
|
3515
|
+
if (/^data:image\/(?:png|jpeg|gif|webp)(?:[;,]|$)/i.test(icon)) return true;
|
|
3516
|
+
let url;
|
|
3517
|
+
try {
|
|
3518
|
+
url = new URL(icon);
|
|
3519
|
+
} catch {
|
|
3520
|
+
return false;
|
|
3521
|
+
}
|
|
3522
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return false;
|
|
3523
|
+
const inspectorIsLocal = currentPageIsLoopback();
|
|
3524
|
+
if (isLocalNetworkHostname(url.hostname) && !inspectorIsLocal) return false;
|
|
3525
|
+
if (url.protocol === "http:" && !inspectorIsLocal) return false;
|
|
3526
|
+
return true;
|
|
3497
3527
|
}
|
|
3498
3528
|
//#endregion
|
|
3499
3529
|
//#region src/inspector/hosts.ts
|
|
@@ -5991,16 +6021,12 @@ var SUNPEAK_INLINE_HELPER_SCRIPT = `
|
|
|
5991
6021
|
//#region src/inspector/iframe-resource.tsx
|
|
5992
6022
|
/**
|
|
5993
6023
|
* Allowed origins for cross-origin script loading.
|
|
5994
|
-
* - Local development: localhost, 127.0.0.1, file://
|
|
5995
6024
|
* - Production: sunpeak-prod-app-storage.s3.us-east-2.amazonaws.com (serves user scripts)
|
|
6025
|
+
*
|
|
6026
|
+
* Loopback script URLs are handled separately in isAllowedUrl() so hosted
|
|
6027
|
+
* inspectors cannot be tricked into loading scripts from a visitor's machine.
|
|
5996
6028
|
*/
|
|
5997
|
-
var ALLOWED_SCRIPT_ORIGINS = [
|
|
5998
|
-
"https://sunpeak-prod-app-storage.s3.us-east-2.amazonaws.com",
|
|
5999
|
-
"http://localhost",
|
|
6000
|
-
"https://localhost",
|
|
6001
|
-
"http://127.0.0.1",
|
|
6002
|
-
"https://127.0.0.1"
|
|
6003
|
-
];
|
|
6029
|
+
var ALLOWED_SCRIPT_ORIGINS = ["https://sunpeak-prod-app-storage.s3.us-east-2.amazonaws.com"];
|
|
6004
6030
|
/**
|
|
6005
6031
|
* Escapes HTML special characters to prevent XSS via attribute injection.
|
|
6006
6032
|
*/
|
|
@@ -6538,6 +6564,9 @@ var VALID_SCREEN_WIDTHS = new Set([
|
|
|
6538
6564
|
"tablet",
|
|
6539
6565
|
"full"
|
|
6540
6566
|
]);
|
|
6567
|
+
function isSafeStoredString(value) {
|
|
6568
|
+
return typeof value === "string" && value.length <= 200 && !/[\u0000-\u001f\u007f]/.test(value);
|
|
6569
|
+
}
|
|
6541
6570
|
function sanitizeStoredPrefs(raw) {
|
|
6542
6571
|
if (!raw || typeof raw !== "object") return {};
|
|
6543
6572
|
const obj = raw;
|
|
@@ -6545,6 +6574,8 @@ function sanitizeStoredPrefs(raw) {
|
|
|
6545
6574
|
if (typeof obj.theme === "string" && VALID_THEMES.has(obj.theme)) prefs.theme = obj.theme;
|
|
6546
6575
|
if (typeof obj.locale === "string") prefs.locale = obj.locale;
|
|
6547
6576
|
if (typeof obj.displayMode === "string" && VALID_DISPLAY_MODES.has(obj.displayMode)) prefs.displayMode = obj.displayMode;
|
|
6577
|
+
if (typeof obj.containerHeight === "number" && Number.isFinite(obj.containerHeight)) prefs.containerHeight = obj.containerHeight;
|
|
6578
|
+
if (typeof obj.containerWidth === "number" && Number.isFinite(obj.containerWidth)) prefs.containerWidth = obj.containerWidth;
|
|
6548
6579
|
if (typeof obj.containerMaxHeight === "number" && Number.isFinite(obj.containerMaxHeight)) prefs.containerMaxHeight = obj.containerMaxHeight;
|
|
6549
6580
|
if (typeof obj.containerMaxWidth === "number" && Number.isFinite(obj.containerMaxWidth)) prefs.containerMaxWidth = obj.containerMaxWidth;
|
|
6550
6581
|
if (obj.safeAreaInsets && typeof obj.safeAreaInsets === "object") {
|
|
@@ -6563,6 +6594,10 @@ function sanitizeStoredPrefs(raw) {
|
|
|
6563
6594
|
if (typeof obj.screenWidth === "string" && VALID_SCREEN_WIDTHS.has(obj.screenWidth)) prefs.screenWidth = obj.screenWidth;
|
|
6564
6595
|
if (typeof obj.sidebarWidth === "number" && Number.isFinite(obj.sidebarWidth)) prefs.sidebarWidth = Math.max(DEFAULT_SIDEBAR_WIDTH$1, Math.round(obj.sidebarWidth));
|
|
6565
6596
|
if (typeof obj.rightSidebarWidth === "number" && Number.isFinite(obj.rightSidebarWidth)) prefs.rightSidebarWidth = Math.max(DEFAULT_SIDEBAR_WIDTH$1, Math.round(obj.rightSidebarWidth));
|
|
6597
|
+
if (typeof obj.timeZone === "string") prefs.timeZone = obj.timeZone;
|
|
6598
|
+
if (typeof obj.prodResources === "boolean") prefs.prodResources = obj.prodResources;
|
|
6599
|
+
if (isSafeStoredString(obj.modelProvider)) prefs.modelProvider = obj.modelProvider;
|
|
6600
|
+
if (isSafeStoredString(obj.modelId)) prefs.modelId = obj.modelId;
|
|
6566
6601
|
return prefs;
|
|
6567
6602
|
}
|
|
6568
6603
|
function readStoredPrefs() {
|
|
@@ -6575,6 +6610,12 @@ function readStoredPrefs() {
|
|
|
6575
6610
|
return {};
|
|
6576
6611
|
}
|
|
6577
6612
|
}
|
|
6613
|
+
function writeStoredPrefs(prefs) {
|
|
6614
|
+
if (typeof window === "undefined") return;
|
|
6615
|
+
try {
|
|
6616
|
+
localStorage.setItem(PREFS_KEY, JSON.stringify(prefs));
|
|
6617
|
+
} catch {}
|
|
6618
|
+
}
|
|
6578
6619
|
function deriveContainerDimensions({ displayMode, containerHeight, containerWidth, containerMaxHeight, containerMaxWidth, measuredContentWidth, viewportHeight = 800, viewportWidth = 1280 }) {
|
|
6579
6620
|
if (containerHeight != null || containerWidth != null || containerMaxHeight != null || containerMaxWidth != null) return {
|
|
6580
6621
|
...containerHeight != null ? { height: containerHeight } : {},
|
|
@@ -6623,8 +6664,8 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6623
6664
|
const [theme, setTheme] = useState(urlParams.theme ?? storedPrefs.theme ?? DEFAULT_THEME);
|
|
6624
6665
|
const [displayMode, _setDisplayMode] = useState(urlParams.displayMode ?? storedPrefs.displayMode ?? DEFAULT_DISPLAY_MODE);
|
|
6625
6666
|
const [locale, setLocale] = useState(urlParams.locale ?? storedPrefs.locale ?? "en-US");
|
|
6626
|
-
const [containerHeight, setContainerHeight] = useState(
|
|
6627
|
-
const [containerWidth, setContainerWidth] = useState(
|
|
6667
|
+
const [containerHeight, setContainerHeight] = useState(storedPrefs.containerHeight);
|
|
6668
|
+
const [containerWidth, setContainerWidth] = useState(storedPrefs.containerWidth);
|
|
6628
6669
|
const [containerMaxHeight, setContainerMaxHeight] = useState(urlParams.containerMaxHeight ?? storedPrefs.containerMaxHeight);
|
|
6629
6670
|
const [containerMaxWidth, setContainerMaxWidth] = useState(urlParams.containerMaxWidth ?? storedPrefs.containerMaxWidth);
|
|
6630
6671
|
const [platform, setPlatform] = useState(urlParams.platform ?? storedPrefs.platform ?? DEFAULT_PLATFORM);
|
|
@@ -6636,7 +6677,7 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6636
6677
|
left: 0,
|
|
6637
6678
|
right: 0
|
|
6638
6679
|
});
|
|
6639
|
-
const [timeZone, setTimeZone] = useState(() => Intl.DateTimeFormat().resolvedOptions().timeZone);
|
|
6680
|
+
const [timeZone, setTimeZone] = useState(() => storedPrefs.timeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone);
|
|
6640
6681
|
const isFirstRender = useRef(true);
|
|
6641
6682
|
useEffect(() => {
|
|
6642
6683
|
if (isFirstRender.current) {
|
|
@@ -6644,29 +6685,32 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6644
6685
|
return;
|
|
6645
6686
|
}
|
|
6646
6687
|
if (autoRun) return;
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6688
|
+
writeStoredPrefs({
|
|
6689
|
+
...readStoredPrefs(),
|
|
6690
|
+
theme,
|
|
6691
|
+
locale,
|
|
6692
|
+
displayMode,
|
|
6693
|
+
containerHeight,
|
|
6694
|
+
containerWidth,
|
|
6695
|
+
containerMaxHeight,
|
|
6696
|
+
containerMaxWidth,
|
|
6697
|
+
safeAreaInsets,
|
|
6698
|
+
activeHost,
|
|
6699
|
+
platform,
|
|
6700
|
+
hover,
|
|
6701
|
+
touch,
|
|
6702
|
+
screenWidth,
|
|
6703
|
+
sidebarWidth,
|
|
6704
|
+
rightSidebarWidth,
|
|
6705
|
+
timeZone
|
|
6706
|
+
});
|
|
6665
6707
|
}, [
|
|
6666
6708
|
autoRun,
|
|
6667
6709
|
theme,
|
|
6668
6710
|
locale,
|
|
6669
6711
|
displayMode,
|
|
6712
|
+
containerHeight,
|
|
6713
|
+
containerWidth,
|
|
6670
6714
|
containerMaxHeight,
|
|
6671
6715
|
containerMaxWidth,
|
|
6672
6716
|
safeAreaInsets,
|
|
@@ -6676,7 +6720,8 @@ function useInspectorState({ simulations, defaultHost = "chatgpt", preserveToolD
|
|
|
6676
6720
|
touch,
|
|
6677
6721
|
screenWidth,
|
|
6678
6722
|
sidebarWidth,
|
|
6679
|
-
rightSidebarWidth
|
|
6723
|
+
rightSidebarWidth,
|
|
6724
|
+
timeZone
|
|
6680
6725
|
]);
|
|
6681
6726
|
const [measuredContentWidth, setMeasuredContentWidth] = useState(void 0);
|
|
6682
6727
|
const handleContentWidthChange = useCallback((width) => {
|
|
@@ -7589,12 +7634,16 @@ var DOCS_BASE_URL = "https://sunpeak.ai/docs";
|
|
|
7589
7634
|
var DEFAULT_MODEL_PROVIDERS = [{
|
|
7590
7635
|
id: "openai",
|
|
7591
7636
|
label: "OpenAI",
|
|
7592
|
-
defaultModel: "gpt-
|
|
7637
|
+
defaultModel: "gpt-5.5"
|
|
7593
7638
|
}, {
|
|
7594
7639
|
id: "anthropic",
|
|
7595
7640
|
label: "Anthropic",
|
|
7596
|
-
defaultModel: "claude-
|
|
7641
|
+
defaultModel: "claude-sonnet-4-20250514"
|
|
7597
7642
|
}];
|
|
7643
|
+
function createModelConversationId() {
|
|
7644
|
+
const random = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2);
|
|
7645
|
+
return `model-chat-${Date.now()}-${random}`;
|
|
7646
|
+
}
|
|
7598
7647
|
function splitCssArgs(value) {
|
|
7599
7648
|
const args = [];
|
|
7600
7649
|
let depth = 0;
|
|
@@ -7687,6 +7736,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7687
7736
|
autoRun: params.get("autoRun") === "true"
|
|
7688
7737
|
};
|
|
7689
7738
|
}, []);
|
|
7739
|
+
const storedPrefs = React.useMemo(() => initUrlParams.autoRun ? {} : readStoredPrefs(), [initUrlParams.autoRun]);
|
|
7690
7740
|
const [selectedToolName, setSelectedToolName] = React.useState(() => {
|
|
7691
7741
|
if (initUrlParams.tool && toolMap.has(initUrlParams.tool)) return initUrlParams.tool;
|
|
7692
7742
|
if (initUrlParams.simulation) {
|
|
@@ -7736,7 +7786,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7736
7786
|
const [oauthStatus, setOauthStatus] = React.useState("none");
|
|
7737
7787
|
const [oauthError, setOauthError] = React.useState();
|
|
7738
7788
|
const connection = useMcpConnection(isEmbedded ? void 0 : mcpServerUrl || void 0, inspectorApiBaseUrl);
|
|
7739
|
-
const [prodResources, setProdResources] = React.useState(state.urlProdResources ?? defaultProdResources);
|
|
7789
|
+
const [prodResources, setProdResources] = React.useState(state.urlProdResources ?? storedPrefs.prodResources ?? defaultProdResources);
|
|
7740
7790
|
const showSidebar = state.urlSidebar !== false;
|
|
7741
7791
|
const showDevOverlay = state.urlDevOverlay !== false;
|
|
7742
7792
|
const [isRunning, setIsRunning] = React.useState(false);
|
|
@@ -7758,6 +7808,15 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7758
7808
|
if (requested && modelProviderOptions.some((provider) => provider.id === requested)) return requested;
|
|
7759
7809
|
return modelProviderOptions[0]?.id ?? "openai";
|
|
7760
7810
|
}, [modelChat?.defaultProvider, modelProviderOptions]);
|
|
7811
|
+
const initialModelProvider = React.useMemo(() => {
|
|
7812
|
+
const stored = storedPrefs.modelProvider;
|
|
7813
|
+
if (stored && modelProviderOptions.some((provider) => provider.id === stored)) return stored;
|
|
7814
|
+
return defaultModelProvider;
|
|
7815
|
+
}, [
|
|
7816
|
+
defaultModelProvider,
|
|
7817
|
+
modelProviderOptions,
|
|
7818
|
+
storedPrefs.modelProvider
|
|
7819
|
+
]);
|
|
7761
7820
|
const getDefaultModelId = React.useCallback((provider) => {
|
|
7762
7821
|
const option = modelProviderOptions.find((item) => item.id === provider);
|
|
7763
7822
|
const candidates = [
|
|
@@ -7769,8 +7828,20 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7769
7828
|
if (providerModels.length === 0) return candidates.find(Boolean) ?? "";
|
|
7770
7829
|
return candidates.find((model) => model && providerModels.includes(model)) ?? providerModels[0];
|
|
7771
7830
|
}, [modelChat?.defaultModel, modelProviderOptions]);
|
|
7772
|
-
const
|
|
7773
|
-
|
|
7831
|
+
const getInitialModelId = React.useCallback((provider) => {
|
|
7832
|
+
const stored = storedPrefs.modelId;
|
|
7833
|
+
if (storedPrefs.modelProvider && storedPrefs.modelProvider !== provider) return getDefaultModelId(provider);
|
|
7834
|
+
const providerModels = modelProviderOptions.find((item) => item.id === provider)?.models ?? [];
|
|
7835
|
+
if (stored && (providerModels.length === 0 || providerModels.includes(stored))) return stored;
|
|
7836
|
+
return getDefaultModelId(provider);
|
|
7837
|
+
}, [
|
|
7838
|
+
getDefaultModelId,
|
|
7839
|
+
modelProviderOptions,
|
|
7840
|
+
storedPrefs.modelId,
|
|
7841
|
+
storedPrefs.modelProvider
|
|
7842
|
+
]);
|
|
7843
|
+
const [modelProvider, setModelProvider] = React.useState(initialModelProvider);
|
|
7844
|
+
const [modelId, setModelId] = React.useState(() => getInitialModelId(initialModelProvider));
|
|
7774
7845
|
const [apiKeyDraft, setApiKeyDraft] = React.useState("");
|
|
7775
7846
|
const [keyStatus, setKeyStatus] = React.useState({ hasKey: false });
|
|
7776
7847
|
const [isKeyStatusLoading, setIsKeyStatusLoading] = React.useState(usesApiKeyUi);
|
|
@@ -7779,6 +7850,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7779
7850
|
const [chatInput, setChatInput] = React.useState("");
|
|
7780
7851
|
const [isChatting, setIsChatting] = React.useState(false);
|
|
7781
7852
|
const [chatStatus, setChatStatus] = React.useState("");
|
|
7853
|
+
const modelConversationIdRef = React.useRef(createModelConversationId());
|
|
7782
7854
|
const currentModelProvider = React.useMemo(() => modelProviderOptions.find((provider) => provider.id === modelProvider), [modelProvider, modelProviderOptions]);
|
|
7783
7855
|
const selectedProviderModelOptions = React.useMemo(() => currentModelProvider?.models ?? [], [currentModelProvider?.models]);
|
|
7784
7856
|
const modelCallableTools = React.useMemo(() => {
|
|
@@ -7789,6 +7861,25 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7789
7861
|
}
|
|
7790
7862
|
return Array.from(map.values());
|
|
7791
7863
|
}, [simulations]);
|
|
7864
|
+
const isFirstInspectorPrefsRender = React.useRef(true);
|
|
7865
|
+
React.useEffect(() => {
|
|
7866
|
+
if (isFirstInspectorPrefsRender.current) {
|
|
7867
|
+
isFirstInspectorPrefsRender.current = false;
|
|
7868
|
+
return;
|
|
7869
|
+
}
|
|
7870
|
+
if (initUrlParams.autoRun) return;
|
|
7871
|
+
writeStoredPrefs({
|
|
7872
|
+
...readStoredPrefs(),
|
|
7873
|
+
prodResources,
|
|
7874
|
+
modelProvider,
|
|
7875
|
+
modelId
|
|
7876
|
+
});
|
|
7877
|
+
}, [
|
|
7878
|
+
initUrlParams.autoRun,
|
|
7879
|
+
modelId,
|
|
7880
|
+
modelProvider,
|
|
7881
|
+
prodResources
|
|
7882
|
+
]);
|
|
7792
7883
|
React.useEffect(() => {
|
|
7793
7884
|
setServerUrl(mcpServerUrl ?? "");
|
|
7794
7885
|
}, [mcpServerUrl]);
|
|
@@ -7898,6 +7989,13 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
7898
7989
|
usesApiKeyUi,
|
|
7899
7990
|
usesLocalModelEndpoints
|
|
7900
7991
|
]);
|
|
7992
|
+
const handleResetModelConversation = React.useCallback(() => {
|
|
7993
|
+
modelConversationIdRef.current = createModelConversationId();
|
|
7994
|
+
setChatMessages([]);
|
|
7995
|
+
setChatInput("");
|
|
7996
|
+
setChatStatus("");
|
|
7997
|
+
setIsChatting(false);
|
|
7998
|
+
}, []);
|
|
7901
7999
|
React.useEffect(() => {
|
|
7902
8000
|
state.setSelectedSimulationName(effectiveSimulationName);
|
|
7903
8001
|
}, [effectiveSimulationName]);
|
|
@@ -8158,15 +8256,18 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8158
8256
|
state.setToolResultJson("");
|
|
8159
8257
|
state.setToolResultError("");
|
|
8160
8258
|
setHasRun(false);
|
|
8259
|
+
const requestConversationId = modelConversationIdRef.current;
|
|
8161
8260
|
try {
|
|
8162
8261
|
const messages = nextMessages.map((message) => ({
|
|
8163
8262
|
role: message.role,
|
|
8164
|
-
content: message.content
|
|
8165
|
-
}));
|
|
8263
|
+
content: message.content.trim()
|
|
8264
|
+
})).filter((message) => message.content.length > 0);
|
|
8166
8265
|
let data;
|
|
8167
8266
|
if (modelChatHandler) data = await modelChatHandler({
|
|
8267
|
+
conversationId: requestConversationId,
|
|
8168
8268
|
provider: modelProvider,
|
|
8169
8269
|
modelId,
|
|
8270
|
+
host: state.activeHost,
|
|
8170
8271
|
messages,
|
|
8171
8272
|
tools: modelCallableTools,
|
|
8172
8273
|
appContext: state.modelAppContext ?? void 0
|
|
@@ -8177,8 +8278,10 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8177
8278
|
method: "POST",
|
|
8178
8279
|
headers: { "Content-Type": "application/json" },
|
|
8179
8280
|
body: JSON.stringify({
|
|
8281
|
+
conversationId: requestConversationId,
|
|
8180
8282
|
provider: modelProvider,
|
|
8181
8283
|
modelId,
|
|
8284
|
+
host: state.activeHost,
|
|
8182
8285
|
messages,
|
|
8183
8286
|
appContext: state.modelAppContext ?? void 0
|
|
8184
8287
|
})
|
|
@@ -8187,6 +8290,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8187
8290
|
if (!res.ok || data.error) throw new Error(data.error ?? `Model request failed (${res.status})`);
|
|
8188
8291
|
}
|
|
8189
8292
|
if (data.error) throw new Error(data.error);
|
|
8293
|
+
if (requestConversationId !== modelConversationIdRef.current) return;
|
|
8190
8294
|
let rendersApp = false;
|
|
8191
8295
|
const toolCalls = data.toolCalls ?? [];
|
|
8192
8296
|
for (let index = toolCalls.length - 1; index >= 0; index--) {
|
|
@@ -8224,6 +8328,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8224
8328
|
});
|
|
8225
8329
|
setChatStatus("");
|
|
8226
8330
|
} catch (err) {
|
|
8331
|
+
if (requestConversationId !== modelConversationIdRef.current) return;
|
|
8227
8332
|
const message = err instanceof Error ? err.message : String(err);
|
|
8228
8333
|
setChatMessages((messages) => [...messages, {
|
|
8229
8334
|
id: `assistant-error-${Date.now()}`,
|
|
@@ -8232,7 +8337,7 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8232
8337
|
}]);
|
|
8233
8338
|
setChatStatus(message);
|
|
8234
8339
|
} finally {
|
|
8235
|
-
setIsChatting(false);
|
|
8340
|
+
if (requestConversationId === modelConversationIdRef.current) setIsChatting(false);
|
|
8236
8341
|
}
|
|
8237
8342
|
}, [
|
|
8238
8343
|
canUseModelChat,
|
|
@@ -8846,33 +8951,69 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
8846
8951
|
children: /* @__PURE__ */ jsxs("div", {
|
|
8847
8952
|
className: "space-y-1",
|
|
8848
8953
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
8849
|
-
className: "grid grid-cols-
|
|
8850
|
-
children: [
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8954
|
+
className: "grid grid-cols-[0.7fr_minmax(0,1fr)_1.75rem] items-end gap-2",
|
|
8955
|
+
children: [
|
|
8956
|
+
/* @__PURE__ */ jsx(SidebarControl, {
|
|
8957
|
+
label: "Provider",
|
|
8958
|
+
children: /* @__PURE__ */ jsx(SidebarSelect, {
|
|
8959
|
+
value: modelProvider,
|
|
8960
|
+
onChange: handleModelProviderChange,
|
|
8961
|
+
options: modelProviderOptions.map((provider) => ({
|
|
8962
|
+
value: provider.id,
|
|
8963
|
+
label: provider.label ?? provider.id
|
|
8964
|
+
}))
|
|
8965
|
+
})
|
|
8966
|
+
}),
|
|
8967
|
+
/* @__PURE__ */ jsx(SidebarControl, {
|
|
8968
|
+
label: "Model",
|
|
8969
|
+
children: selectedProviderModelOptions.length > 0 ? /* @__PURE__ */ jsx(SidebarSelect, {
|
|
8970
|
+
value: modelId,
|
|
8971
|
+
onChange: setModelId,
|
|
8972
|
+
options: selectedProviderModelOptions.map((model) => ({
|
|
8973
|
+
value: model,
|
|
8974
|
+
label: model
|
|
8975
|
+
}))
|
|
8976
|
+
}) : /* @__PURE__ */ jsx(SidebarInput, {
|
|
8977
|
+
value: modelId,
|
|
8978
|
+
onChange: setModelId,
|
|
8979
|
+
applyOnBlur: true,
|
|
8980
|
+
placeholder: getDefaultModelId(modelProvider)
|
|
8981
|
+
})
|
|
8982
|
+
}),
|
|
8983
|
+
/* @__PURE__ */ jsxs("div", {
|
|
8984
|
+
className: "group relative flex h-7 items-center self-end",
|
|
8985
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
8986
|
+
type: "button",
|
|
8987
|
+
onClick: handleResetModelConversation,
|
|
8988
|
+
disabled: chatMessages.length === 0 && !isChatting && !chatStatus,
|
|
8989
|
+
"aria-label": "Reset model conversation",
|
|
8990
|
+
"aria-describedby": "reset-model-conversation-tooltip",
|
|
8991
|
+
title: "Reset conversation",
|
|
8992
|
+
className: "flex h-7 w-7 cursor-pointer items-center justify-center rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-40",
|
|
8993
|
+
style: {
|
|
8994
|
+
backgroundColor: "var(--color-background-primary)",
|
|
8995
|
+
color: "var(--color-text-primary)"
|
|
8996
|
+
},
|
|
8997
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
8998
|
+
width: "18",
|
|
8999
|
+
height: "18",
|
|
9000
|
+
viewBox: "0 0 24 24",
|
|
9001
|
+
fill: "currentColor",
|
|
9002
|
+
"aria-hidden": "true",
|
|
9003
|
+
children: /* @__PURE__ */ 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" })
|
|
9004
|
+
})
|
|
9005
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
9006
|
+
id: "reset-model-conversation-tooltip",
|
|
9007
|
+
role: "tooltip",
|
|
9008
|
+
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",
|
|
9009
|
+
style: {
|
|
9010
|
+
backgroundColor: "var(--color-text-primary)",
|
|
9011
|
+
color: "var(--color-background-primary)"
|
|
9012
|
+
},
|
|
9013
|
+
children: "Reset conversation"
|
|
9014
|
+
})]
|
|
8874
9015
|
})
|
|
8875
|
-
|
|
9016
|
+
]
|
|
8876
9017
|
}), usesApiKeyUi && /* @__PURE__ */ jsxs(SidebarControl, {
|
|
8877
9018
|
label: "API Key",
|
|
8878
9019
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -9260,4 +9401,4 @@ function Inspector({ children, app, simulations: initialSimulationsProp = EMPTY_
|
|
|
9260
9401
|
//#endregion
|
|
9261
9402
|
export { cn as C, registerHostShell as S, extractResourceCSP as _, SidebarCollapsibleControl as a, getHostShell as b, SidebarSelect as c, SimpleSidebar as d, ThemeProvider as f, IframeResource as g, useInspectorState as h, SidebarCheckbox as i, SidebarTextarea as l, useMcpConnection as m, flattenAppToSimulations as n, SidebarControl as o, useThemeContext as p, resolveServerToolResult as r, SidebarInput as s, Inspector as t, SidebarToggle as u, McpAppHost as v, DEFAULT_STYLE_VARIABLES as w, getRegisteredHosts as x, SCREEN_WIDTHS as y };
|
|
9262
9403
|
|
|
9263
|
-
//# sourceMappingURL=inspector-
|
|
9404
|
+
//# sourceMappingURL=inspector-BSha-CAW.js.map
|