@mcp-use/inspector 2.2.0-canary.2 → 2.2.0-canary.4

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.
Files changed (38) hide show
  1. package/dist/cdn/inspector.css +1 -1
  2. package/dist/cdn/inspector.js +32865 -32186
  3. package/dist/client/components/ChatTab.d.ts.map +1 -1
  4. package/dist/client/components/IframeConsole.d.ts +1 -1
  5. package/dist/client/components/IframeConsole.d.ts.map +1 -1
  6. package/dist/client/components/LoginModal.d.ts +11 -0
  7. package/dist/client/components/LoginModal.d.ts.map +1 -0
  8. package/dist/client/components/chat/ChatHeader.d.ts +10 -1
  9. package/dist/client/components/chat/ChatHeader.d.ts.map +1 -1
  10. package/dist/client/components/chat/ChatLandingForm.d.ts +8 -1
  11. package/dist/client/components/chat/ChatLandingForm.d.ts.map +1 -1
  12. package/dist/client/components/chat/ConfigurationDialog.d.ts +11 -1
  13. package/dist/client/components/chat/ConfigurationDialog.d.ts.map +1 -1
  14. package/dist/client/components/chat/useChatMessages.d.ts +4 -0
  15. package/dist/client/components/chat/useChatMessages.d.ts.map +1 -1
  16. package/dist/client/components/prompts/PromptResultDisplay.d.ts +1 -1
  17. package/dist/client/components/prompts/PromptResultDisplay.d.ts.map +1 -1
  18. package/dist/client/components/prompts/SavedPromptsList.d.ts +1 -1
  19. package/dist/client/components/prompts/SavedPromptsList.d.ts.map +1 -1
  20. package/dist/client/context/InspectorContext.d.ts +47 -1
  21. package/dist/client/context/InspectorContext.d.ts.map +1 -1
  22. package/dist/client/index.js +493 -102
  23. package/dist/server/server.d.ts.map +1 -1
  24. package/dist/server/server.js +9 -0
  25. package/dist/web/assets/{browser-p_miO3oL.js → browser-Du2AEj9X.js} +3 -3
  26. package/dist/web/assets/{chunk-GEOH7R4G-BpYNWk0M.js → chunk-2ATSIYOF-p66_KyAj.js} +1 -1
  27. package/dist/web/assets/{chunk-VDUR5PXK-ZU1Bss9y.js → chunk-2KALGUHZ-Dhp_lEVe.js} +1 -1
  28. package/dist/web/assets/{chunk-LG5NSHEL-hL8J2Ky1.js → chunk-LG5NSHEL-CEW8sESk.js} +1 -1
  29. package/dist/web/assets/{client-KmRT1sYj.js → client-DF9JX_Yn.js} +1 -1
  30. package/dist/web/assets/{client-J4HPCNHM-BQeZwtAZ.js → client-QBNSMKSM-Dm43Zysm.js} +3 -3
  31. package/dist/web/assets/index-B3SIc62D.css +2 -0
  32. package/dist/web/assets/{index-BRzOvEWM.js → index-Dk8r25sC.js} +89 -89
  33. package/dist/web/assets/react-IJvOo_WW.js +1 -0
  34. package/dist/web/assets/{stdio-CWIMXSHX-DI1TMMAc.js → stdio-5Y3QCAX6-N32gogWZ.js} +1 -1
  35. package/dist/web/index.html +6 -6
  36. package/package.json +4 -3
  37. package/dist/web/assets/index-DAF0St0M.css +0 -2
  38. package/dist/web/assets/react-CV-Ixx_3.js +0 -1
@@ -5177,7 +5177,7 @@ var init_module = __esm({
5177
5177
  }
5178
5178
  });
5179
5179
 
5180
- // ../mcp-use/dist/chunk-KPIFWECU.js
5180
+ // ../mcp-use/dist/chunk-CT5P3B7U.js
5181
5181
  import { RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps";
5182
5182
  import {
5183
5183
  CreateMessageRequestSchema,
@@ -5345,12 +5345,12 @@ function setTelemetrySource(source) {
5345
5345
  Tel.getInstance().setSource(source);
5346
5346
  }
5347
5347
  var VERSION, _a3, BaseTelemetryEvent, _a4, MCPAgentExecutionEvent, _a5, ServerRunEvent, _a6, ServerInitializeEvent, _a7, ServerToolCallEvent, _a8, ServerResourceCallEvent, _a9, ServerPromptCallEvent, _a10, ServerContextEvent, _a11, MCPClientInitEvent, _a12, ConnectorInitEvent, _a13, ClientAddServerEvent, _a14, ClientRemoveServerEvent, USER_ID_STORAGE_KEY, cachedEnvironment, _a15, Telemetry2, Tel, _a16, BaseConnector, _a17, ConnectionManager;
5348
- var init_chunk_KPIFWECU = __esm({
5349
- "../mcp-use/dist/chunk-KPIFWECU.js"() {
5348
+ var init_chunk_CT5P3B7U = __esm({
5349
+ "../mcp-use/dist/chunk-CT5P3B7U.js"() {
5350
5350
  "use strict";
5351
5351
  init_chunk_QWQYAQCK();
5352
5352
  init_chunk_3GQAWCBQ();
5353
- VERSION = "1.24.2-canary.2";
5353
+ VERSION = "1.24.2-canary.4";
5354
5354
  __name(getPackageVersion2, "getPackageVersion");
5355
5355
  BaseTelemetryEvent = (_a3 = class {
5356
5356
  }, __name(_a3, "BaseTelemetryEvent"), _a3);
@@ -6620,7 +6620,7 @@ var init_chunk_KPIFWECU = __esm({
6620
6620
  }
6621
6621
  });
6622
6622
 
6623
- // ../mcp-use/dist/chunk-VDUR5PXK.js
6623
+ // ../mcp-use/dist/chunk-2KALGUHZ.js
6624
6624
  import {
6625
6625
  Client
6626
6626
  } from "@modelcontextprotocol/sdk/client/index.js";
@@ -6685,10 +6685,10 @@ function createConnectorFromConfig(serverConfig, connectorOptions) {
6685
6685
  throw new Error("Cannot determine connector type from config");
6686
6686
  }
6687
6687
  var _a18, SseConnectionManager, _a19, HttpConnector, _a20, MCPSession, _a21, BaseMCPClient;
6688
- var init_chunk_VDUR5PXK = __esm({
6689
- "../mcp-use/dist/chunk-VDUR5PXK.js"() {
6688
+ var init_chunk_2KALGUHZ = __esm({
6689
+ "../mcp-use/dist/chunk-2KALGUHZ.js"() {
6690
6690
  "use strict";
6691
- init_chunk_KPIFWECU();
6691
+ init_chunk_CT5P3B7U();
6692
6692
  init_chunk_QWQYAQCK();
6693
6693
  init_chunk_3GQAWCBQ();
6694
6694
  SseConnectionManager = (_a18 = class extends ConnectionManager {
@@ -7947,7 +7947,7 @@ var init_chunk_VDUR5PXK = __esm({
7947
7947
  }
7948
7948
  });
7949
7949
 
7950
- // ../mcp-use/dist/chunk-GEOH7R4G.js
7950
+ // ../mcp-use/dist/chunk-2ATSIYOF.js
7951
7951
  import {
7952
7952
  discoverOAuthProtectedResourceMetadata,
7953
7953
  discoverAuthorizationServerMetadata,
@@ -8257,11 +8257,11 @@ async function onMcpAuthorization() {
8257
8257
  }
8258
8258
  }
8259
8259
  var _a22, BrowserMCPClient, _a23, BrowserOAuthClientProvider;
8260
- var init_chunk_GEOH7R4G = __esm({
8261
- "../mcp-use/dist/chunk-GEOH7R4G.js"() {
8260
+ var init_chunk_2ATSIYOF = __esm({
8261
+ "../mcp-use/dist/chunk-2ATSIYOF.js"() {
8262
8262
  "use strict";
8263
- init_chunk_VDUR5PXK();
8264
- init_chunk_KPIFWECU();
8263
+ init_chunk_2KALGUHZ();
8264
+ init_chunk_CT5P3B7U();
8265
8265
  init_chunk_QWQYAQCK();
8266
8266
  init_chunk_3GQAWCBQ();
8267
8267
  __name(trackBrowserClientInit, "trackBrowserClientInit");
@@ -27978,18 +27978,18 @@ var init_stdio_transport = __esm({
27978
27978
  }
27979
27979
  });
27980
27980
 
27981
- // ../mcp-use/dist/stdio-CWIMXSHX.js
27982
- var stdio_CWIMXSHX_exports = {};
27983
- __export(stdio_CWIMXSHX_exports, {
27981
+ // ../mcp-use/dist/stdio-5Y3QCAX6.js
27982
+ var stdio_5Y3QCAX6_exports = {};
27983
+ __export(stdio_5Y3QCAX6_exports, {
27984
27984
  StdioConnector: () => StdioConnector
27985
27985
  });
27986
27986
  import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
27987
27987
  import process2 from "process";
27988
27988
  var _a38, StdioConnectionManager, _a39, StdioConnector;
27989
- var init_stdio_CWIMXSHX = __esm({
27990
- "../mcp-use/dist/stdio-CWIMXSHX.js"() {
27989
+ var init_stdio_5Y3QCAX6 = __esm({
27990
+ "../mcp-use/dist/stdio-5Y3QCAX6.js"() {
27991
27991
  "use strict";
27992
- init_chunk_KPIFWECU();
27992
+ init_chunk_CT5P3B7U();
27993
27993
  init_chunk_QWQYAQCK();
27994
27994
  init_chunk_3GQAWCBQ();
27995
27995
  init_stdio_transport();
@@ -28133,9 +28133,9 @@ var init_stdio_CWIMXSHX = __esm({
28133
28133
  }
28134
28134
  });
28135
28135
 
28136
- // ../mcp-use/dist/client-J4HPCNHM.js
28137
- var client_J4HPCNHM_exports = {};
28138
- __export(client_J4HPCNHM_exports, {
28136
+ // ../mcp-use/dist/client-QBNSMKSM.js
28137
+ var client_QBNSMKSM_exports = {};
28138
+ __export(client_QBNSMKSM_exports, {
28139
28139
  BaseCodeExecutor: () => BaseCodeExecutor,
28140
28140
  E2BCodeExecutor: () => E2BCodeExecutor,
28141
28141
  MCPClient: () => MCPClient,
@@ -28275,12 +28275,12 @@ function trackNodeClientInit(config, codeMode, callbacks) {
28275
28275
  }).catch((e2) => logger.debug(`Failed to track MCPClient init: ${e2}`));
28276
28276
  }
28277
28277
  var _a40, BaseCodeExecutor, _a41, E2BCodeExecutor, vm, vmCheckAttempted, _a42, VMCodeExecutor, _a43, CodeModeConnector, _a44, MCPClient;
28278
- var init_client_J4HPCNHM = __esm({
28279
- "../mcp-use/dist/client-J4HPCNHM.js"() {
28278
+ var init_client_QBNSMKSM = __esm({
28279
+ "../mcp-use/dist/client-QBNSMKSM.js"() {
28280
28280
  "use strict";
28281
28281
  init_chunk_LG5NSHEL();
28282
- init_chunk_VDUR5PXK();
28283
- init_chunk_KPIFWECU();
28282
+ init_chunk_2KALGUHZ();
28283
+ init_chunk_CT5P3B7U();
28284
28284
  init_chunk_QWQYAQCK();
28285
28285
  init_chunk_3GQAWCBQ();
28286
28286
  init_fs();
@@ -29217,7 +29217,7 @@ ${shim}
29217
29217
  clientInfo: serverConfig.clientInfo ?? this.config.clientInfo
29218
29218
  };
29219
29219
  if ("command" in merged && "args" in merged) {
29220
- const { StdioConnector: StdioConnector2 } = await Promise.resolve().then(() => (init_stdio_CWIMXSHX(), stdio_CWIMXSHX_exports));
29220
+ const { StdioConnector: StdioConnector2 } = await Promise.resolve().then(() => (init_stdio_5Y3QCAX6(), stdio_5Y3QCAX6_exports));
29221
29221
  const stdioConfig = merged;
29222
29222
  return new StdioConnector2({
29223
29223
  command: stdioConfig.command,
@@ -74896,11 +74896,11 @@ var _a45, BaseAdapter, _a46, LangChainAdapter, _a47, MCPServerTool, PresentActiv
74896
74896
  var init_browser = __esm({
74897
74897
  "../mcp-use/dist/src/browser.js"() {
74898
74898
  "use strict";
74899
- init_chunk_GEOH7R4G();
74899
+ init_chunk_2ATSIYOF();
74900
74900
  init_chunk_UJPHRNQP();
74901
74901
  init_chunk_LG5NSHEL();
74902
- init_chunk_VDUR5PXK();
74903
- init_chunk_KPIFWECU();
74902
+ init_chunk_2KALGUHZ();
74903
+ init_chunk_CT5P3B7U();
74904
74904
  init_chunk_QWQYAQCK();
74905
74905
  init_chunk_3GQAWCBQ();
74906
74906
  init_dist3();
@@ -76247,7 +76247,7 @@ Raw error: ${result}`
76247
76247
  logger.debug(
76248
76248
  `Creating MCPClient with ${Object.keys(this.mcpServersConfig).length} server(s)...`
76249
76249
  );
76250
- const { MCPClient: MCPClient2 } = await Promise.resolve().then(() => (init_client_J4HPCNHM(), client_J4HPCNHM_exports));
76250
+ const { MCPClient: MCPClient2 } = await Promise.resolve().then(() => (init_client_QBNSMKSM(), client_QBNSMKSM_exports));
76251
76251
  this.client = new MCPClient2({ mcpServers: this.mcpServersConfig });
76252
76252
  logger.debug("\u2705 MCPClient created successfully");
76253
76253
  }
@@ -80698,7 +80698,7 @@ var levelFilterColors = {
80698
80698
  trace: "text-gray-500"
80699
80699
  };
80700
80700
  function IframeConsole({
80701
- iframeId,
80701
+ iframeId: _iframeId,
80702
80702
  enabled = true
80703
80703
  }) {
80704
80704
  const [proxyToPageConsole, setProxyToPageConsole] = useState6(() => {
@@ -86569,6 +86569,7 @@ var InspectorContext = createContext3(
86569
86569
  void 0
86570
86570
  );
86571
86571
  function InspectorProvider({ children }) {
86572
+ const hostedChatUrl = typeof import.meta !== "undefined" ? import.meta.env?.VITE_MANUFACT_CHAT_URL : void 0;
86572
86573
  const [state, setState] = useState14({
86573
86574
  selectedServerId: null,
86574
86575
  activeTab: "tools",
@@ -86580,7 +86581,13 @@ function InspectorProvider({ children }) {
86580
86581
  tunnelUrl: null,
86581
86582
  isTunnelStarting: false,
86582
86583
  isEmbedded: false,
86583
- embeddedConfig: {}
86584
+ embeddedConfig: hostedChatUrl ? {
86585
+ chatApiUrl: hostedChatUrl,
86586
+ chatStreamProtocol: "data-stream",
86587
+ // Include cookies so the backend can recognise authenticated users
86588
+ // (session cookie shared across subdomains via COOKIE_DOMAIN).
86589
+ chatCredentials: "include"
86590
+ } : {}
86584
86591
  });
86585
86592
  const setSelectedServerId = useCallback12((serverId) => {
86586
86593
  setState((prev) => ({ ...prev, selectedServerId: serverId }));
@@ -90539,7 +90546,7 @@ function SavedPromptsList({
90539
90546
  savedPrompts,
90540
90547
  selectedPrompt,
90541
90548
  onLoadPrompt,
90542
- onDeletePrompt,
90549
+ onDeletePrompt: _onDeletePrompt,
90543
90550
  focusedIndex
90544
90551
  }) {
90545
90552
  if (savedPrompts.length === 0) {
@@ -90901,11 +90908,11 @@ function extractErrorMessage3(result) {
90901
90908
  function PromptResultDisplay({
90902
90909
  results,
90903
90910
  copiedResult,
90904
- previewMode = true,
90911
+ previewMode: _previewMode = true,
90905
90912
  onCopy,
90906
90913
  onDelete,
90907
90914
  onFullscreen,
90908
- onTogglePreview,
90915
+ onTogglePreview: _onTogglePreview,
90909
90916
  onMaximize,
90910
90917
  isMaximized = false
90911
90918
  }) {
@@ -91725,11 +91732,11 @@ PromptsTab.displayName = "PromptsTab";
91725
91732
 
91726
91733
  // src/client/components/ChatTab.tsx
91727
91734
  import {
91728
- useCallback as useCallback23,
91735
+ useCallback as useCallback24,
91729
91736
  useEffect as useEffect27,
91730
91737
  useMemo as useMemo19,
91731
91738
  useRef as useRef21,
91732
- useState as useState33
91739
+ useState as useState34
91733
91740
  } from "react";
91734
91741
  import { toast as toast7 } from "sonner";
91735
91742
 
@@ -91906,7 +91913,8 @@ function ConfigurationDialog({
91906
91913
  onSave,
91907
91914
  onClear,
91908
91915
  showClearButton = false,
91909
- buttonLabel: _buttonLabel = "Configure API Key"
91916
+ buttonLabel: _buttonLabel = "Configure API Key",
91917
+ freeTierInfo
91910
91918
  }) {
91911
91919
  const [models, setModels] = useState28([]);
91912
91920
  const [isLoadingModels, setIsLoadingModels] = useState28(false);
@@ -91961,10 +91969,22 @@ function ConfigurationDialog({
91961
91969
  };
91962
91970
  return /* @__PURE__ */ jsx68(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs43(DialogContent, { className: "max-w-md", "data-testid": "chat-config-dialog", children: [
91963
91971
  /* @__PURE__ */ jsxs43(DialogHeader, { children: [
91964
- /* @__PURE__ */ jsx68(DialogTitle, { children: "LLM Provider Configuration" }),
91965
- /* @__PURE__ */ jsx68(DialogDescription, { children: "Configure your LLM provider and API key to start chatting with the MCP server" })
91972
+ /* @__PURE__ */ jsx68(DialogTitle, { children: freeTierInfo ? "Model & usage" : "LLM Provider Configuration" }),
91973
+ /* @__PURE__ */ jsx68(DialogDescription, { children: freeTierInfo ? "You're using Manufact's free tier. Sign in to increase your limits, or bring your own key to pick any model." : "Configure your LLM provider and API key to start chatting with the MCP server" })
91966
91974
  ] }),
91967
91975
  /* @__PURE__ */ jsxs43("div", { className: "space-y-4", children: [
91976
+ freeTierInfo && /* @__PURE__ */ jsx68("div", { className: "rounded-md border bg-muted/40 p-3 space-y-2", children: /* @__PURE__ */ jsxs43("div", { className: "flex items-center justify-between gap-3", children: [
91977
+ /* @__PURE__ */ jsxs43("div", { className: "text-sm", children: [
91978
+ /* @__PURE__ */ jsx68("div", { className: "font-medium", children: "Manufact free tier" }),
91979
+ /* @__PURE__ */ jsx68("div", { className: "text-xs text-muted-foreground", children: "Sign in for increased generous limits." })
91980
+ ] }),
91981
+ /* @__PURE__ */ jsx68(Button, { size: "sm", onClick: freeTierInfo.onLoginClick, children: "Sign in" })
91982
+ ] }) }),
91983
+ freeTierInfo && /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
91984
+ /* @__PURE__ */ jsx68("div", { className: "h-px flex-1 bg-border" }),
91985
+ /* @__PURE__ */ jsx68("span", { children: "or use your own API key" }),
91986
+ /* @__PURE__ */ jsx68("div", { className: "h-px flex-1 bg-border" })
91987
+ ] }),
91968
91988
  /* @__PURE__ */ jsxs43("div", { className: "space-y-2", children: [
91969
91989
  /* @__PURE__ */ jsx68(Label2, { children: "Provider" }),
91970
91990
  /* @__PURE__ */ jsxs43(
@@ -92137,7 +92157,7 @@ function ConfigurationDialog({
92137
92157
  }
92138
92158
 
92139
92159
  // src/client/components/chat/ChatHeader.tsx
92140
- import { Fragment as Fragment17, jsx as jsx69, jsxs as jsxs44 } from "react/jsx-runtime";
92160
+ import { jsx as jsx69, jsxs as jsxs44 } from "react/jsx-runtime";
92141
92161
  function ChatHeader({
92142
92162
  llmConfig,
92143
92163
  hasMessages,
@@ -92153,6 +92173,7 @@ function ChatHeader({
92153
92173
  onSaveConfig,
92154
92174
  onClearConfig,
92155
92175
  hideConfigButton,
92176
+ freeTierInfo,
92156
92177
  clearButtonLabel,
92157
92178
  hideTitle,
92158
92179
  clearButtonHideIcon,
@@ -92165,7 +92186,7 @@ function ChatHeader({
92165
92186
  return /* @__PURE__ */ jsxs44("div", { className: "flex flex-row absolute top-0 right-0 z-10 w-full items-center justify-between p-1 pt-2 gap-2", children: [
92166
92187
  /* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 rounded-full p-2 px-2 sm:px-4", children: [
92167
92188
  !hideTitle && /* @__PURE__ */ jsx69("h3", { className: "text-xl sm:text-3xl font-base", children: "Chat" }),
92168
- llmConfig && !hideConfigButton && /* @__PURE__ */ jsx69(Fragment17, { children: /* @__PURE__ */ jsxs44(Tooltip, { children: [
92189
+ llmConfig && (!hideConfigButton || freeTierInfo) && /* @__PURE__ */ jsxs44(Tooltip, { children: [
92169
92190
  /* @__PURE__ */ jsx69(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs44(
92170
92191
  Badge,
92171
92192
  {
@@ -92187,11 +92208,11 @@ function ChatHeader({
92187
92208
  ]
92188
92209
  }
92189
92210
  ) }),
92190
- /* @__PURE__ */ jsx69(TooltipContent, { children: /* @__PURE__ */ jsx69("p", { children: "Change API Key" }) })
92191
- ] }) })
92211
+ /* @__PURE__ */ jsx69(TooltipContent, { children: /* @__PURE__ */ jsx69("p", { children: freeTierInfo ? "Change model / upgrade" : "Change API Key" }) })
92212
+ ] })
92192
92213
  ] }),
92193
92214
  /* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 pr-2 sm:pr-3 pt-0 sm:pt-2 shrink-0", children: [
92194
- llmConfig && !hideConfigButton && /* @__PURE__ */ jsxs44(Tooltip, { children: [
92215
+ llmConfig && (!hideConfigButton || freeTierInfo) && /* @__PURE__ */ jsxs44(Tooltip, { children: [
92195
92216
  /* @__PURE__ */ jsx69(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx69(
92196
92217
  Button,
92197
92218
  {
@@ -92278,7 +92299,7 @@ function ChatHeader({
92278
92299
  /* @__PURE__ */ jsx69(TooltipContent, { children: /* @__PURE__ */ jsx69("p", { children: clearButtonLabel ?? "New Chat" }) })
92279
92300
  ] })
92280
92301
  ] }),
92281
- !hideConfigButton && /* @__PURE__ */ jsx69(
92302
+ (!hideConfigButton || freeTierInfo) && /* @__PURE__ */ jsx69(
92282
92303
  ConfigurationDialog,
92283
92304
  {
92284
92305
  open: configDialogOpen,
@@ -92291,8 +92312,9 @@ function ChatHeader({
92291
92312
  onApiKeyChange,
92292
92313
  onSave: onSaveConfig,
92293
92314
  onClear: onClearConfig,
92294
- showClearButton: !!llmConfig,
92295
- buttonLabel: llmConfig ? "Change API Key" : "Configure API Key"
92315
+ showClearButton: !!llmConfig && !freeTierInfo,
92316
+ buttonLabel: llmConfig ? "Change API Key" : "Configure API Key",
92317
+ freeTierInfo
92296
92318
  }
92297
92319
  )
92298
92320
  ] })
@@ -92898,7 +92920,8 @@ function ChatLandingForm({
92898
92920
  hideModelBadge,
92899
92921
  hideServerUrl,
92900
92922
  quickQuestions = [],
92901
- onQuickQuestionSelect
92923
+ onQuickQuestionSelect,
92924
+ freeTierInfo
92902
92925
  }) {
92903
92926
  const canSend = inputValue.trim() || promptResults.length > 0 || attachments.length > 0;
92904
92927
  return /* @__PURE__ */ jsx77(AuroraBackground, { children: /* @__PURE__ */ jsxs51(BlurFade, { className: "w-full max-w-4xl mx-auto px-2 sm:px-4", children: [
@@ -92985,7 +93008,7 @@ function ChatLandingForm({
92985
93008
  },
92986
93009
  question
92987
93010
  )) }),
92988
- llmConfig && !hideModelBadge && /* @__PURE__ */ jsx77("div", { className: "flex justify-center mt-4", children: /* @__PURE__ */ jsxs51(Tooltip, { children: [
93011
+ llmConfig && (!hideModelBadge || freeTierInfo) && /* @__PURE__ */ jsx77("div", { className: "flex justify-center mt-4", children: /* @__PURE__ */ jsxs51(Tooltip, { children: [
92989
93012
  /* @__PURE__ */ jsx77(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs51(
92990
93013
  Badge,
92991
93014
  {
@@ -93007,7 +93030,7 @@ function ChatLandingForm({
93007
93030
  ]
93008
93031
  }
93009
93032
  ) }),
93010
- /* @__PURE__ */ jsx77(TooltipContent, { children: /* @__PURE__ */ jsx77("p", { children: "Change API Key" }) })
93033
+ /* @__PURE__ */ jsx77(TooltipContent, { children: /* @__PURE__ */ jsx77("p", { children: freeTierInfo ? "Change model / upgrade" : "Change API Key" }) })
93011
93034
  ] }) })
93012
93035
  ] })
93013
93036
  ] }) });
@@ -93317,7 +93340,7 @@ function UserMessage({
93317
93340
  }
93318
93341
 
93319
93342
  // src/client/components/chat/MessageList.tsx
93320
- import { Fragment as Fragment18, jsx as jsx82, jsxs as jsxs56 } from "react/jsx-runtime";
93343
+ import { Fragment as Fragment17, jsx as jsx82, jsxs as jsxs56 } from "react/jsx-runtime";
93321
93344
  var MessageList = memo4(
93322
93345
  ({
93323
93346
  messages,
@@ -93452,7 +93475,7 @@ var MessageList = memo4(
93452
93475
  ] }, partKey);
93453
93476
  }
93454
93477
  return null;
93455
- }) : /* @__PURE__ */ jsxs56(Fragment18, { children: [
93478
+ }) : /* @__PURE__ */ jsxs56(Fragment17, { children: [
93456
93479
  /* @__PURE__ */ jsx82(
93457
93480
  AssistantMessage,
93458
93481
  {
@@ -93659,6 +93682,7 @@ function useChatMessages({
93659
93682
  const [messages, setMessages] = useState31(initialMessages ?? []);
93660
93683
  const [isLoading, setIsLoading] = useState31(false);
93661
93684
  const [attachments, setAttachments] = useState31([]);
93685
+ const [rateLimitInfo, setRateLimitInfo] = useState31(null);
93662
93686
  const abortControllerRef = useRef19(null);
93663
93687
  const sendMessage = useCallback21(
93664
93688
  async (userInput, promptResults, extraAttachments) => {
@@ -93754,6 +93778,16 @@ ${parts2.join("\n")}`
93754
93778
  )
93755
93779
  });
93756
93780
  if (!response.ok) {
93781
+ if (response.status === 429) {
93782
+ const errBody = await response.json().catch(() => null);
93783
+ if (errBody?.loginRequired && errBody?.loginUrl) {
93784
+ setRateLimitInfo({ loginUrl: errBody.loginUrl });
93785
+ }
93786
+ setMessages(
93787
+ (prev) => prev.filter((m2) => m2.id !== `assistant-${Date.now()}`)
93788
+ );
93789
+ return;
93790
+ }
93757
93791
  throw new Error(`HTTP error! status: ${response.status}`);
93758
93792
  }
93759
93793
  const assistantMessageId = `assistant-${Date.now()}`;
@@ -93999,6 +94033,10 @@ ${parts2.join("\n")}`
93999
94033
  );
94000
94034
  const clearMessages = useCallback21(() => {
94001
94035
  setMessages([]);
94036
+ setRateLimitInfo(null);
94037
+ }, []);
94038
+ const clearRateLimitInfo = useCallback21(() => {
94039
+ setRateLimitInfo(null);
94002
94040
  }, []);
94003
94041
  const stop = useCallback21(() => {
94004
94042
  if (abortControllerRef.current) {
@@ -94034,8 +94072,10 @@ ${parts2.join("\n")}`
94034
94072
  messages,
94035
94073
  isLoading,
94036
94074
  attachments,
94075
+ rateLimitInfo,
94037
94076
  sendMessage,
94038
94077
  clearMessages,
94078
+ clearRateLimitInfo,
94039
94079
  setMessages,
94040
94080
  stop,
94041
94081
  addAttachment,
@@ -94592,8 +94632,321 @@ ${parts2.join("\n")}`,
94592
94632
  };
94593
94633
  }
94594
94634
 
94635
+ // src/client/components/LoginModal.tsx
94636
+ import { useCallback as useCallback23, useState as useState33 } from "react";
94637
+ import { AlertCircle, Eye as Eye2, EyeOff as EyeOff2 } from "lucide-react";
94638
+ import { Fragment as Fragment18, jsx as jsx83, jsxs as jsxs57 } from "react/jsx-runtime";
94639
+ function GoogleIcon({ className }) {
94640
+ return /* @__PURE__ */ jsxs57(
94641
+ "svg",
94642
+ {
94643
+ viewBox: "0 0 24 24",
94644
+ className,
94645
+ xmlns: "http://www.w3.org/2000/svg",
94646
+ children: [
94647
+ /* @__PURE__ */ jsx83(
94648
+ "path",
94649
+ {
94650
+ d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z",
94651
+ fill: "#4285F4"
94652
+ }
94653
+ ),
94654
+ /* @__PURE__ */ jsx83(
94655
+ "path",
94656
+ {
94657
+ d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z",
94658
+ fill: "#34A853"
94659
+ }
94660
+ ),
94661
+ /* @__PURE__ */ jsx83(
94662
+ "path",
94663
+ {
94664
+ d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z",
94665
+ fill: "#FBBC05"
94666
+ }
94667
+ ),
94668
+ /* @__PURE__ */ jsx83(
94669
+ "path",
94670
+ {
94671
+ d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z",
94672
+ fill: "#EA4335"
94673
+ }
94674
+ )
94675
+ ]
94676
+ }
94677
+ );
94678
+ }
94679
+ function GitHubIcon({ className }) {
94680
+ return /* @__PURE__ */ jsx83(
94681
+ "svg",
94682
+ {
94683
+ viewBox: "0 0 24 24",
94684
+ className,
94685
+ fill: "currentColor",
94686
+ xmlns: "http://www.w3.org/2000/svg",
94687
+ children: /* @__PURE__ */ jsx83("path", { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" })
94688
+ }
94689
+ );
94690
+ }
94691
+ function Divider({ text }) {
94692
+ return /* @__PURE__ */ jsxs57("div", { className: "relative flex items-center", children: [
94693
+ /* @__PURE__ */ jsx83("div", { className: "flex-grow border-t border-border" }),
94694
+ /* @__PURE__ */ jsx83("span", { className: "mx-3 flex-shrink text-xs text-muted-foreground", children: text }),
94695
+ /* @__PURE__ */ jsx83("div", { className: "flex-grow border-t border-border" })
94696
+ ] });
94697
+ }
94698
+ function LoginModal({
94699
+ authOrigin,
94700
+ onDismiss,
94701
+ onUseApiKey
94702
+ }) {
94703
+ const [email, setEmail] = useState33("");
94704
+ const [password, setPassword] = useState33("");
94705
+ const [showPassword, setShowPassword] = useState33(false);
94706
+ const [error, setError] = useState33(null);
94707
+ const [loading, setLoading] = useState33(
94708
+ null
94709
+ );
94710
+ const handleSuccess = useCallback23(() => {
94711
+ window.dispatchEvent(new CustomEvent("manufact:session-changed"));
94712
+ onDismiss();
94713
+ }, [onDismiss]);
94714
+ const handleEmailSignIn = async (e2) => {
94715
+ e2.preventDefault();
94716
+ setError(null);
94717
+ setLoading("email");
94718
+ try {
94719
+ const res = await fetch(`${authOrigin}/api/auth/sign-in/email`, {
94720
+ method: "POST",
94721
+ headers: { "Content-Type": "application/json" },
94722
+ credentials: "include",
94723
+ body: JSON.stringify({ email, password, rememberMe: true })
94724
+ });
94725
+ if (!res.ok) {
94726
+ const body = await res.json().catch(() => ({}));
94727
+ throw new Error(
94728
+ body.message || "Incorrect email or password."
94729
+ );
94730
+ }
94731
+ handleSuccess();
94732
+ } catch (err) {
94733
+ setError(err instanceof Error ? err.message : "Sign in failed.");
94734
+ } finally {
94735
+ setLoading(null);
94736
+ }
94737
+ };
94738
+ const handleOAuth = (provider) => {
94739
+ setError(null);
94740
+ setLoading(provider);
94741
+ const callbackURL = `${window.location.origin}/inspector/oauth-popup-closed.html`;
94742
+ fetch(`${authOrigin}/api/auth/sign-in/social`, {
94743
+ method: "POST",
94744
+ headers: { "Content-Type": "application/json" },
94745
+ credentials: "include",
94746
+ body: JSON.stringify({ provider, callbackURL })
94747
+ }).then((res) => res.json()).then((data) => {
94748
+ if (!data.url) throw new Error("No redirect URL returned");
94749
+ const popup = window.open(
94750
+ data.url,
94751
+ "manufact-oauth",
94752
+ "width=500,height=650"
94753
+ );
94754
+ const onMessage = (ev) => {
94755
+ if (ev.data?.type !== "manufact:oauth-complete") return;
94756
+ window.removeEventListener("message", onMessage);
94757
+ clearInterval(poll);
94758
+ setLoading(null);
94759
+ try {
94760
+ popup?.close();
94761
+ } catch {
94762
+ }
94763
+ handleSuccess();
94764
+ };
94765
+ window.addEventListener("message", onMessage);
94766
+ const poll = setInterval(async () => {
94767
+ const closed = !popup || popup.closed;
94768
+ try {
94769
+ const sr2 = await fetch(`${authOrigin}/api/auth/get-session`, {
94770
+ credentials: "include"
94771
+ });
94772
+ const sd = await sr2.json().catch(() => null);
94773
+ if (sd?.user) {
94774
+ clearInterval(poll);
94775
+ window.removeEventListener("message", onMessage);
94776
+ setLoading(null);
94777
+ if (!closed) {
94778
+ try {
94779
+ popup?.close();
94780
+ } catch {
94781
+ }
94782
+ }
94783
+ handleSuccess();
94784
+ return;
94785
+ }
94786
+ } catch {
94787
+ }
94788
+ if (closed) {
94789
+ clearInterval(poll);
94790
+ window.removeEventListener("message", onMessage);
94791
+ setLoading(null);
94792
+ }
94793
+ }, 2e3);
94794
+ }).catch((err) => {
94795
+ setError(err instanceof Error ? err.message : "OAuth failed.");
94796
+ setLoading(null);
94797
+ });
94798
+ };
94799
+ const isLoading = loading !== null;
94800
+ return /* @__PURE__ */ jsx83(
94801
+ Dialog,
94802
+ {
94803
+ open: true,
94804
+ onOpenChange: (open) => {
94805
+ if (!open) onDismiss();
94806
+ },
94807
+ children: /* @__PURE__ */ jsxs57(DialogContent, { className: "max-w-sm", children: [
94808
+ /* @__PURE__ */ jsxs57(DialogHeader, { children: [
94809
+ /* @__PURE__ */ jsx83(DialogTitle, { children: "Sign in to Manufact" }),
94810
+ /* @__PURE__ */ jsx83(DialogDescription, { children: "Sign in to unlock generous usage limits on the Manufact free tier." })
94811
+ ] }),
94812
+ /* @__PURE__ */ jsxs57("form", { onSubmit: handleEmailSignIn, className: "space-y-3", children: [
94813
+ /* @__PURE__ */ jsxs57("div", { className: "space-y-1.5", children: [
94814
+ /* @__PURE__ */ jsx83(Label2, { htmlFor: "lm-email", children: "Email" }),
94815
+ /* @__PURE__ */ jsx83(
94816
+ Input,
94817
+ {
94818
+ id: "lm-email",
94819
+ type: "email",
94820
+ placeholder: "you@example.com",
94821
+ value: email,
94822
+ onChange: (e2) => {
94823
+ setEmail(e2.target.value);
94824
+ setError(null);
94825
+ },
94826
+ disabled: isLoading,
94827
+ required: true,
94828
+ autoComplete: "email"
94829
+ }
94830
+ )
94831
+ ] }),
94832
+ /* @__PURE__ */ jsxs57("div", { className: "space-y-1.5", children: [
94833
+ /* @__PURE__ */ jsx83(Label2, { htmlFor: "lm-password", children: "Password" }),
94834
+ /* @__PURE__ */ jsxs57("div", { className: "relative", children: [
94835
+ /* @__PURE__ */ jsx83(
94836
+ Input,
94837
+ {
94838
+ id: "lm-password",
94839
+ type: showPassword ? "text" : "password",
94840
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
94841
+ value: password,
94842
+ onChange: (e2) => {
94843
+ setPassword(e2.target.value);
94844
+ setError(null);
94845
+ },
94846
+ disabled: isLoading,
94847
+ required: true,
94848
+ autoComplete: "current-password",
94849
+ className: "pr-10"
94850
+ }
94851
+ ),
94852
+ /* @__PURE__ */ jsx83(
94853
+ "button",
94854
+ {
94855
+ type: "button",
94856
+ className: "absolute inset-y-0 right-0 pr-3 flex items-center text-muted-foreground hover:text-foreground",
94857
+ onClick: () => setShowPassword((v2) => !v2),
94858
+ "aria-label": showPassword ? "Hide password" : "Show password",
94859
+ tabIndex: -1,
94860
+ children: showPassword ? /* @__PURE__ */ jsx83(EyeOff2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx83(Eye2, { className: "h-4 w-4" })
94861
+ }
94862
+ )
94863
+ ] })
94864
+ ] }),
94865
+ error && /* @__PURE__ */ jsxs57("p", { className: "text-sm text-destructive flex items-center gap-1.5", children: [
94866
+ /* @__PURE__ */ jsx83(AlertCircle, { className: "h-4 w-4 shrink-0" }),
94867
+ error
94868
+ ] }),
94869
+ /* @__PURE__ */ jsx83(Button, { type: "submit", disabled: isLoading, className: "w-full", children: loading === "email" ? /* @__PURE__ */ jsxs57(Fragment18, { children: [
94870
+ /* @__PURE__ */ jsx83(Spinner, { className: "mr-2" }),
94871
+ "Signing in\u2026"
94872
+ ] }) : "Sign in" })
94873
+ ] }),
94874
+ /* @__PURE__ */ jsx83(Divider, { text: "Or continue with" }),
94875
+ /* @__PURE__ */ jsxs57("div", { className: "grid grid-cols-2 gap-2", children: [
94876
+ /* @__PURE__ */ jsxs57(
94877
+ Button,
94878
+ {
94879
+ variant: "outline",
94880
+ type: "button",
94881
+ disabled: isLoading,
94882
+ onClick: () => handleOAuth("google"),
94883
+ children: [
94884
+ loading === "google" ? /* @__PURE__ */ jsx83(Spinner, { className: "mr-2" }) : /* @__PURE__ */ jsx83(GoogleIcon, { className: cn("mr-2 h-4 w-4") }),
94885
+ "Google"
94886
+ ]
94887
+ }
94888
+ ),
94889
+ /* @__PURE__ */ jsxs57(
94890
+ Button,
94891
+ {
94892
+ variant: "outline",
94893
+ type: "button",
94894
+ disabled: isLoading,
94895
+ onClick: () => handleOAuth("github"),
94896
+ children: [
94897
+ loading === "github" ? /* @__PURE__ */ jsx83(Spinner, { className: "mr-2" }) : /* @__PURE__ */ jsx83(GitHubIcon, { className: cn("mr-2 h-4 w-4") }),
94898
+ "GitHub"
94899
+ ]
94900
+ }
94901
+ )
94902
+ ] }),
94903
+ onUseApiKey && /* @__PURE__ */ jsxs57(Fragment18, { children: [
94904
+ /* @__PURE__ */ jsx83(Divider, { text: "or" }),
94905
+ /* @__PURE__ */ jsx83(
94906
+ "button",
94907
+ {
94908
+ type: "button",
94909
+ disabled: isLoading,
94910
+ onClick: onUseApiKey,
94911
+ className: "w-full text-sm text-muted-foreground hover:text-foreground transition-colors text-center",
94912
+ children: "Use your own API key"
94913
+ }
94914
+ )
94915
+ ] }),
94916
+ /* @__PURE__ */ jsxs57("p", { className: "text-xs text-center text-muted-foreground pt-1", children: [
94917
+ "By signing in you agree to our",
94918
+ " ",
94919
+ /* @__PURE__ */ jsx83(
94920
+ "a",
94921
+ {
94922
+ href: "https://manufact.com/terms",
94923
+ target: "_blank",
94924
+ rel: "noopener noreferrer",
94925
+ className: "underline hover:text-foreground",
94926
+ children: "Terms"
94927
+ }
94928
+ ),
94929
+ " ",
94930
+ "and",
94931
+ " ",
94932
+ /* @__PURE__ */ jsx83(
94933
+ "a",
94934
+ {
94935
+ href: "https://manufact.com/privacy",
94936
+ target: "_blank",
94937
+ rel: "noopener noreferrer",
94938
+ className: "underline hover:text-foreground",
94939
+ children: "Privacy Policy"
94940
+ }
94941
+ )
94942
+ ] })
94943
+ ] })
94944
+ }
94945
+ );
94946
+ }
94947
+
94595
94948
  // src/client/components/ChatTab.tsx
94596
- import { jsx as jsx83, jsxs as jsxs57 } from "react/jsx-runtime";
94949
+ import { jsx as jsx84, jsxs as jsxs58 } from "react/jsx-runtime";
94597
94950
  var PROMPT_TRIGGER_REGEX = /(?:^\/$|\s+\/$)/;
94598
94951
  var PROMPT_ARROW_KEYS = ["ArrowDown", "ArrowUp", "Escape", "Enter"];
94599
94952
  function ChatTab({
@@ -94625,12 +94978,12 @@ function ChatTab({
94625
94978
  extraHeaders,
94626
94979
  body
94627
94980
  }) {
94628
- const [inputValue, setInputValue] = useState33("");
94629
- const [promptsDropdownOpen, setPromptsDropdownOpen] = useState33(false);
94630
- const [promptFocusedIndex, setPromptFocusedIndex] = useState33(-1);
94631
- const [quickQuestions, setQuickQuestions] = useState33(chatQuickQuestions);
94632
- const [followups, setFollowups] = useState33(chatFollowups);
94633
- const [disabledTools, setDisabledTools] = useState33(/* @__PURE__ */ new Set());
94981
+ const [inputValue, setInputValue] = useState34("");
94982
+ const [promptsDropdownOpen, setPromptsDropdownOpen] = useState34(false);
94983
+ const [promptFocusedIndex, setPromptFocusedIndex] = useState34(-1);
94984
+ const [quickQuestions, setQuickQuestions] = useState34(chatQuickQuestions);
94985
+ const [followups, setFollowups] = useState34(chatFollowups);
94986
+ const [disabledTools, setDisabledTools] = useState34(/* @__PURE__ */ new Set());
94634
94987
  const textareaRef = useRef21(null);
94635
94988
  const messagesAreaRef = useRef21(null);
94636
94989
  const triggerSpanRef = useRef21(null);
@@ -94655,8 +95008,12 @@ function ChatTab({
94655
95008
  saveLLMConfig,
94656
95009
  clearConfig
94657
95010
  } = useConfig({ mcpServerUrl: connection.url });
94658
- const llmConfig = managedLlmConfig ?? localLlmConfig;
94659
- const isManaged = !!managedLlmConfig;
95011
+ const [forceClientSide, setForceClientSide] = useState34(
95012
+ () => !!localLlmConfig
95013
+ );
95014
+ const effectiveClientSide = useClientSide || forceClientSide || !!localLlmConfig;
95015
+ const llmConfig = effectiveClientSide ? localLlmConfig : managedLlmConfig ?? localLlmConfig;
95016
+ const isManaged = !effectiveClientSide && !!managedLlmConfig;
94660
95017
  const { getAllModelContexts } = useWidgetDebug();
94661
95018
  const widgetModelContexts = getAllModelContexts();
94662
95019
  const chatHookParams = {
@@ -94693,7 +95050,20 @@ function ChatTab({
94693
95050
  stop,
94694
95051
  addAttachment,
94695
95052
  removeAttachment
94696
- } = useClientSide ? clientSideChat : serverSideChat;
95053
+ } = effectiveClientSide ? clientSideChat : serverSideChat;
95054
+ const rateLimitInfo = effectiveClientSide ? null : serverSideChat.rateLimitInfo ?? null;
95055
+ const clearRateLimitInfo = effectiveClientSide ? void 0 : serverSideChat.clearRateLimitInfo;
95056
+ const handleUseApiKey = useCallback24(() => {
95057
+ clearRateLimitInfo?.();
95058
+ setForceClientSide(true);
95059
+ setConfigDialogOpen(true);
95060
+ }, [clearRateLimitInfo, setConfigDialogOpen]);
95061
+ const [showLoginModal, setShowLoginModal] = useState34(false);
95062
+ const handleOpenLogin = useCallback24(() => {
95063
+ setConfigDialogOpen(false);
95064
+ setShowLoginModal(true);
95065
+ }, [setConfigDialogOpen]);
95066
+ const freeTierInfo = isManaged ? { onLoginClick: handleOpenLogin } : void 0;
94697
95067
  const {
94698
95068
  filteredPrompts,
94699
95069
  setSelectedPrompt,
@@ -94708,11 +95078,11 @@ function ChatTab({
94708
95078
  callPrompt,
94709
95079
  serverId
94710
95080
  });
94711
- const sanitizeStringList = useCallback23((input) => {
95081
+ const sanitizeStringList = useCallback24((input) => {
94712
95082
  if (!Array.isArray(input)) return [];
94713
95083
  return input.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean).slice(0, 8);
94714
95084
  }, []);
94715
- const serializeMessageContent = useCallback23((message) => {
95085
+ const serializeMessageContent = useCallback24((message) => {
94716
95086
  if (typeof message.content === "string" && message.content.trim()) {
94717
95087
  return message.content;
94718
95088
  }
@@ -94727,7 +95097,7 @@ function ChatTab({
94727
95097
  }
94728
95098
  return "";
94729
95099
  }, []);
94730
- const serializeToolResult2 = useCallback23((result) => {
95100
+ const serializeToolResult2 = useCallback24((result) => {
94731
95101
  if (result === null || result === void 0) return "No result";
94732
95102
  if (typeof result === "string") {
94733
95103
  try {
@@ -94760,7 +95130,7 @@ function ChatTab({
94760
95130
  }
94761
95131
  return JSON.stringify(result, null, 2);
94762
95132
  }, []);
94763
- const getSerializedMessages = useCallback23(() => {
95133
+ const getSerializedMessages = useCallback24(() => {
94764
95134
  return messages.map((message) => {
94765
95135
  const textContent = serializeMessageContent(message);
94766
95136
  const toolInvocations = message.parts?.filter((p2) => p2.type === "tool-invocation" && p2.toolInvocation).map((p2) => ({
@@ -94779,7 +95149,7 @@ function ChatTab({
94779
95149
  };
94780
95150
  });
94781
95151
  }, [messages, serializeMessageContent]);
94782
- const postBridgeEvent = useCallback23(
95152
+ const postBridgeEvent = useCallback24(
94783
95153
  (type, payload = {}) => {
94784
95154
  if (typeof window === "undefined" || window.parent === window) return;
94785
95155
  window.parent.postMessage(
@@ -95049,12 +95419,12 @@ function ChatTab({
95049
95419
  useKeyboardShortcuts(
95050
95420
  enableKeyboardShortcuts ? { onNewChat: clearMessages } : {}
95051
95421
  );
95052
- const clearPromptsUIState = useCallback23(() => {
95422
+ const clearPromptsUIState = useCallback24(() => {
95053
95423
  setPromptFocusedIndex(-1);
95054
95424
  setPromptsDropdownOpen(false);
95055
95425
  triggerSpanRef.current = null;
95056
95426
  }, []);
95057
- const updatePromptsDropdownState = useCallback23(() => {
95427
+ const updatePromptsDropdownState = useCallback24(() => {
95058
95428
  if (!textareaRef.current) {
95059
95429
  return;
95060
95430
  }
@@ -95085,12 +95455,12 @@ function ChatTab({
95085
95455
  }
95086
95456
  updatePromptsDropdownState();
95087
95457
  }, [inputValue, updatePromptsDropdownState]);
95088
- const clearPromptsState = useCallback23(() => {
95458
+ const clearPromptsState = useCallback24(() => {
95089
95459
  setSelectedPrompt(null);
95090
95460
  setPromptArgs({});
95091
95461
  clearPromptsUIState();
95092
95462
  }, [clearPromptsUIState]);
95093
- const handlePromptSelect = useCallback23(
95463
+ const handlePromptSelect = useCallback24(
95094
95464
  async (prompt) => {
95095
95465
  setSelectedPrompt(prompt);
95096
95466
  if (prompt.arguments && prompt.arguments.length > 0) {
@@ -95120,7 +95490,7 @@ function ChatTab({
95120
95490
  },
95121
95491
  [executePrompt, clearPromptsState, inputValue]
95122
95492
  );
95123
- const handleSendMessage = useCallback23(() => {
95493
+ const handleSendMessage = useCallback24(() => {
95124
95494
  const hasContent = inputValue.trim() || results.length > 0 || attachments.length > 0;
95125
95495
  if (!hasContent) {
95126
95496
  return;
@@ -95129,7 +95499,7 @@ function ChatTab({
95129
95499
  setInputValue("");
95130
95500
  clearPromptResults();
95131
95501
  }, [inputValue, results, sendMessage, clearPromptResults, attachments]);
95132
- const handlePromptKeyDown = useCallback23(
95502
+ const handlePromptKeyDown = useCallback24(
95133
95503
  (e2) => {
95134
95504
  if (e2.key === "ArrowDown") {
95135
95505
  setPromptFocusedIndex((prev) => {
@@ -95158,7 +95528,7 @@ function ChatTab({
95158
95528
  clearPromptsUIState
95159
95529
  ]
95160
95530
  );
95161
- const handleKeyDown = useCallback23(
95531
+ const handleKeyDown = useCallback24(
95162
95532
  (e2) => {
95163
95533
  if (PROMPT_ARROW_KEYS.includes(e2.key) && promptsDropdownOpen) {
95164
95534
  e2.preventDefault();
@@ -95170,7 +95540,7 @@ function ChatTab({
95170
95540
  },
95171
95541
  [handleSendMessage, handlePromptKeyDown, promptsDropdownOpen]
95172
95542
  );
95173
- const handleKeyUp = useCallback23(
95543
+ const handleKeyUp = useCallback24(
95174
95544
  (e2) => {
95175
95545
  if (e2.key === "ArrowLeft" || e2.key === "ArrowRight") {
95176
95546
  updatePromptsDropdownState();
@@ -95178,7 +95548,7 @@ function ChatTab({
95178
95548
  },
95179
95549
  [updatePromptsDropdownState]
95180
95550
  );
95181
- const formatMessagesAsMarkdown = useCallback23(
95551
+ const formatMessagesAsMarkdown = useCallback24(
95182
95552
  (messages2) => {
95183
95553
  let content = `# Chat Export - ${(/* @__PURE__ */ new Date()).toLocaleString()}
95184
95554
 
@@ -95218,14 +95588,14 @@ ${sections.join("\n\n")}`;
95218
95588
  },
95219
95589
  [serializeMessageContent, serializeToolResult2]
95220
95590
  );
95221
- const handleCopyChat = useCallback23(() => {
95591
+ const handleCopyChat = useCallback24(() => {
95222
95592
  const formattedMessages = formatMessagesAsMarkdown(messages);
95223
95593
  copyToClipboard(formattedMessages).then(
95224
95594
  () => toast7.success("Chat copied to clipboard"),
95225
95595
  () => toast7.error("Failed to copy chat")
95226
95596
  );
95227
95597
  }, [messages, formatMessagesAsMarkdown]);
95228
- const handleExportChat = useCallback23(
95598
+ const handleExportChat = useCallback24(
95229
95599
  (format2) => {
95230
95600
  const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
95231
95601
  const filename = `chat-export-${dateStr}`;
@@ -95258,11 +95628,11 @@ ${sections.join("\n\n")}`;
95258
95628
  },
95259
95629
  [messages, formatMessagesAsMarkdown, serializeMessageContent]
95260
95630
  );
95261
- const handleClearConfig = useCallback23(() => {
95631
+ const handleClearConfig = useCallback24(() => {
95262
95632
  clearConfig();
95263
95633
  clearMessages();
95264
95634
  }, [clearConfig, clearMessages]);
95265
- const handleQuickQuestionSelect = useCallback23(
95635
+ const handleQuickQuestionSelect = useCallback24(
95266
95636
  (question) => {
95267
95637
  if (!question.trim()) return;
95268
95638
  if (!llmConfig || !isConnected) return;
@@ -95275,7 +95645,7 @@ ${sections.join("\n\n")}`;
95275
95645
  },
95276
95646
  [postBridgeEvent, sendMessage, llmConfig, isConnected]
95277
95647
  );
95278
- const handleFollowupSelect = useCallback23(
95648
+ const handleFollowupSelect = useCallback24(
95279
95649
  (followup) => {
95280
95650
  if (!followup.trim()) return;
95281
95651
  if (!llmConfig || !isConnected) return;
@@ -95288,9 +95658,20 @@ ${sections.join("\n\n")}`;
95288
95658
  },
95289
95659
  [postBridgeEvent, sendMessage, llmConfig, isConnected]
95290
95660
  );
95661
+ const loginModalNode = (rateLimitInfo || showLoginModal) && chatApiUrl ? /* @__PURE__ */ jsx84(
95662
+ LoginModal,
95663
+ {
95664
+ authOrigin: new URL(chatApiUrl).origin,
95665
+ onDismiss: () => {
95666
+ clearRateLimitInfo?.();
95667
+ setShowLoginModal(false);
95668
+ },
95669
+ onUseApiKey: handleUseApiKey
95670
+ }
95671
+ ) : null;
95291
95672
  if (llmConfig && messages.length === 0) {
95292
- return /* @__PURE__ */ jsxs57("div", { className: "flex flex-col h-full", children: [
95293
- !isManaged && /* @__PURE__ */ jsx83("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsx83(
95673
+ return /* @__PURE__ */ jsxs58("div", { className: "flex flex-col h-full", children: [
95674
+ /* @__PURE__ */ jsx84("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsx84(
95294
95675
  ConfigurationDialog,
95295
95676
  {
95296
95677
  open: configDialogOpen,
@@ -95303,11 +95684,12 @@ ${sections.join("\n\n")}`;
95303
95684
  onApiKeyChange: setTempApiKey,
95304
95685
  onSave: saveLLMConfig,
95305
95686
  onClear: handleClearConfig,
95306
- showClearButton: true,
95307
- buttonLabel: "Change API Key"
95687
+ showClearButton: !isManaged,
95688
+ buttonLabel: "Change API Key",
95689
+ freeTierInfo
95308
95690
  }
95309
95691
  ) }),
95310
- /* @__PURE__ */ jsx83(
95692
+ /* @__PURE__ */ jsx84(
95311
95693
  ChatLandingForm,
95312
95694
  {
95313
95695
  mcpServerUrl: connection.url,
@@ -95338,23 +95720,30 @@ ${sections.join("\n\n")}`;
95338
95720
  onConfigDialogOpenChange: setConfigDialogOpen,
95339
95721
  onAttachmentAdd: addAttachment,
95340
95722
  onAttachmentRemove: removeAttachment,
95341
- hideModelBadge,
95723
+ hideModelBadge: (
95724
+ // In hosted mode the host default is `hideModelBadge=true`, but
95725
+ // once the user has supplied their own API key (client-side mode)
95726
+ // we want the provider/model badge back so they can see and
95727
+ // change what they're using.
95728
+ hideModelBadge && !effectiveClientSide
95729
+ ),
95342
95730
  hideServerUrl,
95343
95731
  quickQuestions,
95344
- onQuickQuestionSelect: handleQuickQuestionSelect
95732
+ onQuickQuestionSelect: handleQuickQuestionSelect,
95733
+ freeTierInfo
95345
95734
  }
95346
- )
95735
+ ),
95736
+ loginModalNode
95347
95737
  ] });
95348
95738
  }
95349
- return /* @__PURE__ */ jsxs57("div", { className: "flex flex-col h-full relative", children: [
95350
- /* @__PURE__ */ jsx83(
95739
+ return /* @__PURE__ */ jsxs58("div", { className: "flex flex-col h-full relative", children: [
95740
+ /* @__PURE__ */ jsx84(
95351
95741
  ChatHeader,
95352
95742
  {
95353
95743
  llmConfig,
95354
95744
  hasMessages: messages.length > 0,
95355
- configDialogOpen: isManaged ? false : configDialogOpen,
95356
- onConfigDialogOpenChange: isManaged ? () => {
95357
- } : setConfigDialogOpen,
95745
+ configDialogOpen,
95746
+ onConfigDialogOpenChange: setConfigDialogOpen,
95358
95747
  onClearChat: clearMessages,
95359
95748
  tempProvider,
95360
95749
  tempModel,
@@ -95364,9 +95753,10 @@ ${sections.join("\n\n")}`;
95364
95753
  onApiKeyChange: setTempApiKey,
95365
95754
  onSaveConfig: saveLLMConfig,
95366
95755
  onClearConfig: handleClearConfig,
95756
+ hideConfigButton: isManaged && !freeTierInfo,
95757
+ freeTierInfo,
95367
95758
  onCopyChat: handleCopyChat,
95368
95759
  onExportChat: handleExportChat,
95369
- hideConfigButton: isManaged,
95370
95760
  clearButtonLabel,
95371
95761
  hideTitle,
95372
95762
  clearButtonHideIcon,
@@ -95375,17 +95765,17 @@ ${sections.join("\n\n")}`;
95375
95765
  hideClearButton
95376
95766
  }
95377
95767
  ),
95378
- /* @__PURE__ */ jsx83(
95768
+ /* @__PURE__ */ jsx84(
95379
95769
  "div",
95380
95770
  {
95381
95771
  ref: messagesAreaRef,
95382
95772
  className: "flex-1 overflow-y-auto p-2 sm:p-4 pt-[80px] sm:pt-[100px]",
95383
- children: !llmConfig ? /* @__PURE__ */ jsx83(
95773
+ children: !llmConfig ? /* @__PURE__ */ jsx84(
95384
95774
  ConfigureEmptyState,
95385
95775
  {
95386
95776
  onConfigureClick: () => setConfigDialogOpen(true)
95387
95777
  }
95388
- ) : /* @__PURE__ */ jsx83(
95778
+ ) : /* @__PURE__ */ jsx84(
95389
95779
  MessageList,
95390
95780
  {
95391
95781
  messages,
@@ -95399,11 +95789,12 @@ ${sections.join("\n\n")}`;
95399
95789
  )
95400
95790
  }
95401
95791
  ),
95402
- llmConfig && /* @__PURE__ */ jsx83(
95792
+ loginModalNode,
95793
+ llmConfig && /* @__PURE__ */ jsx84(
95403
95794
  ChatInputArea,
95404
95795
  {
95405
95796
  inputValue,
95406
- isConnected,
95797
+ isConnected: isConnected && !rateLimitInfo,
95407
95798
  isLoading,
95408
95799
  textareaRef,
95409
95800
  promptsDropdownOpen,