@modelnex/sdk 0.5.13 → 0.5.15
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/dist/aom-GA6W42DG.mjs +71 -0
- package/dist/aom-J6NYMGDW.mjs +69 -0
- package/dist/chunk-6DZX6EAA.mjs +37 -0
- package/dist/dom-sync-Y7Z7TOU6.mjs +57 -0
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +71 -34
- package/dist/index.mjs +70 -34
- package/package.json +12 -11
|
@@ -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://api.modelnex.com";
|
|
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://api.modelnex.com).
|
|
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://api.modelnex.com";
|
|
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://api.modelnex.com).
|
|
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,
|
|
@@ -227,11 +228,11 @@ function resolveSocketIoTransports(serverUrl, order) {
|
|
|
227
228
|
try {
|
|
228
229
|
const host = new URL(serverUrl).hostname.toLowerCase();
|
|
229
230
|
if (host.endsWith("awsapprunner.com")) {
|
|
230
|
-
return ["
|
|
231
|
+
return ["websocket"];
|
|
231
232
|
}
|
|
232
233
|
} catch {
|
|
233
234
|
}
|
|
234
|
-
return
|
|
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://api.modelnex.com";
|
|
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 ??
|
|
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) => {
|
|
@@ -3151,6 +3154,12 @@ function useTourPlayback({
|
|
|
3151
3154
|
const [serverState, setServerState] = (0, import_react12.useState)(null);
|
|
3152
3155
|
const ctx = (0, import_react12.useContext)(ModelNexContext);
|
|
3153
3156
|
const devMode = ctx?.devMode;
|
|
3157
|
+
const devModeRef = (0, import_react12.useRef)(devMode);
|
|
3158
|
+
devModeRef.current = devMode;
|
|
3159
|
+
const userProfileRef = (0, import_react12.useRef)(userProfile);
|
|
3160
|
+
userProfileRef.current = userProfile;
|
|
3161
|
+
const experienceTypeRef = (0, import_react12.useRef)(experienceType);
|
|
3162
|
+
experienceTypeRef.current = experienceType;
|
|
3154
3163
|
const tourRef = (0, import_react12.useRef)(null);
|
|
3155
3164
|
const stepIndexRef = (0, import_react12.useRef)(0);
|
|
3156
3165
|
const skipRequestedRef = (0, import_react12.useRef)(false);
|
|
@@ -3190,18 +3199,27 @@ function useTourPlayback({
|
|
|
3190
3199
|
(0, import_react12.useEffect)(() => {
|
|
3191
3200
|
if (disabled) return;
|
|
3192
3201
|
if (typeof window === "undefined") return;
|
|
3202
|
+
let cancelled = false;
|
|
3203
|
+
let createdSocket = null;
|
|
3193
3204
|
import("socket.io-client").then((ioModule) => {
|
|
3205
|
+
if (cancelled) return;
|
|
3194
3206
|
const io2 = ioModule.default || ioModule;
|
|
3195
3207
|
const socket = io2(serverUrl, {
|
|
3196
3208
|
path: "/socket.io",
|
|
3197
3209
|
// standard
|
|
3198
|
-
transports: resolveSocketIoTransports(serverUrl, "
|
|
3210
|
+
transports: resolveSocketIoTransports(serverUrl, "polling-first")
|
|
3199
3211
|
});
|
|
3212
|
+
if (cancelled) {
|
|
3213
|
+
socket.disconnect();
|
|
3214
|
+
return;
|
|
3215
|
+
}
|
|
3216
|
+
createdSocket = socket;
|
|
3200
3217
|
socketRef.current = socket;
|
|
3201
3218
|
socket.on("connect", () => {
|
|
3202
3219
|
console.log("[TourClient] Connected to tour agent server:", socket.id);
|
|
3203
|
-
|
|
3204
|
-
|
|
3220
|
+
const profile = userProfileRef.current;
|
|
3221
|
+
if (websiteId && profile?.userId) {
|
|
3222
|
+
socket.emit("tour:init", { websiteId, userId: profile.userId, userType: profile.type });
|
|
3205
3223
|
}
|
|
3206
3224
|
});
|
|
3207
3225
|
socket.on("tour:server_state", (payload) => {
|
|
@@ -3226,6 +3244,11 @@ function useTourPlayback({
|
|
|
3226
3244
|
}
|
|
3227
3245
|
});
|
|
3228
3246
|
socket.on("tour:command", async (payload) => {
|
|
3247
|
+
const emitIfOpen = (ev, data) => {
|
|
3248
|
+
if (socketRef.current !== socket) return;
|
|
3249
|
+
if (!socket.connected) return;
|
|
3250
|
+
socket.emit(ev, data);
|
|
3251
|
+
};
|
|
3229
3252
|
console.log("[TourClient] Received command batch:", payload.stepIndex, payload.commands);
|
|
3230
3253
|
runCleanup(pendingManualWaitCleanupRef.current);
|
|
3231
3254
|
pendingManualWaitCleanupRef.current = null;
|
|
@@ -3284,7 +3307,7 @@ function useTourPlayback({
|
|
|
3284
3307
|
if (!payload.commands || !Array.isArray(payload.commands)) {
|
|
3285
3308
|
console.warn("[TourClient] Payload commands is not an array:", payload);
|
|
3286
3309
|
commandInFlightRef.current = false;
|
|
3287
|
-
|
|
3310
|
+
emitIfOpen("tour:action_result", {
|
|
3288
3311
|
success: false,
|
|
3289
3312
|
reason: "invalid_commands",
|
|
3290
3313
|
commandBatchId,
|
|
@@ -3563,7 +3586,7 @@ function useTourPlayback({
|
|
|
3563
3586
|
currentStepOrder: stepIndexRef.current
|
|
3564
3587
|
});
|
|
3565
3588
|
}
|
|
3566
|
-
|
|
3589
|
+
emitIfOpen("tour:action_result", {
|
|
3567
3590
|
success: true,
|
|
3568
3591
|
interrupted: true,
|
|
3569
3592
|
results,
|
|
@@ -3588,7 +3611,7 @@ function useTourPlayback({
|
|
|
3588
3611
|
currentStepOrder: stepIndexRef.current
|
|
3589
3612
|
});
|
|
3590
3613
|
}
|
|
3591
|
-
|
|
3614
|
+
emitIfOpen("tour:action_result", {
|
|
3592
3615
|
success: false,
|
|
3593
3616
|
reason: "execution_error",
|
|
3594
3617
|
error: String(err),
|
|
@@ -3657,7 +3680,7 @@ function useTourPlayback({
|
|
|
3657
3680
|
currentStepOrder: stepIndexRef.current
|
|
3658
3681
|
});
|
|
3659
3682
|
}
|
|
3660
|
-
|
|
3683
|
+
emitIfOpen("tour:action_result", {
|
|
3661
3684
|
success: true,
|
|
3662
3685
|
waitingForInput: true,
|
|
3663
3686
|
results,
|
|
@@ -3690,7 +3713,7 @@ function useTourPlayback({
|
|
|
3690
3713
|
const { waitForDomSettle: waitForDomSettle2 } = await Promise.resolve().then(() => (init_dom_sync(), dom_sync_exports));
|
|
3691
3714
|
await waitForDomSettle2({ timeoutMs: 1500, debounceMs: 200 });
|
|
3692
3715
|
await syncAOM();
|
|
3693
|
-
|
|
3716
|
+
emitIfOpen("tour:user_input", {
|
|
3694
3717
|
transcript,
|
|
3695
3718
|
runId: runIdRef.current,
|
|
3696
3719
|
turnId: turnIdRef.current
|
|
@@ -3709,7 +3732,7 @@ function useTourPlayback({
|
|
|
3709
3732
|
currentStepOrder: stepIndexRef.current
|
|
3710
3733
|
});
|
|
3711
3734
|
}
|
|
3712
|
-
|
|
3735
|
+
emitIfOpen("tour:action_result", {
|
|
3713
3736
|
success: true,
|
|
3714
3737
|
results,
|
|
3715
3738
|
commandBatchId,
|
|
@@ -3722,8 +3745,9 @@ function useTourPlayback({
|
|
|
3722
3745
|
if (isActiveRef.current) return;
|
|
3723
3746
|
runIdRef.current = typeof tourData.runId === "number" ? tourData.runId : runIdRef.current;
|
|
3724
3747
|
const tour = tourData.tourContext ?? tourRef.current;
|
|
3725
|
-
|
|
3726
|
-
|
|
3748
|
+
const expType = experienceTypeRef.current;
|
|
3749
|
+
if (tour?.type && tour.type !== expType) {
|
|
3750
|
+
console.log(`[TourClient] Ignoring ${tour.type} start (this hook is for ${expType})`);
|
|
3727
3751
|
return;
|
|
3728
3752
|
}
|
|
3729
3753
|
skipRequestedRef.current = false;
|
|
@@ -3750,11 +3774,13 @@ function useTourPlayback({
|
|
|
3750
3774
|
try {
|
|
3751
3775
|
const { generateMinifiedAOM: generateMinifiedAOM2 } = await Promise.resolve().then(() => (init_aom(), aom_exports));
|
|
3752
3776
|
const aom = generateMinifiedAOM2();
|
|
3753
|
-
socket.
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3777
|
+
if (socketRef.current === socket && socket.connected) {
|
|
3778
|
+
socket.emit("tour:sync_dom", {
|
|
3779
|
+
url: window.location.pathname + window.location.search + window.location.hash,
|
|
3780
|
+
aom: aom.nodes,
|
|
3781
|
+
domSummary: captureDomSummary()
|
|
3782
|
+
});
|
|
3783
|
+
}
|
|
3758
3784
|
} catch (e) {
|
|
3759
3785
|
console.warn("[TourClient] Initial DOM sync failed:", e);
|
|
3760
3786
|
}
|
|
@@ -3782,7 +3808,7 @@ function useTourPlayback({
|
|
|
3782
3808
|
handleTourEnd();
|
|
3783
3809
|
});
|
|
3784
3810
|
socket.on("tour:debug_log", (entry) => {
|
|
3785
|
-
const isDev =
|
|
3811
|
+
const isDev = devModeRef.current || process.env.NODE_ENV === "development" || typeof window !== "undefined" && window.MODELNEX_DEBUG;
|
|
3786
3812
|
if (isDev) {
|
|
3787
3813
|
console.log(`%c[ModelNex Tour] ${entry.type}`, "color: #3b82f6; font-weight: bold", entry);
|
|
3788
3814
|
if (typeof window !== "undefined") {
|
|
@@ -3792,18 +3818,28 @@ function useTourPlayback({
|
|
|
3792
3818
|
}
|
|
3793
3819
|
}
|
|
3794
3820
|
});
|
|
3795
|
-
console.log("[ModelNex SDK] Tour playback initialized. Debug logs enabled:",
|
|
3821
|
+
console.log("[ModelNex SDK] Tour playback initialized. Debug logs enabled:", devModeRef.current || process.env.NODE_ENV === "development");
|
|
3796
3822
|
});
|
|
3797
3823
|
return () => {
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3824
|
+
cancelled = true;
|
|
3825
|
+
const toClose = createdSocket ?? socketRef.current;
|
|
3826
|
+
if (toClose) {
|
|
3827
|
+
toClose.disconnect();
|
|
3801
3828
|
}
|
|
3829
|
+
createdSocket = null;
|
|
3830
|
+
socketRef.current = null;
|
|
3802
3831
|
setServerState(null);
|
|
3803
3832
|
runIdRef.current = null;
|
|
3804
3833
|
turnIdRef.current = null;
|
|
3805
3834
|
};
|
|
3806
|
-
}, [serverUrl, websiteId,
|
|
3835
|
+
}, [serverUrl, websiteId, disabled]);
|
|
3836
|
+
(0, import_react12.useEffect)(() => {
|
|
3837
|
+
if (disabled) return;
|
|
3838
|
+
const s = socketRef.current;
|
|
3839
|
+
const profile = userProfile;
|
|
3840
|
+
if (!s?.connected || !websiteId || !profile?.userId) return;
|
|
3841
|
+
s.emit("tour:init", { websiteId, userId: profile.userId, userType: profile.type });
|
|
3842
|
+
}, [disabled, websiteId, userProfile?.userId, userProfile?.type]);
|
|
3807
3843
|
(0, import_react12.useEffect)(() => {
|
|
3808
3844
|
if (!showCaptions || !isReviewMode) {
|
|
3809
3845
|
removeCaption();
|
|
@@ -3942,7 +3978,7 @@ function useTourPlayback({
|
|
|
3942
3978
|
setPendingTour(null);
|
|
3943
3979
|
pendingTourRef.current = null;
|
|
3944
3980
|
let retries = 0;
|
|
3945
|
-
while (!socketRef.current?.connected && retries <
|
|
3981
|
+
while (!socketRef.current?.connected && retries < 30) {
|
|
3946
3982
|
await new Promise((r) => setTimeout(r, 200));
|
|
3947
3983
|
retries++;
|
|
3948
3984
|
}
|
|
@@ -8419,7 +8455,7 @@ function ModelNexChatBubble({
|
|
|
8419
8455
|
const messagesEndRef = (0, import_react18.useRef)(null);
|
|
8420
8456
|
const abortControllerRef = (0, import_react18.useRef)(null);
|
|
8421
8457
|
const panelRef = (0, import_react18.useRef)(null);
|
|
8422
|
-
const serverUrl = ctx?.serverUrl ??
|
|
8458
|
+
const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
8423
8459
|
const voice = useVoice(serverUrl);
|
|
8424
8460
|
const audioLevels = useAudioLevel(voice.isListening);
|
|
8425
8461
|
const recordingMode = ctx?.recordingMode ?? false;
|
|
@@ -8506,7 +8542,7 @@ function ModelNexChatBubble({
|
|
|
8506
8542
|
if (lastAutoTaggedUrlRef.current === currentUrl || localStorage.getItem(storageKey)) {
|
|
8507
8543
|
return;
|
|
8508
8544
|
}
|
|
8509
|
-
const baseUrl = commandUrl ?? serverUrl2 ??
|
|
8545
|
+
const baseUrl = commandUrl ?? serverUrl2 ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
8510
8546
|
const url = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/auto-tag` : `${baseUrl}/agent/auto-tag`;
|
|
8511
8547
|
const elements = extractedElements.map((el) => ({
|
|
8512
8548
|
fingerprint: el.fingerprint,
|
|
@@ -8896,7 +8932,7 @@ function ModelNexChatBubble({
|
|
|
8896
8932
|
}
|
|
8897
8933
|
};
|
|
8898
8934
|
const stopAgent = async () => {
|
|
8899
|
-
const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ??
|
|
8935
|
+
const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
8900
8936
|
const abortUrl = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/abort` : `${baseUrl}/agent/abort`;
|
|
8901
8937
|
try {
|
|
8902
8938
|
await fetch(abortUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ socketId: ctx?.socketId }) });
|
|
@@ -10163,7 +10199,7 @@ function ModelNexOnboardingPanel({
|
|
|
10163
10199
|
title = "Getting Started"
|
|
10164
10200
|
}) {
|
|
10165
10201
|
const ctx = (0, import_react19.useContext)(ModelNexContext);
|
|
10166
|
-
const serverUrl = ctx?.serverUrl ??
|
|
10202
|
+
const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
10167
10203
|
const voice = useVoice(serverUrl);
|
|
10168
10204
|
const audioLevels = useAudioLevel(voice.isListening);
|
|
10169
10205
|
const [input, setInput] = (0, import_react19.useState)("");
|
|
@@ -10862,15 +10898,15 @@ function TourProgressPanel({ tour, currentStepIndex, onSkip, voiceOnly }) {
|
|
|
10862
10898
|
}
|
|
10863
10899
|
|
|
10864
10900
|
// src/index.ts
|
|
10865
|
-
var DEFAULT_SERVER_URL2 = "https://69tgf4aic6.us-east-1.awsapprunner.com";
|
|
10866
10901
|
var ModelNexProvider = ({
|
|
10867
10902
|
children,
|
|
10868
10903
|
websiteId,
|
|
10869
10904
|
userProfile,
|
|
10870
10905
|
toursApiBase,
|
|
10871
|
-
devMode
|
|
10906
|
+
devMode,
|
|
10907
|
+
serverUrl: serverUrlProp
|
|
10872
10908
|
}) => {
|
|
10873
|
-
const serverUrl =
|
|
10909
|
+
const serverUrl = serverUrlProp ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
10874
10910
|
const commandUrl = void 0;
|
|
10875
10911
|
const disableSocket = false;
|
|
10876
10912
|
const renderedChildren = children;
|
|
@@ -10983,6 +11019,7 @@ var ModelNexProvider = ({
|
|
|
10983
11019
|
};
|
|
10984
11020
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10985
11021
|
0 && (module.exports = {
|
|
11022
|
+
DEFAULT_MODELNEX_SERVER_URL,
|
|
10986
11023
|
ModelNexChatBubble,
|
|
10987
11024
|
ModelNexOnboardingPanel,
|
|
10988
11025
|
ModelNexProvider,
|
package/dist/index.mjs
CHANGED
|
@@ -18,11 +18,11 @@ function resolveSocketIoTransports(serverUrl, order) {
|
|
|
18
18
|
try {
|
|
19
19
|
const host = new URL(serverUrl).hostname.toLowerCase();
|
|
20
20
|
if (host.endsWith("awsapprunner.com")) {
|
|
21
|
-
return ["
|
|
21
|
+
return ["websocket"];
|
|
22
22
|
}
|
|
23
23
|
} catch {
|
|
24
24
|
}
|
|
25
|
-
return
|
|
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://api.modelnex.com";
|
|
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 ??
|
|
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) => {
|
|
@@ -2942,6 +2944,12 @@ function useTourPlayback({
|
|
|
2942
2944
|
const [serverState, setServerState] = useState7(null);
|
|
2943
2945
|
const ctx = useContext4(ModelNexContext);
|
|
2944
2946
|
const devMode = ctx?.devMode;
|
|
2947
|
+
const devModeRef = useRef8(devMode);
|
|
2948
|
+
devModeRef.current = devMode;
|
|
2949
|
+
const userProfileRef = useRef8(userProfile);
|
|
2950
|
+
userProfileRef.current = userProfile;
|
|
2951
|
+
const experienceTypeRef = useRef8(experienceType);
|
|
2952
|
+
experienceTypeRef.current = experienceType;
|
|
2945
2953
|
const tourRef = useRef8(null);
|
|
2946
2954
|
const stepIndexRef = useRef8(0);
|
|
2947
2955
|
const skipRequestedRef = useRef8(false);
|
|
@@ -2981,18 +2989,27 @@ function useTourPlayback({
|
|
|
2981
2989
|
useEffect11(() => {
|
|
2982
2990
|
if (disabled) return;
|
|
2983
2991
|
if (typeof window === "undefined") return;
|
|
2992
|
+
let cancelled = false;
|
|
2993
|
+
let createdSocket = null;
|
|
2984
2994
|
import("socket.io-client").then((ioModule) => {
|
|
2995
|
+
if (cancelled) return;
|
|
2985
2996
|
const io2 = ioModule.default || ioModule;
|
|
2986
2997
|
const socket = io2(serverUrl, {
|
|
2987
2998
|
path: "/socket.io",
|
|
2988
2999
|
// standard
|
|
2989
|
-
transports: resolveSocketIoTransports(serverUrl, "
|
|
3000
|
+
transports: resolveSocketIoTransports(serverUrl, "polling-first")
|
|
2990
3001
|
});
|
|
3002
|
+
if (cancelled) {
|
|
3003
|
+
socket.disconnect();
|
|
3004
|
+
return;
|
|
3005
|
+
}
|
|
3006
|
+
createdSocket = socket;
|
|
2991
3007
|
socketRef.current = socket;
|
|
2992
3008
|
socket.on("connect", () => {
|
|
2993
3009
|
console.log("[TourClient] Connected to tour agent server:", socket.id);
|
|
2994
|
-
|
|
2995
|
-
|
|
3010
|
+
const profile = userProfileRef.current;
|
|
3011
|
+
if (websiteId && profile?.userId) {
|
|
3012
|
+
socket.emit("tour:init", { websiteId, userId: profile.userId, userType: profile.type });
|
|
2996
3013
|
}
|
|
2997
3014
|
});
|
|
2998
3015
|
socket.on("tour:server_state", (payload) => {
|
|
@@ -3017,6 +3034,11 @@ function useTourPlayback({
|
|
|
3017
3034
|
}
|
|
3018
3035
|
});
|
|
3019
3036
|
socket.on("tour:command", async (payload) => {
|
|
3037
|
+
const emitIfOpen = (ev, data) => {
|
|
3038
|
+
if (socketRef.current !== socket) return;
|
|
3039
|
+
if (!socket.connected) return;
|
|
3040
|
+
socket.emit(ev, data);
|
|
3041
|
+
};
|
|
3020
3042
|
console.log("[TourClient] Received command batch:", payload.stepIndex, payload.commands);
|
|
3021
3043
|
runCleanup(pendingManualWaitCleanupRef.current);
|
|
3022
3044
|
pendingManualWaitCleanupRef.current = null;
|
|
@@ -3075,7 +3097,7 @@ function useTourPlayback({
|
|
|
3075
3097
|
if (!payload.commands || !Array.isArray(payload.commands)) {
|
|
3076
3098
|
console.warn("[TourClient] Payload commands is not an array:", payload);
|
|
3077
3099
|
commandInFlightRef.current = false;
|
|
3078
|
-
|
|
3100
|
+
emitIfOpen("tour:action_result", {
|
|
3079
3101
|
success: false,
|
|
3080
3102
|
reason: "invalid_commands",
|
|
3081
3103
|
commandBatchId,
|
|
@@ -3354,7 +3376,7 @@ function useTourPlayback({
|
|
|
3354
3376
|
currentStepOrder: stepIndexRef.current
|
|
3355
3377
|
});
|
|
3356
3378
|
}
|
|
3357
|
-
|
|
3379
|
+
emitIfOpen("tour:action_result", {
|
|
3358
3380
|
success: true,
|
|
3359
3381
|
interrupted: true,
|
|
3360
3382
|
results,
|
|
@@ -3379,7 +3401,7 @@ function useTourPlayback({
|
|
|
3379
3401
|
currentStepOrder: stepIndexRef.current
|
|
3380
3402
|
});
|
|
3381
3403
|
}
|
|
3382
|
-
|
|
3404
|
+
emitIfOpen("tour:action_result", {
|
|
3383
3405
|
success: false,
|
|
3384
3406
|
reason: "execution_error",
|
|
3385
3407
|
error: String(err),
|
|
@@ -3448,7 +3470,7 @@ function useTourPlayback({
|
|
|
3448
3470
|
currentStepOrder: stepIndexRef.current
|
|
3449
3471
|
});
|
|
3450
3472
|
}
|
|
3451
|
-
|
|
3473
|
+
emitIfOpen("tour:action_result", {
|
|
3452
3474
|
success: true,
|
|
3453
3475
|
waitingForInput: true,
|
|
3454
3476
|
results,
|
|
@@ -3481,7 +3503,7 @@ function useTourPlayback({
|
|
|
3481
3503
|
const { waitForDomSettle } = await import("./dom-sync-L5KIP45X.mjs");
|
|
3482
3504
|
await waitForDomSettle({ timeoutMs: 1500, debounceMs: 200 });
|
|
3483
3505
|
await syncAOM();
|
|
3484
|
-
|
|
3506
|
+
emitIfOpen("tour:user_input", {
|
|
3485
3507
|
transcript,
|
|
3486
3508
|
runId: runIdRef.current,
|
|
3487
3509
|
turnId: turnIdRef.current
|
|
@@ -3500,7 +3522,7 @@ function useTourPlayback({
|
|
|
3500
3522
|
currentStepOrder: stepIndexRef.current
|
|
3501
3523
|
});
|
|
3502
3524
|
}
|
|
3503
|
-
|
|
3525
|
+
emitIfOpen("tour:action_result", {
|
|
3504
3526
|
success: true,
|
|
3505
3527
|
results,
|
|
3506
3528
|
commandBatchId,
|
|
@@ -3513,8 +3535,9 @@ function useTourPlayback({
|
|
|
3513
3535
|
if (isActiveRef.current) return;
|
|
3514
3536
|
runIdRef.current = typeof tourData.runId === "number" ? tourData.runId : runIdRef.current;
|
|
3515
3537
|
const tour = tourData.tourContext ?? tourRef.current;
|
|
3516
|
-
|
|
3517
|
-
|
|
3538
|
+
const expType = experienceTypeRef.current;
|
|
3539
|
+
if (tour?.type && tour.type !== expType) {
|
|
3540
|
+
console.log(`[TourClient] Ignoring ${tour.type} start (this hook is for ${expType})`);
|
|
3518
3541
|
return;
|
|
3519
3542
|
}
|
|
3520
3543
|
skipRequestedRef.current = false;
|
|
@@ -3541,11 +3564,13 @@ function useTourPlayback({
|
|
|
3541
3564
|
try {
|
|
3542
3565
|
const { generateMinifiedAOM: generateMinifiedAOM2 } = await import("./aom-HDYNCIOY.mjs");
|
|
3543
3566
|
const aom = generateMinifiedAOM2();
|
|
3544
|
-
socket.
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3567
|
+
if (socketRef.current === socket && socket.connected) {
|
|
3568
|
+
socket.emit("tour:sync_dom", {
|
|
3569
|
+
url: window.location.pathname + window.location.search + window.location.hash,
|
|
3570
|
+
aom: aom.nodes,
|
|
3571
|
+
domSummary: captureDomSummary()
|
|
3572
|
+
});
|
|
3573
|
+
}
|
|
3549
3574
|
} catch (e) {
|
|
3550
3575
|
console.warn("[TourClient] Initial DOM sync failed:", e);
|
|
3551
3576
|
}
|
|
@@ -3573,7 +3598,7 @@ function useTourPlayback({
|
|
|
3573
3598
|
handleTourEnd();
|
|
3574
3599
|
});
|
|
3575
3600
|
socket.on("tour:debug_log", (entry) => {
|
|
3576
|
-
const isDev =
|
|
3601
|
+
const isDev = devModeRef.current || process.env.NODE_ENV === "development" || typeof window !== "undefined" && window.MODELNEX_DEBUG;
|
|
3577
3602
|
if (isDev) {
|
|
3578
3603
|
console.log(`%c[ModelNex Tour] ${entry.type}`, "color: #3b82f6; font-weight: bold", entry);
|
|
3579
3604
|
if (typeof window !== "undefined") {
|
|
@@ -3583,18 +3608,28 @@ function useTourPlayback({
|
|
|
3583
3608
|
}
|
|
3584
3609
|
}
|
|
3585
3610
|
});
|
|
3586
|
-
console.log("[ModelNex SDK] Tour playback initialized. Debug logs enabled:",
|
|
3611
|
+
console.log("[ModelNex SDK] Tour playback initialized. Debug logs enabled:", devModeRef.current || process.env.NODE_ENV === "development");
|
|
3587
3612
|
});
|
|
3588
3613
|
return () => {
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3614
|
+
cancelled = true;
|
|
3615
|
+
const toClose = createdSocket ?? socketRef.current;
|
|
3616
|
+
if (toClose) {
|
|
3617
|
+
toClose.disconnect();
|
|
3592
3618
|
}
|
|
3619
|
+
createdSocket = null;
|
|
3620
|
+
socketRef.current = null;
|
|
3593
3621
|
setServerState(null);
|
|
3594
3622
|
runIdRef.current = null;
|
|
3595
3623
|
turnIdRef.current = null;
|
|
3596
3624
|
};
|
|
3597
|
-
}, [serverUrl, websiteId,
|
|
3625
|
+
}, [serverUrl, websiteId, disabled]);
|
|
3626
|
+
useEffect11(() => {
|
|
3627
|
+
if (disabled) return;
|
|
3628
|
+
const s = socketRef.current;
|
|
3629
|
+
const profile = userProfile;
|
|
3630
|
+
if (!s?.connected || !websiteId || !profile?.userId) return;
|
|
3631
|
+
s.emit("tour:init", { websiteId, userId: profile.userId, userType: profile.type });
|
|
3632
|
+
}, [disabled, websiteId, userProfile?.userId, userProfile?.type]);
|
|
3598
3633
|
useEffect11(() => {
|
|
3599
3634
|
if (!showCaptions || !isReviewMode) {
|
|
3600
3635
|
removeCaption();
|
|
@@ -3733,7 +3768,7 @@ function useTourPlayback({
|
|
|
3733
3768
|
setPendingTour(null);
|
|
3734
3769
|
pendingTourRef.current = null;
|
|
3735
3770
|
let retries = 0;
|
|
3736
|
-
while (!socketRef.current?.connected && retries <
|
|
3771
|
+
while (!socketRef.current?.connected && retries < 30) {
|
|
3737
3772
|
await new Promise((r) => setTimeout(r, 200));
|
|
3738
3773
|
retries++;
|
|
3739
3774
|
}
|
|
@@ -8209,7 +8244,7 @@ function ModelNexChatBubble({
|
|
|
8209
8244
|
const messagesEndRef = useRef13(null);
|
|
8210
8245
|
const abortControllerRef = useRef13(null);
|
|
8211
8246
|
const panelRef = useRef13(null);
|
|
8212
|
-
const serverUrl = ctx?.serverUrl ??
|
|
8247
|
+
const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
8213
8248
|
const voice = useVoice(serverUrl);
|
|
8214
8249
|
const audioLevels = useAudioLevel(voice.isListening);
|
|
8215
8250
|
const recordingMode = ctx?.recordingMode ?? false;
|
|
@@ -8296,7 +8331,7 @@ function ModelNexChatBubble({
|
|
|
8296
8331
|
if (lastAutoTaggedUrlRef.current === currentUrl || localStorage.getItem(storageKey)) {
|
|
8297
8332
|
return;
|
|
8298
8333
|
}
|
|
8299
|
-
const baseUrl = commandUrl ?? serverUrl2 ??
|
|
8334
|
+
const baseUrl = commandUrl ?? serverUrl2 ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
8300
8335
|
const url = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/auto-tag` : `${baseUrl}/agent/auto-tag`;
|
|
8301
8336
|
const elements = extractedElements.map((el) => ({
|
|
8302
8337
|
fingerprint: el.fingerprint,
|
|
@@ -8686,7 +8721,7 @@ function ModelNexChatBubble({
|
|
|
8686
8721
|
}
|
|
8687
8722
|
};
|
|
8688
8723
|
const stopAgent = async () => {
|
|
8689
|
-
const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ??
|
|
8724
|
+
const baseUrl = ctx?.commandUrl ?? ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
8690
8725
|
const abortUrl = baseUrl.startsWith("/") ? `${window.location.origin}${baseUrl}/agent/abort` : `${baseUrl}/agent/abort`;
|
|
8691
8726
|
try {
|
|
8692
8727
|
await fetch(abortUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ socketId: ctx?.socketId }) });
|
|
@@ -9953,7 +9988,7 @@ function ModelNexOnboardingPanel({
|
|
|
9953
9988
|
title = "Getting Started"
|
|
9954
9989
|
}) {
|
|
9955
9990
|
const ctx = useContext6(ModelNexContext);
|
|
9956
|
-
const serverUrl = ctx?.serverUrl ??
|
|
9991
|
+
const serverUrl = ctx?.serverUrl ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
9957
9992
|
const voice = useVoice(serverUrl);
|
|
9958
9993
|
const audioLevels = useAudioLevel(voice.isListening);
|
|
9959
9994
|
const [input, setInput] = useState14("");
|
|
@@ -10652,15 +10687,15 @@ function TourProgressPanel({ tour, currentStepIndex, onSkip, voiceOnly }) {
|
|
|
10652
10687
|
}
|
|
10653
10688
|
|
|
10654
10689
|
// src/index.ts
|
|
10655
|
-
var DEFAULT_SERVER_URL2 = "https://69tgf4aic6.us-east-1.awsapprunner.com";
|
|
10656
10690
|
var ModelNexProvider = ({
|
|
10657
10691
|
children,
|
|
10658
10692
|
websiteId,
|
|
10659
10693
|
userProfile,
|
|
10660
10694
|
toursApiBase,
|
|
10661
|
-
devMode
|
|
10695
|
+
devMode,
|
|
10696
|
+
serverUrl: serverUrlProp
|
|
10662
10697
|
}) => {
|
|
10663
|
-
const serverUrl =
|
|
10698
|
+
const serverUrl = serverUrlProp ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
10664
10699
|
const commandUrl = void 0;
|
|
10665
10700
|
const disableSocket = false;
|
|
10666
10701
|
const renderedChildren = children;
|
|
@@ -10772,6 +10807,7 @@ var ModelNexProvider = ({
|
|
|
10772
10807
|
);
|
|
10773
10808
|
};
|
|
10774
10809
|
export {
|
|
10810
|
+
DEFAULT_MODELNEX_SERVER_URL,
|
|
10775
10811
|
ModelNexChatBubble,
|
|
10776
10812
|
ModelNexOnboardingPanel,
|
|
10777
10813
|
ModelNexProvider,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelnex/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
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
|
-
|
|
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
|
+
}
|