@modelnex/sdk 0.5.12 → 0.5.14

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.
@@ -0,0 +1,71 @@
1
+ import "./chunk-6DZX6EAA.mjs";
2
+
3
+ // src/utils/aom.ts
4
+ var uidMap = /* @__PURE__ */ new Map();
5
+ var nextUid = 1;
6
+ function generateMinifiedAOM() {
7
+ uidMap.clear();
8
+ nextUid = 1;
9
+ const interactives = document.querySelectorAll(
10
+ 'button, a, input, select, textarea, [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="option"]'
11
+ );
12
+ const nodes = [];
13
+ interactives.forEach((el) => {
14
+ if (!el.offsetParent && (el.offsetWidth === 0 || el.offsetHeight === 0)) {
15
+ return;
16
+ }
17
+ if (el.closest("#modelnex-studio-root") || el.closest("#modelnex-active-agent-root")) {
18
+ return;
19
+ }
20
+ const uid = `node:${nextUid++}`;
21
+ uidMap.set(uid, el);
22
+ let text = (el.textContent || "").replace(/\s+/g, " ").trim();
23
+ const ariaLabel = el.getAttribute("aria-label");
24
+ const placeholder = el.getAttribute("placeholder");
25
+ let value = void 0;
26
+ if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
27
+ value = el.value;
28
+ }
29
+ let role = el.tagName.toLowerCase();
30
+ if (el.hasAttribute("role")) {
31
+ role = el.getAttribute("role");
32
+ } else if (role === "a") {
33
+ role = "link";
34
+ } else if (el instanceof HTMLInputElement) {
35
+ role = el.type ? `input[${el.type}]` : "input";
36
+ }
37
+ const node = { uid, role };
38
+ const displayLabel = ariaLabel || text || placeholder;
39
+ if (displayLabel) {
40
+ node.text = displayLabel.substring(0, 100);
41
+ }
42
+ if (el.getAttribute("name")) {
43
+ node.name = el.getAttribute("name");
44
+ }
45
+ if (value) {
46
+ node.value = value.substring(0, 100);
47
+ }
48
+ if (el instanceof HTMLAnchorElement && el.href) {
49
+ try {
50
+ const url = new URL(el.href);
51
+ node.href = url.pathname + url.search + url.hash;
52
+ } catch {
53
+ node.href = el.getAttribute("href");
54
+ }
55
+ }
56
+ nodes.push(node);
57
+ });
58
+ return { nodes };
59
+ }
60
+ function getElementByUid(uid) {
61
+ return uidMap.get(uid) || null;
62
+ }
63
+ function clearAOMMap() {
64
+ uidMap.clear();
65
+ nextUid = 1;
66
+ }
67
+ export {
68
+ clearAOMMap,
69
+ generateMinifiedAOM,
70
+ getElementByUid
71
+ };
@@ -0,0 +1,69 @@
1
+ // src/utils/aom.ts
2
+ var uidMap = /* @__PURE__ */ new Map();
3
+ var nextUid = 1;
4
+ function generateMinifiedAOM() {
5
+ uidMap.clear();
6
+ nextUid = 1;
7
+ const interactives = document.querySelectorAll(
8
+ 'button, a, input, select, textarea, [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="option"]'
9
+ );
10
+ const nodes = [];
11
+ interactives.forEach((el) => {
12
+ if (!el.offsetParent && (el.offsetWidth === 0 || el.offsetHeight === 0)) {
13
+ return;
14
+ }
15
+ if (el.closest("#modelnex-studio-root") || el.closest("#modelnex-active-agent-root")) {
16
+ return;
17
+ }
18
+ const uid = `node:${nextUid++}`;
19
+ uidMap.set(uid, el);
20
+ let text = (el.textContent || "").replace(/\s+/g, " ").trim();
21
+ const ariaLabel = el.getAttribute("aria-label");
22
+ const placeholder = el.getAttribute("placeholder");
23
+ let value = void 0;
24
+ if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
25
+ value = el.value;
26
+ }
27
+ let role = el.tagName.toLowerCase();
28
+ if (el.hasAttribute("role")) {
29
+ role = el.getAttribute("role");
30
+ } else if (role === "a") {
31
+ role = "link";
32
+ } else if (el instanceof HTMLInputElement) {
33
+ role = el.type ? `input[${el.type}]` : "input";
34
+ }
35
+ const node = { uid, role };
36
+ const displayLabel = ariaLabel || text || placeholder;
37
+ if (displayLabel) {
38
+ node.text = displayLabel.substring(0, 100);
39
+ }
40
+ if (el.getAttribute("name")) {
41
+ node.name = el.getAttribute("name");
42
+ }
43
+ if (value) {
44
+ node.value = value.substring(0, 100);
45
+ }
46
+ if (el instanceof HTMLAnchorElement && el.href) {
47
+ try {
48
+ const url = new URL(el.href);
49
+ node.href = url.pathname + url.search + url.hash;
50
+ } catch {
51
+ node.href = el.getAttribute("href");
52
+ }
53
+ }
54
+ nodes.push(node);
55
+ });
56
+ return { nodes };
57
+ }
58
+ function getElementByUid(uid) {
59
+ return uidMap.get(uid) || null;
60
+ }
61
+ function clearAOMMap() {
62
+ uidMap.clear();
63
+ nextUid = 1;
64
+ }
65
+ export {
66
+ clearAOMMap,
67
+ generateMinifiedAOM,
68
+ getElementByUid
69
+ };
@@ -0,0 +1,37 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __commonJS = (cb, mod) => function __require2() {
14
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+
33
+ export {
34
+ __require,
35
+ __commonJS,
36
+ __toESM
37
+ };
@@ -0,0 +1,57 @@
1
+ import "./chunk-6DZX6EAA.mjs";
2
+
3
+ // src/utils/dom-sync.ts
4
+ function waitForDomSettle(options = {}) {
5
+ const { timeoutMs = 5e3, debounceMs = 400, minWaitMs = 100 } = options;
6
+ return new Promise((resolve) => {
7
+ let debounceTimer = null;
8
+ let resolved = false;
9
+ const maxTimer = setTimeout(() => {
10
+ if (!resolved) {
11
+ resolved = true;
12
+ cleanup();
13
+ console.log("[DOM Sync] Forced resolution by max timeout");
14
+ resolve();
15
+ }
16
+ }, Math.max(timeoutMs, minWaitMs));
17
+ const finish = () => {
18
+ if (!resolved) {
19
+ resolved = true;
20
+ cleanup();
21
+ resolve();
22
+ }
23
+ };
24
+ const observer = new MutationObserver((mutations) => {
25
+ const hasSignificantMutations = mutations.some((m) => {
26
+ if (m.target instanceof HTMLElement) {
27
+ if (m.target.hasAttribute("data-modelnex-tour-highlight")) return false;
28
+ if (m.target.hasAttribute("data-modelnex-caption")) return false;
29
+ if (m.target.closest("#modelnex-studio-root")) return false;
30
+ if (m.target.closest("#modelnex-active-agent-root")) return false;
31
+ }
32
+ return true;
33
+ });
34
+ if (!hasSignificantMutations) return;
35
+ if (debounceTimer) clearTimeout(debounceTimer);
36
+ debounceTimer = setTimeout(finish, debounceMs);
37
+ });
38
+ const cleanup = () => {
39
+ observer.disconnect();
40
+ if (debounceTimer) clearTimeout(debounceTimer);
41
+ clearTimeout(maxTimer);
42
+ };
43
+ setTimeout(() => {
44
+ if (resolved) return;
45
+ observer.observe(document.body, {
46
+ childList: true,
47
+ subtree: true,
48
+ attributes: true,
49
+ characterData: true
50
+ });
51
+ debounceTimer = setTimeout(finish, debounceMs);
52
+ }, minWaitMs);
53
+ });
54
+ }
55
+ export {
56
+ waitForDomSettle
57
+ };
package/dist/index.d.mts CHANGED
@@ -227,6 +227,9 @@ interface RecordingStep {
227
227
  onboarding?: OnboardingStepMetadata;
228
228
  }
229
229
 
230
+ /** Default ModelNex server when `serverUrl` is omitted or React context is unavailable. */
231
+ declare const DEFAULT_MODELNEX_SERVER_URL = "https://modelnex-server-production.up.railway.app";
232
+
230
233
  /**
231
234
  * Automatic DOM element extraction with stable fingerprinting.
232
235
  *
@@ -818,6 +821,11 @@ declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
818
821
 
819
822
  interface ModelNexProviderProps {
820
823
  children?: unknown;
824
+ /**
825
+ * ModelNex Server URL (e.g. https://xxx.up.railway.app).
826
+ * When omitted, {@link DEFAULT_MODELNEX_SERVER_URL} is used.
827
+ */
828
+ serverUrl?: string;
821
829
  /** Identifier for the integrated website, for multi-tenancy */
822
830
  websiteId?: string;
823
831
  /**
@@ -838,4 +846,4 @@ interface ModelNexProviderProps {
838
846
  }
839
847
  declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
840
848
 
841
- export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
849
+ export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, DEFAULT_MODELNEX_SERVER_URL, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
package/dist/index.d.ts CHANGED
@@ -227,6 +227,9 @@ interface RecordingStep {
227
227
  onboarding?: OnboardingStepMetadata;
228
228
  }
229
229
 
230
+ /** Default ModelNex server when `serverUrl` is omitted or React context is unavailable. */
231
+ declare const DEFAULT_MODELNEX_SERVER_URL = "https://modelnex-server-production.up.railway.app";
232
+
230
233
  /**
231
234
  * Automatic DOM element extraction with stable fingerprinting.
232
235
  *
@@ -818,6 +821,11 @@ declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
818
821
 
819
822
  interface ModelNexProviderProps {
820
823
  children?: unknown;
824
+ /**
825
+ * ModelNex Server URL (e.g. https://xxx.up.railway.app).
826
+ * When omitted, {@link DEFAULT_MODELNEX_SERVER_URL} is used.
827
+ */
828
+ serverUrl?: string;
821
829
  /** Identifier for the integrated website, for multi-tenancy */
822
830
  websiteId?: string;
823
831
  /**
@@ -838,4 +846,4 @@ interface ModelNexProviderProps {
838
846
  }
839
847
  declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
840
848
 
841
- export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
849
+ export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, DEFAULT_MODELNEX_SERVER_URL, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
package/dist/index.js CHANGED
@@ -172,6 +172,7 @@ var init_dom_sync = __esm({
172
172
  // src/index.ts
173
173
  var index_exports = {};
174
174
  __export(index_exports, {
175
+ DEFAULT_MODELNEX_SERVER_URL: () => DEFAULT_MODELNEX_SERVER_URL,
175
176
  ModelNexChatBubble: () => ModelNexChatBubble,
176
177
  ModelNexOnboardingPanel: () => ModelNexOnboardingPanel,
177
178
  ModelNexProvider: () => ModelNexProvider,
@@ -231,7 +232,7 @@ function resolveSocketIoTransports(serverUrl, order) {
231
232
  }
232
233
  } catch {
233
234
  }
234
- return order === "websocket-first" ? ["websocket", "polling"] : ["polling", "websocket"];
235
+ return ["websocket", "polling"];
235
236
  }
236
237
 
237
238
  // src/auto-extract.ts
@@ -2322,9 +2323,11 @@ function useBuiltinActions(registerAction, unregisterAction, tagStore, serverUrl
2322
2323
  }, [registerAction, unregisterAction]);
2323
2324
  }
2324
2325
 
2326
+ // src/constants.ts
2327
+ var DEFAULT_MODELNEX_SERVER_URL = "https://modelnex-server-production.up.railway.app";
2328
+
2325
2329
  // src/hooks/useRunCommand.ts
2326
2330
  var import_react9 = require("react");
2327
- var DEFAULT_SERVER_URL = "https://69tgf4aic6.us-east-1.awsapprunner.com";
2328
2331
  function searchTaggedElementsForQuery(store, query, limit = 8) {
2329
2332
  const allTags = store.getAllTags();
2330
2333
  if (allTags.length === 0) return [];
@@ -2345,7 +2348,7 @@ function searchTaggedElementsForQuery(store, query, limit = 8) {
2345
2348
  }
2346
2349
  function useRunCommand(serverUrlOverride) {
2347
2350
  const context = (0, import_react9.useContext)(ModelNexContext);
2348
- const baseUrl = serverUrlOverride ?? context?.commandUrl ?? context?.serverUrl ?? DEFAULT_SERVER_URL;
2351
+ const baseUrl = serverUrlOverride ?? context?.commandUrl ?? context?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
2349
2352
  const tagStore = context?.tagStore;
2350
2353
  return (0, import_react9.useCallback)(
2351
2354
  async (command, signal) => {
@@ -3195,7 +3198,7 @@ function useTourPlayback({
3195
3198
  const socket = io2(serverUrl, {
3196
3199
  path: "/socket.io",
3197
3200
  // standard
3198
- transports: resolveSocketIoTransports(serverUrl, "websocket-first")
3201
+ transports: resolveSocketIoTransports(serverUrl, "polling-first")
3199
3202
  });
3200
3203
  socketRef.current = socket;
3201
3204
  socket.on("connect", () => {
@@ -3942,7 +3945,7 @@ function useTourPlayback({
3942
3945
  setPendingTour(null);
3943
3946
  pendingTourRef.current = null;
3944
3947
  let retries = 0;
3945
- while (!socketRef.current?.connected && retries < 15) {
3948
+ while (!socketRef.current?.connected && retries < 30) {
3946
3949
  await new Promise((r) => setTimeout(r, 200));
3947
3950
  retries++;
3948
3951
  }
@@ -8419,7 +8422,7 @@ function ModelNexChatBubble({
8419
8422
  const messagesEndRef = (0, import_react18.useRef)(null);
8420
8423
  const abortControllerRef = (0, import_react18.useRef)(null);
8421
8424
  const panelRef = (0, import_react18.useRef)(null);
8422
- const serverUrl = ctx?.serverUrl ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
8425
+ const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
8423
8426
  const voice = useVoice(serverUrl);
8424
8427
  const audioLevels = useAudioLevel(voice.isListening);
8425
8428
  const recordingMode = ctx?.recordingMode ?? false;
@@ -8506,7 +8509,7 @@ function ModelNexChatBubble({
8506
8509
  if (lastAutoTaggedUrlRef.current === currentUrl || localStorage.getItem(storageKey)) {
8507
8510
  return;
8508
8511
  }
8509
- const baseUrl = commandUrl ?? serverUrl2 ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
8512
+ const baseUrl = commandUrl ?? serverUrl2 ?? DEFAULT_MODELNEX_SERVER_URL;
8510
8513
  const url = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/auto-tag` : `${baseUrl}/agent/auto-tag`;
8511
8514
  const elements = extractedElements.map((el) => ({
8512
8515
  fingerprint: el.fingerprint,
@@ -8896,7 +8899,7 @@ function ModelNexChatBubble({
8896
8899
  }
8897
8900
  };
8898
8901
  const stopAgent = async () => {
8899
- const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
8902
+ const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
8900
8903
  const abortUrl = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/abort` : `${baseUrl}/agent/abort`;
8901
8904
  try {
8902
8905
  await fetch(abortUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ socketId: ctx?.socketId }) });
@@ -10163,7 +10166,7 @@ function ModelNexOnboardingPanel({
10163
10166
  title = "Getting Started"
10164
10167
  }) {
10165
10168
  const ctx = (0, import_react19.useContext)(ModelNexContext);
10166
- const serverUrl = ctx?.serverUrl ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
10169
+ const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
10167
10170
  const voice = useVoice(serverUrl);
10168
10171
  const audioLevels = useAudioLevel(voice.isListening);
10169
10172
  const [input, setInput] = (0, import_react19.useState)("");
@@ -10862,15 +10865,15 @@ function TourProgressPanel({ tour, currentStepIndex, onSkip, voiceOnly }) {
10862
10865
  }
10863
10866
 
10864
10867
  // src/index.ts
10865
- var DEFAULT_SERVER_URL2 = "https://69tgf4aic6.us-east-1.awsapprunner.com";
10866
10868
  var ModelNexProvider = ({
10867
10869
  children,
10868
10870
  websiteId,
10869
10871
  userProfile,
10870
10872
  toursApiBase,
10871
- devMode
10873
+ devMode,
10874
+ serverUrl: serverUrlProp
10872
10875
  }) => {
10873
- const serverUrl = DEFAULT_SERVER_URL2;
10876
+ const serverUrl = serverUrlProp ?? DEFAULT_MODELNEX_SERVER_URL;
10874
10877
  const commandUrl = void 0;
10875
10878
  const disableSocket = false;
10876
10879
  const renderedChildren = children;
@@ -10983,6 +10986,7 @@ var ModelNexProvider = ({
10983
10986
  };
10984
10987
  // Annotate the CommonJS export names for ESM import in node:
10985
10988
  0 && (module.exports = {
10989
+ DEFAULT_MODELNEX_SERVER_URL,
10986
10990
  ModelNexChatBubble,
10987
10991
  ModelNexOnboardingPanel,
10988
10992
  ModelNexProvider,
package/dist/index.mjs CHANGED
@@ -22,7 +22,7 @@ function resolveSocketIoTransports(serverUrl, order) {
22
22
  }
23
23
  } catch {
24
24
  }
25
- return order === "websocket-first" ? ["websocket", "polling"] : ["polling", "websocket"];
25
+ return ["websocket", "polling"];
26
26
  }
27
27
 
28
28
  // src/auto-extract.ts
@@ -2113,9 +2113,11 @@ function useBuiltinActions(registerAction, unregisterAction, tagStore, serverUrl
2113
2113
  }, [registerAction, unregisterAction]);
2114
2114
  }
2115
2115
 
2116
+ // src/constants.ts
2117
+ var DEFAULT_MODELNEX_SERVER_URL = "https://modelnex-server-production.up.railway.app";
2118
+
2116
2119
  // src/hooks/useRunCommand.ts
2117
2120
  import { useCallback as useCallback5, useContext as useContext2 } from "react";
2118
- var DEFAULT_SERVER_URL = "https://69tgf4aic6.us-east-1.awsapprunner.com";
2119
2121
  function searchTaggedElementsForQuery(store, query, limit = 8) {
2120
2122
  const allTags = store.getAllTags();
2121
2123
  if (allTags.length === 0) return [];
@@ -2136,7 +2138,7 @@ function searchTaggedElementsForQuery(store, query, limit = 8) {
2136
2138
  }
2137
2139
  function useRunCommand(serverUrlOverride) {
2138
2140
  const context = useContext2(ModelNexContext);
2139
- const baseUrl = serverUrlOverride ?? context?.commandUrl ?? context?.serverUrl ?? DEFAULT_SERVER_URL;
2141
+ const baseUrl = serverUrlOverride ?? context?.commandUrl ?? context?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
2140
2142
  const tagStore = context?.tagStore;
2141
2143
  return useCallback5(
2142
2144
  async (command, signal) => {
@@ -2986,7 +2988,7 @@ function useTourPlayback({
2986
2988
  const socket = io2(serverUrl, {
2987
2989
  path: "/socket.io",
2988
2990
  // standard
2989
- transports: resolveSocketIoTransports(serverUrl, "websocket-first")
2991
+ transports: resolveSocketIoTransports(serverUrl, "polling-first")
2990
2992
  });
2991
2993
  socketRef.current = socket;
2992
2994
  socket.on("connect", () => {
@@ -3733,7 +3735,7 @@ function useTourPlayback({
3733
3735
  setPendingTour(null);
3734
3736
  pendingTourRef.current = null;
3735
3737
  let retries = 0;
3736
- while (!socketRef.current?.connected && retries < 15) {
3738
+ while (!socketRef.current?.connected && retries < 30) {
3737
3739
  await new Promise((r) => setTimeout(r, 200));
3738
3740
  retries++;
3739
3741
  }
@@ -8209,7 +8211,7 @@ function ModelNexChatBubble({
8209
8211
  const messagesEndRef = useRef13(null);
8210
8212
  const abortControllerRef = useRef13(null);
8211
8213
  const panelRef = useRef13(null);
8212
- const serverUrl = ctx?.serverUrl ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
8214
+ const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
8213
8215
  const voice = useVoice(serverUrl);
8214
8216
  const audioLevels = useAudioLevel(voice.isListening);
8215
8217
  const recordingMode = ctx?.recordingMode ?? false;
@@ -8296,7 +8298,7 @@ function ModelNexChatBubble({
8296
8298
  if (lastAutoTaggedUrlRef.current === currentUrl || localStorage.getItem(storageKey)) {
8297
8299
  return;
8298
8300
  }
8299
- const baseUrl = commandUrl ?? serverUrl2 ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
8301
+ const baseUrl = commandUrl ?? serverUrl2 ?? DEFAULT_MODELNEX_SERVER_URL;
8300
8302
  const url = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/auto-tag` : `${baseUrl}/agent/auto-tag`;
8301
8303
  const elements = extractedElements.map((el) => ({
8302
8304
  fingerprint: el.fingerprint,
@@ -8686,7 +8688,7 @@ function ModelNexChatBubble({
8686
8688
  }
8687
8689
  };
8688
8690
  const stopAgent = async () => {
8689
- const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
8691
+ const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
8690
8692
  const abortUrl = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/abort` : `${baseUrl}/agent/abort`;
8691
8693
  try {
8692
8694
  await fetch(abortUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ socketId: ctx?.socketId }) });
@@ -9953,7 +9955,7 @@ function ModelNexOnboardingPanel({
9953
9955
  title = "Getting Started"
9954
9956
  }) {
9955
9957
  const ctx = useContext6(ModelNexContext);
9956
- const serverUrl = ctx?.serverUrl ?? "https://69tgf4aic6.us-east-1.awsapprunner.com";
9958
+ const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
9957
9959
  const voice = useVoice(serverUrl);
9958
9960
  const audioLevels = useAudioLevel(voice.isListening);
9959
9961
  const [input, setInput] = useState14("");
@@ -10652,15 +10654,15 @@ function TourProgressPanel({ tour, currentStepIndex, onSkip, voiceOnly }) {
10652
10654
  }
10653
10655
 
10654
10656
  // src/index.ts
10655
- var DEFAULT_SERVER_URL2 = "https://69tgf4aic6.us-east-1.awsapprunner.com";
10656
10657
  var ModelNexProvider = ({
10657
10658
  children,
10658
10659
  websiteId,
10659
10660
  userProfile,
10660
10661
  toursApiBase,
10661
- devMode
10662
+ devMode,
10663
+ serverUrl: serverUrlProp
10662
10664
  }) => {
10663
- const serverUrl = DEFAULT_SERVER_URL2;
10665
+ const serverUrl = serverUrlProp ?? DEFAULT_MODELNEX_SERVER_URL;
10664
10666
  const commandUrl = void 0;
10665
10667
  const disableSocket = false;
10666
10668
  const renderedChildren = children;
@@ -10772,6 +10774,7 @@ var ModelNexProvider = ({
10772
10774
  );
10773
10775
  };
10774
10776
  export {
10777
+ DEFAULT_MODELNEX_SERVER_URL,
10775
10778
  ModelNexChatBubble,
10776
10779
  ModelNexOnboardingPanel,
10777
10780
  ModelNexProvider,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelnex/sdk",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
4
4
  "description": "React SDK for natural language control of web apps via AI agents",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -20,6 +20,15 @@
20
20
  "dist",
21
21
  "README.md"
22
22
  ],
23
+ "scripts": {
24
+ "prepublishOnly": "npm run build",
25
+ "build": "npm exec -- tsup src/index.ts --format cjs,esm --dts",
26
+ "dev": "npm exec -- tsup src/index.ts --format cjs,esm --watch --dts",
27
+ "lint": "eslint src/",
28
+ "test": "npm run build && node --test tests/*.test.js",
29
+ "test:ci": "npm run test && npm run test:unit",
30
+ "test:unit": "node --import tsx --test tests/*.test.ts"
31
+ },
23
32
  "peerDependencies": {
24
33
  "react": ">=17.0.0",
25
34
  "react-dom": ">=17.0.0",
@@ -58,13 +67,5 @@
58
67
  "bugs": {
59
68
  "url": "https://github.com/sharunaraksha/modelnex-sdk/issues"
60
69
  },
61
- "homepage": "https://github.com/sharunaraksha/modelnex-sdk#readme",
62
- "scripts": {
63
- "build": "npm exec -- tsup src/index.ts --format cjs,esm --dts",
64
- "dev": "npm exec -- tsup src/index.ts --format cjs,esm --watch --dts",
65
- "lint": "eslint src/",
66
- "test": "npm run build && node --test tests/*.test.js",
67
- "test:ci": "npm run test && npm run test:unit",
68
- "test:unit": "node --import tsx --test tests/*.test.ts"
69
- }
70
- }
70
+ "homepage": "https://github.com/sharunaraksha/modelnex-sdk#readme"
71
+ }