@modelnex/sdk 0.5.36 → 0.5.38
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/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +208 -127
- package/dist/index.mjs +206 -127
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -817,9 +817,14 @@ interface SavedDraftPreview {
|
|
|
817
817
|
experienceType: ExperienceType;
|
|
818
818
|
}
|
|
819
819
|
type PreviewLaunchSource = 'standard' | 'query_param';
|
|
820
|
+
type DraftPreviewModeListener = (enabled: boolean) => void;
|
|
820
821
|
declare function getPreviewQueryParamName(experienceType: ExperienceType): 'modelnex_test_tour' | 'modelnex_test_workflow';
|
|
821
822
|
declare function buildDraftPreviewUrl(currentUrl: string, draft: SavedDraftPreview): string;
|
|
822
823
|
declare function shouldPromptForPreviewStart(notificationType: TourNotificationType | undefined, _source: PreviewLaunchSource): boolean;
|
|
824
|
+
declare function hasDraftPreviewModeSignal(): boolean;
|
|
825
|
+
declare function observeDraftPreviewModeSignal(listener: DraftPreviewModeListener, options?: {
|
|
826
|
+
pollIntervalMs?: number;
|
|
827
|
+
}): () => void;
|
|
823
828
|
declare function persistActiveDraftPreview(draft: SavedDraftPreview): void;
|
|
824
829
|
declare function readActiveDraftPreview(): SavedDraftPreview | null;
|
|
825
830
|
declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
|
|
@@ -847,4 +852,4 @@ interface ModelNexProviderProps {
|
|
|
847
852
|
}
|
|
848
853
|
declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
|
|
849
854
|
|
|
850
|
-
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 };
|
|
855
|
+
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, hasDraftPreviewModeSignal, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, observeDraftPreviewModeSignal, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
|
package/dist/index.d.ts
CHANGED
|
@@ -817,9 +817,14 @@ interface SavedDraftPreview {
|
|
|
817
817
|
experienceType: ExperienceType;
|
|
818
818
|
}
|
|
819
819
|
type PreviewLaunchSource = 'standard' | 'query_param';
|
|
820
|
+
type DraftPreviewModeListener = (enabled: boolean) => void;
|
|
820
821
|
declare function getPreviewQueryParamName(experienceType: ExperienceType): 'modelnex_test_tour' | 'modelnex_test_workflow';
|
|
821
822
|
declare function buildDraftPreviewUrl(currentUrl: string, draft: SavedDraftPreview): string;
|
|
822
823
|
declare function shouldPromptForPreviewStart(notificationType: TourNotificationType | undefined, _source: PreviewLaunchSource): boolean;
|
|
824
|
+
declare function hasDraftPreviewModeSignal(): boolean;
|
|
825
|
+
declare function observeDraftPreviewModeSignal(listener: DraftPreviewModeListener, options?: {
|
|
826
|
+
pollIntervalMs?: number;
|
|
827
|
+
}): () => void;
|
|
823
828
|
declare function persistActiveDraftPreview(draft: SavedDraftPreview): void;
|
|
824
829
|
declare function readActiveDraftPreview(): SavedDraftPreview | null;
|
|
825
830
|
declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
|
|
@@ -847,4 +852,4 @@ interface ModelNexProviderProps {
|
|
|
847
852
|
}
|
|
848
853
|
declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
|
|
849
854
|
|
|
850
|
-
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 };
|
|
855
|
+
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, hasDraftPreviewModeSignal, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, observeDraftPreviewModeSignal, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
|
package/dist/index.js
CHANGED
|
@@ -188,11 +188,13 @@ __export(index_exports, {
|
|
|
188
188
|
getPreviewQueryParamName: () => getPreviewQueryParamName,
|
|
189
189
|
getRecordingDraftActionLabel: () => getRecordingDraftActionLabel,
|
|
190
190
|
getRecordingDraftStatusMessage: () => getRecordingDraftStatusMessage,
|
|
191
|
+
hasDraftPreviewModeSignal: () => hasDraftPreviewModeSignal,
|
|
191
192
|
inferOnboardingMetadataForStep: () => inferOnboardingMetadataForStep,
|
|
192
193
|
isAskDrivenInputStepType: () => isAskDrivenInputStepType,
|
|
193
194
|
isInteractiveInputStepType: () => isInteractiveInputStepType,
|
|
194
195
|
isManualOnboardingStep: () => isManualOnboardingStep,
|
|
195
196
|
isRecordingDraftGenerating: () => isRecordingDraftGenerating,
|
|
197
|
+
observeDraftPreviewModeSignal: () => observeDraftPreviewModeSignal,
|
|
196
198
|
persistActiveDraftPreview: () => persistActiveDraftPreview,
|
|
197
199
|
readActiveDraftPreview: () => readActiveDraftPreview,
|
|
198
200
|
shouldPromptForPreviewStart: () => shouldPromptForPreviewStart,
|
|
@@ -918,10 +920,7 @@ function useModelNexSocket({
|
|
|
918
920
|
contexts: serializeContexts(contextsRef.current),
|
|
919
921
|
documentation: documentationRef.current ?? void 0,
|
|
920
922
|
domSummary: captureDomSummary(tagsRef.current),
|
|
921
|
-
websiteId
|
|
922
|
-
// All tagged elements across every page — not just what's visible now.
|
|
923
|
-
// The server uses this to pre-search relevant elements for each user query.
|
|
924
|
-
allTaggedElements: tagsRef.current ? Array.from(tagsRef.current.values()) : void 0
|
|
923
|
+
websiteId
|
|
925
924
|
});
|
|
926
925
|
socket.on("connect", () => {
|
|
927
926
|
emitSdkDebugLog("[ModelNex SDK] Connected to agent server", {
|
|
@@ -2918,6 +2917,159 @@ function clearPersistedRecordingSession() {
|
|
|
2918
2917
|
}
|
|
2919
2918
|
}
|
|
2920
2919
|
|
|
2920
|
+
// src/utils/draftPreview.ts
|
|
2921
|
+
var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
|
|
2922
|
+
var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
|
|
2923
|
+
var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
|
|
2924
|
+
function getPreviewQueryParamName(experienceType) {
|
|
2925
|
+
return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
|
|
2926
|
+
}
|
|
2927
|
+
function buildDraftPreviewUrl(currentUrl, draft) {
|
|
2928
|
+
const url = new URL(currentUrl);
|
|
2929
|
+
url.searchParams.delete("modelnex_test_tour");
|
|
2930
|
+
url.searchParams.delete("modelnex_test_onboarding");
|
|
2931
|
+
url.searchParams.delete("modelnex_test_workflow");
|
|
2932
|
+
url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
|
|
2933
|
+
return url.toString();
|
|
2934
|
+
}
|
|
2935
|
+
function shouldPromptForPreviewStart(notificationType, _source) {
|
|
2936
|
+
const normalizedNotificationType = notificationType ?? "bubble_card";
|
|
2937
|
+
return normalizedNotificationType === "modal";
|
|
2938
|
+
}
|
|
2939
|
+
function hasDraftPreviewModeSignal() {
|
|
2940
|
+
if (typeof window === "undefined") return false;
|
|
2941
|
+
try {
|
|
2942
|
+
const params = new URLSearchParams(window.location.search);
|
|
2943
|
+
if (params.has("modelnex_test_tour") || params.has("modelnex_test_workflow") || params.has("modelnex_test_onboarding")) {
|
|
2944
|
+
return true;
|
|
2945
|
+
}
|
|
2946
|
+
} catch {
|
|
2947
|
+
}
|
|
2948
|
+
return readActiveDraftPreview() !== null;
|
|
2949
|
+
}
|
|
2950
|
+
function observeDraftPreviewModeSignal(listener, options) {
|
|
2951
|
+
if (typeof window === "undefined") return () => {
|
|
2952
|
+
};
|
|
2953
|
+
let currentValue = hasDraftPreviewModeSignal();
|
|
2954
|
+
const pollIntervalMs = options?.pollIntervalMs ?? 500;
|
|
2955
|
+
const syncPreviewModeSignal = () => {
|
|
2956
|
+
const nextValue = hasDraftPreviewModeSignal();
|
|
2957
|
+
if (nextValue === currentValue) return;
|
|
2958
|
+
currentValue = nextValue;
|
|
2959
|
+
listener(nextValue);
|
|
2960
|
+
};
|
|
2961
|
+
const intervalId = window.setInterval(syncPreviewModeSignal, pollIntervalMs);
|
|
2962
|
+
window.addEventListener("focus", syncPreviewModeSignal);
|
|
2963
|
+
window.addEventListener("pageshow", syncPreviewModeSignal);
|
|
2964
|
+
window.addEventListener("popstate", syncPreviewModeSignal);
|
|
2965
|
+
if (typeof document !== "undefined") {
|
|
2966
|
+
document.addEventListener("visibilitychange", syncPreviewModeSignal);
|
|
2967
|
+
}
|
|
2968
|
+
return () => {
|
|
2969
|
+
window.clearInterval(intervalId);
|
|
2970
|
+
window.removeEventListener("focus", syncPreviewModeSignal);
|
|
2971
|
+
window.removeEventListener("pageshow", syncPreviewModeSignal);
|
|
2972
|
+
window.removeEventListener("popstate", syncPreviewModeSignal);
|
|
2973
|
+
if (typeof document !== "undefined") {
|
|
2974
|
+
document.removeEventListener("visibilitychange", syncPreviewModeSignal);
|
|
2975
|
+
}
|
|
2976
|
+
};
|
|
2977
|
+
}
|
|
2978
|
+
function persistActiveDraftPreview(draft) {
|
|
2979
|
+
if (typeof window === "undefined") return;
|
|
2980
|
+
try {
|
|
2981
|
+
window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
2982
|
+
} catch {
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
function readActiveDraftPreview() {
|
|
2986
|
+
if (typeof window === "undefined") return null;
|
|
2987
|
+
try {
|
|
2988
|
+
const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2989
|
+
if (!raw) return null;
|
|
2990
|
+
const parsed = JSON.parse(raw);
|
|
2991
|
+
if (!parsed || typeof parsed.id !== "string") return null;
|
|
2992
|
+
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
2993
|
+
return {
|
|
2994
|
+
id: parsed.id,
|
|
2995
|
+
experienceType: parsed.experienceType
|
|
2996
|
+
};
|
|
2997
|
+
} catch {
|
|
2998
|
+
return null;
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
function clearActiveDraftPreview(experienceType) {
|
|
3002
|
+
if (typeof window === "undefined") return;
|
|
3003
|
+
try {
|
|
3004
|
+
const activePreview = readActiveDraftPreview();
|
|
3005
|
+
if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
|
|
3006
|
+
return;
|
|
3007
|
+
}
|
|
3008
|
+
window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3009
|
+
} catch {
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
function readSavedDraftPreview(storageKey) {
|
|
3013
|
+
if (typeof window === "undefined") return null;
|
|
3014
|
+
try {
|
|
3015
|
+
const raw = window.sessionStorage.getItem(storageKey);
|
|
3016
|
+
if (!raw) return null;
|
|
3017
|
+
const parsed = JSON.parse(raw);
|
|
3018
|
+
if (!parsed || typeof parsed.id !== "string") return null;
|
|
3019
|
+
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
3020
|
+
return {
|
|
3021
|
+
id: parsed.id,
|
|
3022
|
+
experienceType: parsed.experienceType
|
|
3023
|
+
};
|
|
3024
|
+
} catch {
|
|
3025
|
+
return null;
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
function readSuppressedDraftPreview() {
|
|
3029
|
+
return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3030
|
+
}
|
|
3031
|
+
function persistSuppressedDraftPreview(draft) {
|
|
3032
|
+
if (typeof window === "undefined") return;
|
|
3033
|
+
try {
|
|
3034
|
+
window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
3035
|
+
} catch {
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
function clearSuppressedDraftPreview(draft) {
|
|
3039
|
+
if (typeof window === "undefined") return;
|
|
3040
|
+
try {
|
|
3041
|
+
const suppressedDraft = readSuppressedDraftPreview();
|
|
3042
|
+
if (draft && suppressedDraft) {
|
|
3043
|
+
if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
|
|
3044
|
+
return;
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3048
|
+
} catch {
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
function isSuppressedDraftPreview(draft) {
|
|
3052
|
+
const suppressedDraft = readSuppressedDraftPreview();
|
|
3053
|
+
return Boolean(
|
|
3054
|
+
suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
|
|
3055
|
+
);
|
|
3056
|
+
}
|
|
3057
|
+
function persistPreviewSessionSuppression() {
|
|
3058
|
+
if (typeof window === "undefined") return;
|
|
3059
|
+
try {
|
|
3060
|
+
window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
|
|
3061
|
+
} catch {
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
function readPreviewSessionSuppression() {
|
|
3065
|
+
if (typeof window === "undefined") return false;
|
|
3066
|
+
try {
|
|
3067
|
+
return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
|
|
3068
|
+
} catch {
|
|
3069
|
+
return false;
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
|
|
2921
3073
|
// src/hooks/useRunCommand.ts
|
|
2922
3074
|
var import_react9 = require("react");
|
|
2923
3075
|
function searchTaggedElementsForQuery(store, query, limit = 8) {
|
|
@@ -3053,120 +3205,6 @@ var import_react_dom = require("react-dom");
|
|
|
3053
3205
|
// src/hooks/useExperiencePlaybackController.ts
|
|
3054
3206
|
var import_react13 = require("react");
|
|
3055
3207
|
|
|
3056
|
-
// src/utils/draftPreview.ts
|
|
3057
|
-
var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
|
|
3058
|
-
var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
|
|
3059
|
-
var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
|
|
3060
|
-
function getPreviewQueryParamName(experienceType) {
|
|
3061
|
-
return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
|
|
3062
|
-
}
|
|
3063
|
-
function buildDraftPreviewUrl(currentUrl, draft) {
|
|
3064
|
-
const url = new URL(currentUrl);
|
|
3065
|
-
url.searchParams.delete("modelnex_test_tour");
|
|
3066
|
-
url.searchParams.delete("modelnex_test_onboarding");
|
|
3067
|
-
url.searchParams.delete("modelnex_test_workflow");
|
|
3068
|
-
url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
|
|
3069
|
-
return url.toString();
|
|
3070
|
-
}
|
|
3071
|
-
function shouldPromptForPreviewStart(notificationType, _source) {
|
|
3072
|
-
const normalizedNotificationType = notificationType ?? "bubble_card";
|
|
3073
|
-
return normalizedNotificationType === "modal";
|
|
3074
|
-
}
|
|
3075
|
-
function persistActiveDraftPreview(draft) {
|
|
3076
|
-
if (typeof window === "undefined") return;
|
|
3077
|
-
try {
|
|
3078
|
-
window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
3079
|
-
} catch {
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3082
|
-
function readActiveDraftPreview() {
|
|
3083
|
-
if (typeof window === "undefined") return null;
|
|
3084
|
-
try {
|
|
3085
|
-
const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3086
|
-
if (!raw) return null;
|
|
3087
|
-
const parsed = JSON.parse(raw);
|
|
3088
|
-
if (!parsed || typeof parsed.id !== "string") return null;
|
|
3089
|
-
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
3090
|
-
return {
|
|
3091
|
-
id: parsed.id,
|
|
3092
|
-
experienceType: parsed.experienceType
|
|
3093
|
-
};
|
|
3094
|
-
} catch {
|
|
3095
|
-
return null;
|
|
3096
|
-
}
|
|
3097
|
-
}
|
|
3098
|
-
function clearActiveDraftPreview(experienceType) {
|
|
3099
|
-
if (typeof window === "undefined") return;
|
|
3100
|
-
try {
|
|
3101
|
-
const activePreview = readActiveDraftPreview();
|
|
3102
|
-
if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
|
|
3103
|
-
return;
|
|
3104
|
-
}
|
|
3105
|
-
window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3106
|
-
} catch {
|
|
3107
|
-
}
|
|
3108
|
-
}
|
|
3109
|
-
function readSavedDraftPreview(storageKey) {
|
|
3110
|
-
if (typeof window === "undefined") return null;
|
|
3111
|
-
try {
|
|
3112
|
-
const raw = window.sessionStorage.getItem(storageKey);
|
|
3113
|
-
if (!raw) return null;
|
|
3114
|
-
const parsed = JSON.parse(raw);
|
|
3115
|
-
if (!parsed || typeof parsed.id !== "string") return null;
|
|
3116
|
-
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
3117
|
-
return {
|
|
3118
|
-
id: parsed.id,
|
|
3119
|
-
experienceType: parsed.experienceType
|
|
3120
|
-
};
|
|
3121
|
-
} catch {
|
|
3122
|
-
return null;
|
|
3123
|
-
}
|
|
3124
|
-
}
|
|
3125
|
-
function readSuppressedDraftPreview() {
|
|
3126
|
-
return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3127
|
-
}
|
|
3128
|
-
function persistSuppressedDraftPreview(draft) {
|
|
3129
|
-
if (typeof window === "undefined") return;
|
|
3130
|
-
try {
|
|
3131
|
-
window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
3132
|
-
} catch {
|
|
3133
|
-
}
|
|
3134
|
-
}
|
|
3135
|
-
function clearSuppressedDraftPreview(draft) {
|
|
3136
|
-
if (typeof window === "undefined") return;
|
|
3137
|
-
try {
|
|
3138
|
-
const suppressedDraft = readSuppressedDraftPreview();
|
|
3139
|
-
if (draft && suppressedDraft) {
|
|
3140
|
-
if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
|
|
3141
|
-
return;
|
|
3142
|
-
}
|
|
3143
|
-
}
|
|
3144
|
-
window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
3145
|
-
} catch {
|
|
3146
|
-
}
|
|
3147
|
-
}
|
|
3148
|
-
function isSuppressedDraftPreview(draft) {
|
|
3149
|
-
const suppressedDraft = readSuppressedDraftPreview();
|
|
3150
|
-
return Boolean(
|
|
3151
|
-
suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
|
|
3152
|
-
);
|
|
3153
|
-
}
|
|
3154
|
-
function persistPreviewSessionSuppression() {
|
|
3155
|
-
if (typeof window === "undefined") return;
|
|
3156
|
-
try {
|
|
3157
|
-
window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
|
|
3158
|
-
} catch {
|
|
3159
|
-
}
|
|
3160
|
-
}
|
|
3161
|
-
function readPreviewSessionSuppression() {
|
|
3162
|
-
if (typeof window === "undefined") return false;
|
|
3163
|
-
try {
|
|
3164
|
-
return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
|
|
3165
|
-
} catch {
|
|
3166
|
-
return false;
|
|
3167
|
-
}
|
|
3168
|
-
}
|
|
3169
|
-
|
|
3170
3208
|
// src/utils/locationSignature.ts
|
|
3171
3209
|
function getLocationSignature(locationLike) {
|
|
3172
3210
|
if (!locationLike) return "";
|
|
@@ -3267,6 +3305,43 @@ function createTourSocketPool({
|
|
|
3267
3305
|
}
|
|
3268
3306
|
var tourSocketPool = createTourSocketPool();
|
|
3269
3307
|
|
|
3308
|
+
// src/utils/tourTransport.ts
|
|
3309
|
+
function compactCaptureEventForTransport(event) {
|
|
3310
|
+
return {
|
|
3311
|
+
id: event.id,
|
|
3312
|
+
type: event.type,
|
|
3313
|
+
order: event.order,
|
|
3314
|
+
timestamp: event.timestamp,
|
|
3315
|
+
url: event.url,
|
|
3316
|
+
label: event.label,
|
|
3317
|
+
tagName: event.tagName,
|
|
3318
|
+
testId: event.testId,
|
|
3319
|
+
fingerprint: event.fingerprint,
|
|
3320
|
+
textContaining: event.textContaining,
|
|
3321
|
+
fieldType: event.fieldType,
|
|
3322
|
+
valueSample: event.valueSample,
|
|
3323
|
+
note: event.note,
|
|
3324
|
+
stepTypeHint: event.stepTypeHint
|
|
3325
|
+
};
|
|
3326
|
+
}
|
|
3327
|
+
function compactTourForTransport(tour) {
|
|
3328
|
+
const capture = tour.capture;
|
|
3329
|
+
if (!capture || typeof capture !== "object") {
|
|
3330
|
+
return tour;
|
|
3331
|
+
}
|
|
3332
|
+
return {
|
|
3333
|
+
...tour,
|
|
3334
|
+
capture: {
|
|
3335
|
+
...capture.experienceType ? { experienceType: capture.experienceType } : {},
|
|
3336
|
+
...capture.onboardingHints ? { onboardingHints: capture.onboardingHints } : {},
|
|
3337
|
+
...capture.generation ? { generation: capture.generation } : {},
|
|
3338
|
+
...Array.isArray(capture.events) ? {
|
|
3339
|
+
events: capture.events.map((event) => compactCaptureEventForTransport(event))
|
|
3340
|
+
} : {}
|
|
3341
|
+
}
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3270
3345
|
// src/utils/tour-playback-guards.ts
|
|
3271
3346
|
var playbackOwners = /* @__PURE__ */ new Map();
|
|
3272
3347
|
function shouldExecuteTourCommandBatch(isPlaybackActive) {
|
|
@@ -4783,7 +4858,7 @@ function useTourPlayback({
|
|
|
4783
4858
|
emitSocketEvent(socketRef.current, "tour:request_start", {
|
|
4784
4859
|
tourId: tour.id,
|
|
4785
4860
|
previewRunId: previewRunIdRef.current,
|
|
4786
|
-
tourContext: tour
|
|
4861
|
+
tourContext: compactTourForTransport(tour)
|
|
4787
4862
|
});
|
|
4788
4863
|
}, [serverUrl, websiteId]);
|
|
4789
4864
|
(0, import_react12.useEffect)(() => {
|
|
@@ -9450,6 +9525,7 @@ function ModelNexChatBubble({
|
|
|
9450
9525
|
const setRecordingMode = ctx?.setRecordingMode ?? (() => {
|
|
9451
9526
|
});
|
|
9452
9527
|
const devMode = ctx?.devMode ?? false;
|
|
9528
|
+
const authoringMode = ctx?.authoringMode ?? devMode;
|
|
9453
9529
|
const [recordingTourName, setRecordingTourName] = (0, import_react18.useState)("");
|
|
9454
9530
|
const [recordingTargetTypes, setRecordingTargetTypes] = (0, import_react18.useState)("admin");
|
|
9455
9531
|
const [showStopModal, setShowStopModal] = (0, import_react18.useState)(false);
|
|
@@ -9578,11 +9654,11 @@ function ModelNexChatBubble({
|
|
|
9578
9654
|
}
|
|
9579
9655
|
}, [ctx]);
|
|
9580
9656
|
(0, import_react18.useEffect)(() => {
|
|
9581
|
-
if (
|
|
9657
|
+
if (authoringMode && ctx?.extractedElements.length) {
|
|
9582
9658
|
const timer = setTimeout(handleAutoTag, 1e3);
|
|
9583
9659
|
return () => clearTimeout(timer);
|
|
9584
9660
|
}
|
|
9585
|
-
}, [
|
|
9661
|
+
}, [authoringMode, handleAutoTag, ctx?.extractedElements.length, window.location.pathname]);
|
|
9586
9662
|
const onboardingReviewToggle = getReviewModeToggleConfig(onboardingPlayback.playbackState);
|
|
9587
9663
|
const pendingPrompt = playbackController.pendingPrompt;
|
|
9588
9664
|
const pendingNotificationType = (onboardingPlayback.pendingTour || tourPlayback.pendingTour)?.notificationType ?? "bubble_card";
|
|
@@ -9943,7 +10019,7 @@ function ModelNexChatBubble({
|
|
|
9943
10019
|
content: summary || fallbackContent,
|
|
9944
10020
|
summary: summary ?? void 0,
|
|
9945
10021
|
nextSteps: nextSteps ?? void 0,
|
|
9946
|
-
debug:
|
|
10022
|
+
debug: authoringMode ? data?.debug ?? void 0 : void 0
|
|
9947
10023
|
}
|
|
9948
10024
|
]);
|
|
9949
10025
|
} catch (err) {
|
|
@@ -10231,7 +10307,7 @@ function ModelNexChatBubble({
|
|
|
10231
10307
|
children: voice.isMuted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VolumeMuteIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VolumeIcon, {})
|
|
10232
10308
|
}
|
|
10233
10309
|
) }),
|
|
10234
|
-
|
|
10310
|
+
authoringMode && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", background: "var(--modelnex-bg-secondary, #f4f4f5)", borderRadius: "12px", padding: "2px", gap: "2px", marginRight: "4px" }, children: (!recordingMode || activeRecordingExperienceType === "onboarding") && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tooltip, { title: recordingMode ? "Stop & Save Workflow" : "Record Workflow", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
10235
10311
|
"button",
|
|
10236
10312
|
{
|
|
10237
10313
|
onClick: () => {
|
|
@@ -10987,7 +11063,7 @@ function ModelNexChatBubble({
|
|
|
10987
11063
|
)
|
|
10988
11064
|
}
|
|
10989
11065
|
),
|
|
10990
|
-
msg.role === "assistant" &&
|
|
11066
|
+
msg.role === "assistant" && authoringMode && msg.debug && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentTraces, { debug: msg.debug, command: messages[i - 1]?.content ?? "" })
|
|
10991
11067
|
] }, i)),
|
|
10992
11068
|
loading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
10993
11069
|
"div",
|
|
@@ -11988,7 +12064,9 @@ var ModelNexProvider = ({
|
|
|
11988
12064
|
const [actions, setActions] = (0, import_react21.useState)(/* @__PURE__ */ new Map());
|
|
11989
12065
|
const [validatedBrowserDevMode, setValidatedBrowserDevMode] = (0, import_react21.useState)(false);
|
|
11990
12066
|
const [resolvedDevModeKey, setResolvedDevModeKey] = (0, import_react21.useState)(() => resolveInjectedDevModeKey());
|
|
12067
|
+
const [previewRuntimeMode, setPreviewRuntimeMode] = (0, import_react21.useState)(() => hasDraftPreviewModeSignal());
|
|
11991
12068
|
(0, import_react21.useEffect)(() => observeInjectedDevModeKey(setResolvedDevModeKey), []);
|
|
12069
|
+
(0, import_react21.useEffect)(() => observeDraftPreviewModeSignal(setPreviewRuntimeMode), []);
|
|
11992
12070
|
(0, import_react21.useEffect)(() => {
|
|
11993
12071
|
let cancelled = false;
|
|
11994
12072
|
if (!websiteId || !resolvedDevModeKey) {
|
|
@@ -12005,7 +12083,7 @@ var ModelNexProvider = ({
|
|
|
12005
12083
|
cancelled = true;
|
|
12006
12084
|
};
|
|
12007
12085
|
}, [resolvedDevModeKey, serverUrl, websiteId]);
|
|
12008
|
-
const effectiveDevMode = validatedBrowserDevMode;
|
|
12086
|
+
const effectiveDevMode = validatedBrowserDevMode || previewRuntimeMode;
|
|
12009
12087
|
const registerAction = (0, import_react21.useCallback)((action) => {
|
|
12010
12088
|
setActions((prev) => {
|
|
12011
12089
|
const next = new Map(prev);
|
|
@@ -12102,9 +12180,10 @@ var ModelNexProvider = ({
|
|
|
12102
12180
|
voiceMuted,
|
|
12103
12181
|
setVoiceMuted,
|
|
12104
12182
|
socketId,
|
|
12105
|
-
devMode: effectiveDevMode
|
|
12183
|
+
devMode: effectiveDevMode,
|
|
12184
|
+
authoringMode: validatedBrowserDevMode
|
|
12106
12185
|
}),
|
|
12107
|
-
[serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode]
|
|
12186
|
+
[serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode, validatedBrowserDevMode]
|
|
12108
12187
|
);
|
|
12109
12188
|
return import_react21.default.createElement(
|
|
12110
12189
|
ModelNexContext.Provider,
|
|
@@ -12135,11 +12214,13 @@ var ModelNexProvider = ({
|
|
|
12135
12214
|
getPreviewQueryParamName,
|
|
12136
12215
|
getRecordingDraftActionLabel,
|
|
12137
12216
|
getRecordingDraftStatusMessage,
|
|
12217
|
+
hasDraftPreviewModeSignal,
|
|
12138
12218
|
inferOnboardingMetadataForStep,
|
|
12139
12219
|
isAskDrivenInputStepType,
|
|
12140
12220
|
isInteractiveInputStepType,
|
|
12141
12221
|
isManualOnboardingStep,
|
|
12142
12222
|
isRecordingDraftGenerating,
|
|
12223
|
+
observeDraftPreviewModeSignal,
|
|
12143
12224
|
persistActiveDraftPreview,
|
|
12144
12225
|
readActiveDraftPreview,
|
|
12145
12226
|
shouldPromptForPreviewStart,
|
package/dist/index.mjs
CHANGED
|
@@ -709,10 +709,7 @@ function useModelNexSocket({
|
|
|
709
709
|
contexts: serializeContexts(contextsRef.current),
|
|
710
710
|
documentation: documentationRef.current ?? void 0,
|
|
711
711
|
domSummary: captureDomSummary(tagsRef.current),
|
|
712
|
-
websiteId
|
|
713
|
-
// All tagged elements across every page — not just what's visible now.
|
|
714
|
-
// The server uses this to pre-search relevant elements for each user query.
|
|
715
|
-
allTaggedElements: tagsRef.current ? Array.from(tagsRef.current.values()) : void 0
|
|
712
|
+
websiteId
|
|
716
713
|
});
|
|
717
714
|
socket.on("connect", () => {
|
|
718
715
|
emitSdkDebugLog("[ModelNex SDK] Connected to agent server", {
|
|
@@ -2709,6 +2706,159 @@ function clearPersistedRecordingSession() {
|
|
|
2709
2706
|
}
|
|
2710
2707
|
}
|
|
2711
2708
|
|
|
2709
|
+
// src/utils/draftPreview.ts
|
|
2710
|
+
var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
|
|
2711
|
+
var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
|
|
2712
|
+
var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
|
|
2713
|
+
function getPreviewQueryParamName(experienceType) {
|
|
2714
|
+
return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
|
|
2715
|
+
}
|
|
2716
|
+
function buildDraftPreviewUrl(currentUrl, draft) {
|
|
2717
|
+
const url = new URL(currentUrl);
|
|
2718
|
+
url.searchParams.delete("modelnex_test_tour");
|
|
2719
|
+
url.searchParams.delete("modelnex_test_onboarding");
|
|
2720
|
+
url.searchParams.delete("modelnex_test_workflow");
|
|
2721
|
+
url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
|
|
2722
|
+
return url.toString();
|
|
2723
|
+
}
|
|
2724
|
+
function shouldPromptForPreviewStart(notificationType, _source) {
|
|
2725
|
+
const normalizedNotificationType = notificationType ?? "bubble_card";
|
|
2726
|
+
return normalizedNotificationType === "modal";
|
|
2727
|
+
}
|
|
2728
|
+
function hasDraftPreviewModeSignal() {
|
|
2729
|
+
if (typeof window === "undefined") return false;
|
|
2730
|
+
try {
|
|
2731
|
+
const params = new URLSearchParams(window.location.search);
|
|
2732
|
+
if (params.has("modelnex_test_tour") || params.has("modelnex_test_workflow") || params.has("modelnex_test_onboarding")) {
|
|
2733
|
+
return true;
|
|
2734
|
+
}
|
|
2735
|
+
} catch {
|
|
2736
|
+
}
|
|
2737
|
+
return readActiveDraftPreview() !== null;
|
|
2738
|
+
}
|
|
2739
|
+
function observeDraftPreviewModeSignal(listener, options) {
|
|
2740
|
+
if (typeof window === "undefined") return () => {
|
|
2741
|
+
};
|
|
2742
|
+
let currentValue = hasDraftPreviewModeSignal();
|
|
2743
|
+
const pollIntervalMs = options?.pollIntervalMs ?? 500;
|
|
2744
|
+
const syncPreviewModeSignal = () => {
|
|
2745
|
+
const nextValue = hasDraftPreviewModeSignal();
|
|
2746
|
+
if (nextValue === currentValue) return;
|
|
2747
|
+
currentValue = nextValue;
|
|
2748
|
+
listener(nextValue);
|
|
2749
|
+
};
|
|
2750
|
+
const intervalId = window.setInterval(syncPreviewModeSignal, pollIntervalMs);
|
|
2751
|
+
window.addEventListener("focus", syncPreviewModeSignal);
|
|
2752
|
+
window.addEventListener("pageshow", syncPreviewModeSignal);
|
|
2753
|
+
window.addEventListener("popstate", syncPreviewModeSignal);
|
|
2754
|
+
if (typeof document !== "undefined") {
|
|
2755
|
+
document.addEventListener("visibilitychange", syncPreviewModeSignal);
|
|
2756
|
+
}
|
|
2757
|
+
return () => {
|
|
2758
|
+
window.clearInterval(intervalId);
|
|
2759
|
+
window.removeEventListener("focus", syncPreviewModeSignal);
|
|
2760
|
+
window.removeEventListener("pageshow", syncPreviewModeSignal);
|
|
2761
|
+
window.removeEventListener("popstate", syncPreviewModeSignal);
|
|
2762
|
+
if (typeof document !== "undefined") {
|
|
2763
|
+
document.removeEventListener("visibilitychange", syncPreviewModeSignal);
|
|
2764
|
+
}
|
|
2765
|
+
};
|
|
2766
|
+
}
|
|
2767
|
+
function persistActiveDraftPreview(draft) {
|
|
2768
|
+
if (typeof window === "undefined") return;
|
|
2769
|
+
try {
|
|
2770
|
+
window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
2771
|
+
} catch {
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
function readActiveDraftPreview() {
|
|
2775
|
+
if (typeof window === "undefined") return null;
|
|
2776
|
+
try {
|
|
2777
|
+
const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2778
|
+
if (!raw) return null;
|
|
2779
|
+
const parsed = JSON.parse(raw);
|
|
2780
|
+
if (!parsed || typeof parsed.id !== "string") return null;
|
|
2781
|
+
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
2782
|
+
return {
|
|
2783
|
+
id: parsed.id,
|
|
2784
|
+
experienceType: parsed.experienceType
|
|
2785
|
+
};
|
|
2786
|
+
} catch {
|
|
2787
|
+
return null;
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
function clearActiveDraftPreview(experienceType) {
|
|
2791
|
+
if (typeof window === "undefined") return;
|
|
2792
|
+
try {
|
|
2793
|
+
const activePreview = readActiveDraftPreview();
|
|
2794
|
+
if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2798
|
+
} catch {
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
function readSavedDraftPreview(storageKey) {
|
|
2802
|
+
if (typeof window === "undefined") return null;
|
|
2803
|
+
try {
|
|
2804
|
+
const raw = window.sessionStorage.getItem(storageKey);
|
|
2805
|
+
if (!raw) return null;
|
|
2806
|
+
const parsed = JSON.parse(raw);
|
|
2807
|
+
if (!parsed || typeof parsed.id !== "string") return null;
|
|
2808
|
+
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
2809
|
+
return {
|
|
2810
|
+
id: parsed.id,
|
|
2811
|
+
experienceType: parsed.experienceType
|
|
2812
|
+
};
|
|
2813
|
+
} catch {
|
|
2814
|
+
return null;
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
function readSuppressedDraftPreview() {
|
|
2818
|
+
return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2819
|
+
}
|
|
2820
|
+
function persistSuppressedDraftPreview(draft) {
|
|
2821
|
+
if (typeof window === "undefined") return;
|
|
2822
|
+
try {
|
|
2823
|
+
window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
2824
|
+
} catch {
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
function clearSuppressedDraftPreview(draft) {
|
|
2828
|
+
if (typeof window === "undefined") return;
|
|
2829
|
+
try {
|
|
2830
|
+
const suppressedDraft = readSuppressedDraftPreview();
|
|
2831
|
+
if (draft && suppressedDraft) {
|
|
2832
|
+
if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
|
|
2833
|
+
return;
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2837
|
+
} catch {
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2840
|
+
function isSuppressedDraftPreview(draft) {
|
|
2841
|
+
const suppressedDraft = readSuppressedDraftPreview();
|
|
2842
|
+
return Boolean(
|
|
2843
|
+
suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
|
|
2844
|
+
);
|
|
2845
|
+
}
|
|
2846
|
+
function persistPreviewSessionSuppression() {
|
|
2847
|
+
if (typeof window === "undefined") return;
|
|
2848
|
+
try {
|
|
2849
|
+
window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
|
|
2850
|
+
} catch {
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
function readPreviewSessionSuppression() {
|
|
2854
|
+
if (typeof window === "undefined") return false;
|
|
2855
|
+
try {
|
|
2856
|
+
return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
|
|
2857
|
+
} catch {
|
|
2858
|
+
return false;
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
|
|
2712
2862
|
// src/hooks/useRunCommand.ts
|
|
2713
2863
|
import { useCallback as useCallback5, useContext as useContext2 } from "react";
|
|
2714
2864
|
function searchTaggedElementsForQuery(store, query, limit = 8) {
|
|
@@ -2844,120 +2994,6 @@ import { createPortal, flushSync } from "react-dom";
|
|
|
2844
2994
|
// src/hooks/useExperiencePlaybackController.ts
|
|
2845
2995
|
import { useCallback as useCallback8, useEffect as useEffect12, useRef as useRef9, useState as useState8 } from "react";
|
|
2846
2996
|
|
|
2847
|
-
// src/utils/draftPreview.ts
|
|
2848
|
-
var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
|
|
2849
|
-
var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
|
|
2850
|
-
var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
|
|
2851
|
-
function getPreviewQueryParamName(experienceType) {
|
|
2852
|
-
return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
|
|
2853
|
-
}
|
|
2854
|
-
function buildDraftPreviewUrl(currentUrl, draft) {
|
|
2855
|
-
const url = new URL(currentUrl);
|
|
2856
|
-
url.searchParams.delete("modelnex_test_tour");
|
|
2857
|
-
url.searchParams.delete("modelnex_test_onboarding");
|
|
2858
|
-
url.searchParams.delete("modelnex_test_workflow");
|
|
2859
|
-
url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
|
|
2860
|
-
return url.toString();
|
|
2861
|
-
}
|
|
2862
|
-
function shouldPromptForPreviewStart(notificationType, _source) {
|
|
2863
|
-
const normalizedNotificationType = notificationType ?? "bubble_card";
|
|
2864
|
-
return normalizedNotificationType === "modal";
|
|
2865
|
-
}
|
|
2866
|
-
function persistActiveDraftPreview(draft) {
|
|
2867
|
-
if (typeof window === "undefined") return;
|
|
2868
|
-
try {
|
|
2869
|
-
window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
2870
|
-
} catch {
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
function readActiveDraftPreview() {
|
|
2874
|
-
if (typeof window === "undefined") return null;
|
|
2875
|
-
try {
|
|
2876
|
-
const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2877
|
-
if (!raw) return null;
|
|
2878
|
-
const parsed = JSON.parse(raw);
|
|
2879
|
-
if (!parsed || typeof parsed.id !== "string") return null;
|
|
2880
|
-
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
2881
|
-
return {
|
|
2882
|
-
id: parsed.id,
|
|
2883
|
-
experienceType: parsed.experienceType
|
|
2884
|
-
};
|
|
2885
|
-
} catch {
|
|
2886
|
-
return null;
|
|
2887
|
-
}
|
|
2888
|
-
}
|
|
2889
|
-
function clearActiveDraftPreview(experienceType) {
|
|
2890
|
-
if (typeof window === "undefined") return;
|
|
2891
|
-
try {
|
|
2892
|
-
const activePreview = readActiveDraftPreview();
|
|
2893
|
-
if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
|
|
2894
|
-
return;
|
|
2895
|
-
}
|
|
2896
|
-
window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2897
|
-
} catch {
|
|
2898
|
-
}
|
|
2899
|
-
}
|
|
2900
|
-
function readSavedDraftPreview(storageKey) {
|
|
2901
|
-
if (typeof window === "undefined") return null;
|
|
2902
|
-
try {
|
|
2903
|
-
const raw = window.sessionStorage.getItem(storageKey);
|
|
2904
|
-
if (!raw) return null;
|
|
2905
|
-
const parsed = JSON.parse(raw);
|
|
2906
|
-
if (!parsed || typeof parsed.id !== "string") return null;
|
|
2907
|
-
if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
|
|
2908
|
-
return {
|
|
2909
|
-
id: parsed.id,
|
|
2910
|
-
experienceType: parsed.experienceType
|
|
2911
|
-
};
|
|
2912
|
-
} catch {
|
|
2913
|
-
return null;
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
function readSuppressedDraftPreview() {
|
|
2917
|
-
return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2918
|
-
}
|
|
2919
|
-
function persistSuppressedDraftPreview(draft) {
|
|
2920
|
-
if (typeof window === "undefined") return;
|
|
2921
|
-
try {
|
|
2922
|
-
window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
|
|
2923
|
-
} catch {
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
function clearSuppressedDraftPreview(draft) {
|
|
2927
|
-
if (typeof window === "undefined") return;
|
|
2928
|
-
try {
|
|
2929
|
-
const suppressedDraft = readSuppressedDraftPreview();
|
|
2930
|
-
if (draft && suppressedDraft) {
|
|
2931
|
-
if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
|
|
2932
|
-
return;
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
|
-
window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
|
|
2936
|
-
} catch {
|
|
2937
|
-
}
|
|
2938
|
-
}
|
|
2939
|
-
function isSuppressedDraftPreview(draft) {
|
|
2940
|
-
const suppressedDraft = readSuppressedDraftPreview();
|
|
2941
|
-
return Boolean(
|
|
2942
|
-
suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
|
|
2943
|
-
);
|
|
2944
|
-
}
|
|
2945
|
-
function persistPreviewSessionSuppression() {
|
|
2946
|
-
if (typeof window === "undefined") return;
|
|
2947
|
-
try {
|
|
2948
|
-
window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
|
|
2949
|
-
} catch {
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
function readPreviewSessionSuppression() {
|
|
2953
|
-
if (typeof window === "undefined") return false;
|
|
2954
|
-
try {
|
|
2955
|
-
return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
|
|
2956
|
-
} catch {
|
|
2957
|
-
return false;
|
|
2958
|
-
}
|
|
2959
|
-
}
|
|
2960
|
-
|
|
2961
2997
|
// src/utils/locationSignature.ts
|
|
2962
2998
|
function getLocationSignature(locationLike) {
|
|
2963
2999
|
if (!locationLike) return "";
|
|
@@ -3058,6 +3094,43 @@ function createTourSocketPool({
|
|
|
3058
3094
|
}
|
|
3059
3095
|
var tourSocketPool = createTourSocketPool();
|
|
3060
3096
|
|
|
3097
|
+
// src/utils/tourTransport.ts
|
|
3098
|
+
function compactCaptureEventForTransport(event) {
|
|
3099
|
+
return {
|
|
3100
|
+
id: event.id,
|
|
3101
|
+
type: event.type,
|
|
3102
|
+
order: event.order,
|
|
3103
|
+
timestamp: event.timestamp,
|
|
3104
|
+
url: event.url,
|
|
3105
|
+
label: event.label,
|
|
3106
|
+
tagName: event.tagName,
|
|
3107
|
+
testId: event.testId,
|
|
3108
|
+
fingerprint: event.fingerprint,
|
|
3109
|
+
textContaining: event.textContaining,
|
|
3110
|
+
fieldType: event.fieldType,
|
|
3111
|
+
valueSample: event.valueSample,
|
|
3112
|
+
note: event.note,
|
|
3113
|
+
stepTypeHint: event.stepTypeHint
|
|
3114
|
+
};
|
|
3115
|
+
}
|
|
3116
|
+
function compactTourForTransport(tour) {
|
|
3117
|
+
const capture = tour.capture;
|
|
3118
|
+
if (!capture || typeof capture !== "object") {
|
|
3119
|
+
return tour;
|
|
3120
|
+
}
|
|
3121
|
+
return {
|
|
3122
|
+
...tour,
|
|
3123
|
+
capture: {
|
|
3124
|
+
...capture.experienceType ? { experienceType: capture.experienceType } : {},
|
|
3125
|
+
...capture.onboardingHints ? { onboardingHints: capture.onboardingHints } : {},
|
|
3126
|
+
...capture.generation ? { generation: capture.generation } : {},
|
|
3127
|
+
...Array.isArray(capture.events) ? {
|
|
3128
|
+
events: capture.events.map((event) => compactCaptureEventForTransport(event))
|
|
3129
|
+
} : {}
|
|
3130
|
+
}
|
|
3131
|
+
};
|
|
3132
|
+
}
|
|
3133
|
+
|
|
3061
3134
|
// src/utils/tour-playback-guards.ts
|
|
3062
3135
|
var playbackOwners = /* @__PURE__ */ new Map();
|
|
3063
3136
|
function shouldExecuteTourCommandBatch(isPlaybackActive) {
|
|
@@ -4574,7 +4647,7 @@ function useTourPlayback({
|
|
|
4574
4647
|
emitSocketEvent(socketRef.current, "tour:request_start", {
|
|
4575
4648
|
tourId: tour.id,
|
|
4576
4649
|
previewRunId: previewRunIdRef.current,
|
|
4577
|
-
tourContext: tour
|
|
4650
|
+
tourContext: compactTourForTransport(tour)
|
|
4578
4651
|
});
|
|
4579
4652
|
}, [serverUrl, websiteId]);
|
|
4580
4653
|
useEffect11(() => {
|
|
@@ -9240,6 +9313,7 @@ function ModelNexChatBubble({
|
|
|
9240
9313
|
const setRecordingMode = ctx?.setRecordingMode ?? (() => {
|
|
9241
9314
|
});
|
|
9242
9315
|
const devMode = ctx?.devMode ?? false;
|
|
9316
|
+
const authoringMode = ctx?.authoringMode ?? devMode;
|
|
9243
9317
|
const [recordingTourName, setRecordingTourName] = useState13("");
|
|
9244
9318
|
const [recordingTargetTypes, setRecordingTargetTypes] = useState13("admin");
|
|
9245
9319
|
const [showStopModal, setShowStopModal] = useState13(false);
|
|
@@ -9368,11 +9442,11 @@ function ModelNexChatBubble({
|
|
|
9368
9442
|
}
|
|
9369
9443
|
}, [ctx]);
|
|
9370
9444
|
useEffect17(() => {
|
|
9371
|
-
if (
|
|
9445
|
+
if (authoringMode && ctx?.extractedElements.length) {
|
|
9372
9446
|
const timer = setTimeout(handleAutoTag, 1e3);
|
|
9373
9447
|
return () => clearTimeout(timer);
|
|
9374
9448
|
}
|
|
9375
|
-
}, [
|
|
9449
|
+
}, [authoringMode, handleAutoTag, ctx?.extractedElements.length, window.location.pathname]);
|
|
9376
9450
|
const onboardingReviewToggle = getReviewModeToggleConfig(onboardingPlayback.playbackState);
|
|
9377
9451
|
const pendingPrompt = playbackController.pendingPrompt;
|
|
9378
9452
|
const pendingNotificationType = (onboardingPlayback.pendingTour || tourPlayback.pendingTour)?.notificationType ?? "bubble_card";
|
|
@@ -9733,7 +9807,7 @@ function ModelNexChatBubble({
|
|
|
9733
9807
|
content: summary || fallbackContent,
|
|
9734
9808
|
summary: summary ?? void 0,
|
|
9735
9809
|
nextSteps: nextSteps ?? void 0,
|
|
9736
|
-
debug:
|
|
9810
|
+
debug: authoringMode ? data?.debug ?? void 0 : void 0
|
|
9737
9811
|
}
|
|
9738
9812
|
]);
|
|
9739
9813
|
} catch (err) {
|
|
@@ -10021,7 +10095,7 @@ function ModelNexChatBubble({
|
|
|
10021
10095
|
children: voice.isMuted ? /* @__PURE__ */ jsx4(VolumeMuteIcon, {}) : /* @__PURE__ */ jsx4(VolumeIcon, {})
|
|
10022
10096
|
}
|
|
10023
10097
|
) }),
|
|
10024
|
-
|
|
10098
|
+
authoringMode && /* @__PURE__ */ jsx4("div", { style: { display: "flex", background: "var(--modelnex-bg-secondary, #f4f4f5)", borderRadius: "12px", padding: "2px", gap: "2px", marginRight: "4px" }, children: (!recordingMode || activeRecordingExperienceType === "onboarding") && /* @__PURE__ */ jsx4(Tooltip, { title: recordingMode ? "Stop & Save Workflow" : "Record Workflow", children: /* @__PURE__ */ jsx4(
|
|
10025
10099
|
"button",
|
|
10026
10100
|
{
|
|
10027
10101
|
onClick: () => {
|
|
@@ -10777,7 +10851,7 @@ function ModelNexChatBubble({
|
|
|
10777
10851
|
)
|
|
10778
10852
|
}
|
|
10779
10853
|
),
|
|
10780
|
-
msg.role === "assistant" &&
|
|
10854
|
+
msg.role === "assistant" && authoringMode && msg.debug && /* @__PURE__ */ jsx4(AgentTraces, { debug: msg.debug, command: messages[i - 1]?.content ?? "" })
|
|
10781
10855
|
] }, i)),
|
|
10782
10856
|
loading && /* @__PURE__ */ jsx4("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ jsxs3(
|
|
10783
10857
|
"div",
|
|
@@ -11778,7 +11852,9 @@ var ModelNexProvider = ({
|
|
|
11778
11852
|
const [actions, setActions] = useState15(/* @__PURE__ */ new Map());
|
|
11779
11853
|
const [validatedBrowserDevMode, setValidatedBrowserDevMode] = useState15(false);
|
|
11780
11854
|
const [resolvedDevModeKey, setResolvedDevModeKey] = useState15(() => resolveInjectedDevModeKey());
|
|
11855
|
+
const [previewRuntimeMode, setPreviewRuntimeMode] = useState15(() => hasDraftPreviewModeSignal());
|
|
11781
11856
|
useEffect19(() => observeInjectedDevModeKey(setResolvedDevModeKey), []);
|
|
11857
|
+
useEffect19(() => observeDraftPreviewModeSignal(setPreviewRuntimeMode), []);
|
|
11782
11858
|
useEffect19(() => {
|
|
11783
11859
|
let cancelled = false;
|
|
11784
11860
|
if (!websiteId || !resolvedDevModeKey) {
|
|
@@ -11795,7 +11871,7 @@ var ModelNexProvider = ({
|
|
|
11795
11871
|
cancelled = true;
|
|
11796
11872
|
};
|
|
11797
11873
|
}, [resolvedDevModeKey, serverUrl, websiteId]);
|
|
11798
|
-
const effectiveDevMode = validatedBrowserDevMode;
|
|
11874
|
+
const effectiveDevMode = validatedBrowserDevMode || previewRuntimeMode;
|
|
11799
11875
|
const registerAction = useCallback14((action) => {
|
|
11800
11876
|
setActions((prev) => {
|
|
11801
11877
|
const next = new Map(prev);
|
|
@@ -11892,9 +11968,10 @@ var ModelNexProvider = ({
|
|
|
11892
11968
|
voiceMuted,
|
|
11893
11969
|
setVoiceMuted,
|
|
11894
11970
|
socketId,
|
|
11895
|
-
devMode: effectiveDevMode
|
|
11971
|
+
devMode: effectiveDevMode,
|
|
11972
|
+
authoringMode: validatedBrowserDevMode
|
|
11896
11973
|
}),
|
|
11897
|
-
[serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode]
|
|
11974
|
+
[serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode, validatedBrowserDevMode]
|
|
11898
11975
|
);
|
|
11899
11976
|
return React8.createElement(
|
|
11900
11977
|
ModelNexContext.Provider,
|
|
@@ -11924,11 +12001,13 @@ export {
|
|
|
11924
12001
|
getPreviewQueryParamName,
|
|
11925
12002
|
getRecordingDraftActionLabel,
|
|
11926
12003
|
getRecordingDraftStatusMessage,
|
|
12004
|
+
hasDraftPreviewModeSignal,
|
|
11927
12005
|
inferOnboardingMetadataForStep,
|
|
11928
12006
|
isAskDrivenInputStepType,
|
|
11929
12007
|
isInteractiveInputStepType,
|
|
11930
12008
|
isManualOnboardingStep,
|
|
11931
12009
|
isRecordingDraftGenerating,
|
|
12010
|
+
observeDraftPreviewModeSignal,
|
|
11932
12011
|
persistActiveDraftPreview,
|
|
11933
12012
|
readActiveDraftPreview,
|
|
11934
12013
|
shouldPromptForPreviewStart,
|