@modelnex/sdk 0.1.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,10 +8,21 @@ React SDK for ModelNex agent chat, tours, and guided onboarding.
8
8
  npm install @modelnex/sdk react react-dom zod
9
9
  ```
10
10
 
11
+ ## Unit Tests
12
+
13
+ Run the SDK unit tests from the `sdk` package directory:
14
+
15
+ ```bash
16
+ cd sdk
17
+ npm test
18
+ ```
19
+
20
+ The SDK test script builds `dist/` first, then runs the unit tests.
21
+
11
22
  ## Quick Start
12
23
 
13
24
  ```tsx
14
- import { ModelNexProvider, ModelNexChatBubble, ModelNexOnboardingPanel } from '@modelnex/sdk';
25
+ import { ModelNexProvider, ModelNexChatBubble } from '@modelnex/sdk';
15
26
 
16
27
  export default function AppShell() {
17
28
  return (
@@ -28,7 +39,6 @@ export default function AppShell() {
28
39
  >
29
40
  <App />
30
41
  <ModelNexChatBubble appName="My Product" />
31
- <ModelNexOnboardingPanel appName="My Product" />
32
42
  </ModelNexProvider>
33
43
  );
34
44
  }
@@ -36,13 +46,32 @@ export default function AppShell() {
36
46
 
37
47
  `websiteId` identifies the integration. `userProfile` is used for tour/onboarding targeting and completion tracking. `tourFacts.features` is used for `feature_unlocked` experiences.
38
48
 
49
+ ## Tour Start Model
50
+
51
+ ModelNex currently supports these automatic trigger types:
52
+
53
+ - `first_visit`
54
+ - `feature_unlocked`
55
+ - `manual`
56
+
57
+ Each tour or onboarding flow can also configure:
58
+
59
+ - `startPolicy`: `immediate_start` | `prompt_only` | `manual_only`
60
+ - `notificationType`: `bubble_card` | `modal`
61
+
62
+ Current behavior:
63
+
64
+ - `prompt_only + bubble_card` shows an in-bubble prompt
65
+ - `prompt_only + modal` shows a centered modal
66
+ - `immediate_start` starts playback immediately
67
+ - `manual_only` never auto-surfaces
68
+
39
69
  ## Main Exports
40
70
 
41
71
  | Export | Purpose |
42
72
  |--------|---------|
43
73
  | `ModelNexProvider` | Root provider for server connection, chat state, dev tools, tours, and onboarding |
44
- | `ModelNexChatBubble` | General-purpose assistant UI plus recording/review tools |
45
- | `ModelNexOnboardingPanel` | Dedicated customer-facing UI for `type: 'onboarding'` flows |
74
+ | `ModelNexChatBubble` | Unified assistant UI for chat, voice tours, and guided onboarding |
46
75
  | `useRunCommand` | Run agent commands from custom UI |
47
76
  | `useRegisterAction` | Register app actions the agent can execute |
48
77
  | `useTourPlayback` | Low-level playback hook for tours and shared experience runtime |
@@ -0,0 +1,10 @@
1
+ import {
2
+ clearAOMMap,
3
+ generateMinifiedAOM,
4
+ getElementByUid
5
+ } from "./chunk-N65UEB6X.mjs";
6
+ export {
7
+ clearAOMMap,
8
+ generateMinifiedAOM,
9
+ getElementByUid
10
+ };
@@ -62,8 +62,9 @@ function clearAOMMap() {
62
62
  uidMap.clear();
63
63
  nextUid = 1;
64
64
  }
65
+
65
66
  export {
66
- clearAOMMap,
67
67
  generateMinifiedAOM,
68
- getElementByUid
68
+ getElementByUid,
69
+ clearAOMMap
69
70
  };
package/dist/index.d.mts CHANGED
@@ -3,7 +3,7 @@ import { z } from 'zod';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  type ExperienceType = 'tour' | 'onboarding';
6
- type TourStepType = 'narrate' | 'act' | 'ask_and_fill' | 'user_input' | 'ask_or_fill';
6
+ type TourStepType = 'narrate' | 'act' | 'input' | 'ask_and_fill' | 'user_input' | 'ask_or_fill' | 'wait_then_act';
7
7
  type TourUserActionEvent = 'click' | 'input' | 'change' | 'blur';
8
8
  interface TourActionTarget {
9
9
  uid?: string;
@@ -58,7 +58,7 @@ interface TourRecordedClick {
58
58
  /** Visible text or placeholder captured at record time */
59
59
  textContaining: string;
60
60
  }
61
- type TourCaptureEventType = 'session_start' | 'route' | 'click' | 'input' | 'note';
61
+ type TourCaptureEventType = 'session_start' | 'route' | 'hover' | 'click' | 'input' | 'note';
62
62
  interface TourCaptureEvent {
63
63
  id: string;
64
64
  type: TourCaptureEventType;
@@ -134,7 +134,7 @@ interface TourStep {
134
134
  /** Optional onboarding-specific step metadata */
135
135
  onboarding?: OnboardingStepMetadata;
136
136
  }
137
- type TourTrigger = 'first_visit' | 'feature_unlocked' | 'feature_unlock' | 'idle_on_empty_state' | 'return_visit' | 'new_feature' | 'manual';
137
+ type TourTrigger = 'first_visit' | 'feature_launch' | 'feature_unlocked' | 'feature_unlock' | 'new_feature' | 'manual';
138
138
  type TourStartPolicy = 'immediate_start' | 'prompt_only' | 'manual_only';
139
139
  type TourNotificationType = 'bubble_card' | 'modal';
140
140
  interface TourVoiceConfig {
@@ -142,13 +142,21 @@ interface TourVoiceConfig {
142
142
  ttsVoice?: string;
143
143
  ttsPrefetchLeadMs?: number;
144
144
  }
145
+ interface ExperienceModalConfig {
146
+ title?: string;
147
+ description?: string;
148
+ buttonText?: string;
149
+ cancelButtonText?: string;
150
+ backgroundColor?: string;
151
+ textColor?: string;
152
+ }
145
153
  interface ExperiencePresentation {
146
- launcher?: 'tour_bubble' | 'onboarding_bubble' | 'checklist' | 'none';
147
154
  theme?: {
148
155
  tone?: 'guide' | 'coach' | 'operator';
149
156
  accentColor?: string;
150
157
  icon?: string;
151
158
  };
159
+ modalConfig?: ExperienceModalConfig;
152
160
  }
153
161
  interface ExperienceGoal {
154
162
  primaryAction?: string;
@@ -171,6 +179,11 @@ interface Tour {
171
179
  goal?: ExperienceGoal;
172
180
  capture?: {
173
181
  experienceType?: ExperienceType;
182
+ instructions?: {
183
+ transcript?: string;
184
+ noteEvents?: TourCaptureEvent[];
185
+ };
186
+ notes?: RecordingStep[];
174
187
  onboardingHints?: {
175
188
  inferredWaitTargets?: number;
176
189
  inferredCompletionSignals?: number;
@@ -196,7 +209,7 @@ interface TourFacts {
196
209
  features?: string[];
197
210
  }
198
211
  /** Playback state machine states */
199
- type TourPlaybackState = 'idle' | 'intro' | 'executing' | 'thinking' | 'waiting_voice' | 'waiting_input' | 'complete';
212
+ type TourPlaybackState = 'idle' | 'intro' | 'executing' | 'thinking' | 'waiting_voice' | 'waiting_input' | 'paused' | 'complete';
200
213
  /** Internal recording step being built */
201
214
  interface RecordingStep {
202
215
  order: number;
@@ -468,23 +481,36 @@ interface ModelNexChatBubbleProps {
468
481
  }>;
469
482
  /** Welcome message when chat is empty */
470
483
  welcomeMessage?: string;
484
+ /** Name of the AI agent displayed in the header */
485
+ agentName?: string;
471
486
  /** Display name of the app — used in tour intro narration */
472
487
  appName?: string;
473
488
  /** Save recorded flows as tours or onboarding without changing the recorder UX */
474
489
  recordingExperienceType?: ExperienceType;
490
+ /** Custom theme overrides */
491
+ theme?: {
492
+ accentColor?: string;
493
+ accentForeground?: string;
494
+ panelWidth?: string;
495
+ panelMaxHeight?: string;
496
+ bubbleSize?: string;
497
+ bubbleIconSize?: string;
498
+ borderRadius?: string;
499
+ zIndex?: number;
500
+ };
475
501
  }
476
502
  /**
477
503
  * Chat interface for natural language commands.
478
504
  * Shows conversation history; on exit, the agent summarizes what it did and suggests next steps.
479
505
  * Use within ModelNexProvider. Omit to use your own UI with useRunCommand.
480
506
  */
481
- declare function ModelNexChatBubble({ placeholder, defaultCommand, className, onCommand, welcomeMessage, appName, recordingExperienceType, }: ModelNexChatBubbleProps): react_jsx_runtime.JSX.Element;
507
+ declare function ModelNexChatBubble({ placeholder, defaultCommand, className, onCommand, welcomeMessage, agentName, appName, recordingExperienceType, theme, }: ModelNexChatBubbleProps): React$1.ReactPortal | null;
482
508
 
483
509
  interface ModelNexOnboardingPanelProps {
484
510
  appName?: string;
485
511
  title?: string;
486
512
  }
487
- declare function ModelNexOnboardingPanel({ appName, title, }: ModelNexOnboardingPanelProps): react_jsx_runtime.JSX.Element | null;
513
+ declare function ModelNexOnboardingPanel({ appName, title, }: ModelNexOnboardingPanelProps): react_jsx_runtime.JSX.Element;
488
514
 
489
515
  /**
490
516
  * Toggle and read the action-highlight overlay state.
@@ -543,10 +569,14 @@ declare global {
543
569
  }
544
570
  }
545
571
  interface VoiceHook {
546
- /** Speak text via Deepgram TTS (proxied through server). Uses WebRTC loopback for AEC when available. */
572
+ /** Speak text via Deepgram TTS (proxied through server). Uses WebRTC loopback for AEC when available.
573
+ * The returned promise always settles when the scheduled playback settles; callers can choose whether to await it.
574
+ */
547
575
  speak: (text: string, voiceId?: string, options?: {
548
576
  onNearEnd?: () => void;
549
577
  prefetchLeadMs?: number;
578
+ waitForCompletion?: boolean;
579
+ interrupt?: boolean;
550
580
  }) => Promise<void>;
551
581
  /** Stop any in-progress TTS playback immediately */
552
582
  stopSpeaking: () => void;
@@ -556,6 +586,8 @@ interface VoiceHook {
556
586
  startListening: (onResult: (transcript: string) => void, onInterruption?: (transcript: string) => void, onError?: (err: string) => void, options?: {
557
587
  continuous?: boolean;
558
588
  lang?: string;
589
+ onSpeechStarted?: () => void;
590
+ onInterimResult?: (transcript: string) => void;
559
591
  }) => void;
560
592
  /** Stop STT listening */
561
593
  stopListening: () => void;
@@ -569,6 +601,10 @@ interface VoiceHook {
569
601
  }
570
602
  declare function useVoice(serverUrl: string): VoiceHook;
571
603
 
604
+ interface StartTourOptions {
605
+ reviewMode?: boolean;
606
+ reviewMetadata?: Record<string, unknown>;
607
+ }
572
608
  interface TourPlaybackHook {
573
609
  /** Whether a tour is currently running */
574
610
  isActive: boolean;
@@ -590,8 +626,10 @@ interface TourPlaybackHook {
590
626
  reviewStatusMessage: string | null;
591
627
  /** Prompted tour awaiting user confirmation */
592
628
  pendingTour: Tour | null;
629
+ /** Latest server-authored state snapshot for this experience */
630
+ serverState: TourServerState | null;
593
631
  /** Start a specific tour manually */
594
- startTour: (tour: Tour) => void;
632
+ startTour: (tour: Tour, options?: StartTourOptions) => void;
595
633
  /** Accept the currently pending prompt and start playback */
596
634
  acceptPendingTour: () => void;
597
635
  /** Dismiss the currently pending prompt */
@@ -600,6 +638,10 @@ interface TourPlaybackHook {
600
638
  advanceStep: () => void;
601
639
  /** Skip the entire tour */
602
640
  skipTour: () => void;
641
+ /** Explicitly pause the tour agent (for feedback/review) */
642
+ pauseTour: () => void;
643
+ /** Resume the tour agent after a pause */
644
+ resumeTour: () => void;
603
645
  /** Repeat current step narration */
604
646
  repeatStep: () => void;
605
647
  /** Handle a voice input during the tour */
@@ -609,6 +651,23 @@ interface TourPlaybackHook {
609
651
  /** Save a correction against the current preview step */
610
652
  submitReviewFeedback: (utterance: string, apply?: boolean) => Promise<void>;
611
653
  }
654
+ interface TourServerState {
655
+ runId: number | null;
656
+ turnId: string | null;
657
+ stepIndex: number;
658
+ phase: string;
659
+ isActive: boolean;
660
+ isPaused: boolean;
661
+ awaitingUserInput: boolean;
662
+ pendingCommandId: string | null;
663
+ pendingCommandBatch: {
664
+ commandBatchId: string | null;
665
+ stepIndex: number | null;
666
+ turnId: string | null;
667
+ } | null;
668
+ currentUrl?: string | null;
669
+ reason?: string;
670
+ }
612
671
  interface UseTourPlaybackOptions {
613
672
  serverUrl: string;
614
673
  /** Base URL for agent commands (e.g. /api/modelnex for same-origin). Default: serverUrl */
@@ -634,8 +693,12 @@ interface UseTourPlaybackOptions {
634
693
  disabled?: boolean;
635
694
  /** Shared runtime, but allow a distinct product surface such as onboarding */
636
695
  experienceType?: ExperienceType;
696
+ /** Whether to show global floating captions (usually true when bubble is minimized, false when expanded) */
697
+ showCaptions?: boolean;
698
+ /** Disable internal pending prompt/query discovery when a higher-level controller owns it */
699
+ enableAutoDiscovery?: boolean;
637
700
  }
638
- declare function useTourPlayback({ serverUrl, commandUrl, toursApiBase, socketId, websiteId, userProfile, tourFacts, voice, appName, extractedElements, tagStore, onStepChange, onTourEnd, disabled, experienceType, }: UseTourPlaybackOptions): TourPlaybackHook;
701
+ declare function useTourPlayback({ serverUrl, commandUrl, toursApiBase, socketId, websiteId, userProfile, tourFacts, voice, appName, extractedElements, tagStore, onStepChange, onTourEnd, disabled, experienceType, showCaptions, enableAutoDiscovery, }: UseTourPlaybackOptions): TourPlaybackHook;
639
702
 
640
703
  type ExperiencePlaybackHook = TourPlaybackHook;
641
704
  declare function useExperiencePlayback(...args: Parameters<typeof useTourPlayback>): TourPlaybackHook;
@@ -680,6 +743,7 @@ interface RecordingModeHook {
680
743
  continueRecording: () => void;
681
744
  undoLastStep: () => void;
682
745
  previewSteps: () => void;
746
+ prepareToStopRecording: () => void;
683
747
  stopRecording: (tourName: string, targetUserTypes: string[]) => Promise<string | null>;
684
748
  toggleVoiceCapture: () => void;
685
749
  /** Abandon recording — discard all steps and exit recording mode */
@@ -694,6 +758,27 @@ interface UseRecordingModeOptions {
694
758
  onPreview?: (steps: RecordingStep[]) => void;
695
759
  experienceType?: ExperienceType;
696
760
  }
761
+ declare function buildRecordingCapturePayload({ experienceType, steps, captureEvents, capturedTranscript, }: {
762
+ experienceType?: ExperienceType;
763
+ steps?: RecordingStep[];
764
+ captureEvents?: TourCaptureEvent[];
765
+ capturedTranscript?: string;
766
+ }): {
767
+ generation: {
768
+ mode: "capture_v1";
769
+ generatedAt: string;
770
+ eventCount: number;
771
+ noteCount: number;
772
+ generatedStepCount: number;
773
+ };
774
+ instructions?: {
775
+ noteEvents?: TourCaptureEvent[] | undefined;
776
+ transcript?: string | undefined;
777
+ } | undefined;
778
+ experienceType: ExperienceType;
779
+ events: TourCaptureEvent[];
780
+ notes: RecordingStep[];
781
+ };
697
782
  declare function useRecordingMode({ serverUrl, toursApiBase, websiteId, voice, onPreview, experienceType, }: UseRecordingModeOptions): RecordingModeHook;
698
783
 
699
784
  interface TourProgressPanelProps {
@@ -734,11 +819,41 @@ interface RecordingOverlayProps {
734
819
  }
735
820
  declare function RecordingOverlay({ stepIndex, stepCount, captureEventCount, capturedTranscript, isVoiceCaptureActive, phase, pendingNarration, polishedNarration, isListening, onMarkStep, onToggleVoiceCapture, onElementSelected, onPageLevelStep, onStepTypeConfirmed, onStartNarration, onSubmitTextNarration, onNarrationApprove, onNarrationRedo, onNarrationEdit, onAddNextStep, onDoneRecording, onCancel, onCancelRecording, onStopRecording, }: RecordingOverlayProps): react_jsx_runtime.JSX.Element;
736
821
 
822
+ declare function isAskDrivenInputStepType(stepType?: string | null): boolean;
823
+ declare function isInteractiveInputStepType(stepType?: string | null): boolean;
824
+ declare function isManualOnboardingStep(step?: Pick<TourStep, 'type' | 'onboarding'> | null): boolean;
825
+ declare function buildRecordingStepGoal(stepType: TourStepType, selectedElement: {
826
+ label?: string;
827
+ textContaining?: string;
828
+ } | null, recordedClicks?: Array<{
829
+ label?: string;
830
+ }>): string | undefined;
831
+ declare function inferOnboardingMetadataForStep(step: Pick<TourStep, 'type' | 'element' | 'goal' | 'ask'>): OnboardingStepMetadata | undefined;
832
+
833
+ declare function shouldShowRecordingOverlay(phase: RecordingPhase): boolean;
834
+ declare function isRecordingDraftGenerating(phase: RecordingPhase): boolean;
835
+ declare function getRecordingDraftActionLabel(phase: RecordingPhase): string;
836
+ declare function getRecordingDraftStatusMessage(phase: RecordingPhase, experienceType: ExperienceType): string;
837
+
838
+ interface SavedDraftPreview {
839
+ id: string;
840
+ experienceType: ExperienceType;
841
+ }
842
+ type PreviewLaunchSource = 'standard' | 'query_param';
843
+ declare function getPreviewQueryParamName(experienceType: ExperienceType): 'modelnex_test_tour' | 'modelnex_test_onboarding';
844
+ declare function buildDraftPreviewUrl(currentUrl: string, draft: SavedDraftPreview): string;
845
+ declare function shouldPromptForPreviewStart(notificationType: TourNotificationType | undefined, _source: PreviewLaunchSource): boolean;
846
+ declare function persistActiveDraftPreview(draft: SavedDraftPreview): void;
847
+ declare function readActiveDraftPreview(): SavedDraftPreview | null;
848
+ declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
849
+
737
850
  interface ModelNexProviderProps {
738
- children: React$1.ReactNode;
851
+ children?: unknown;
739
852
  serverUrl?: string;
740
853
  /** Base URL for agent commands. Use same-origin path (e.g. /api/modelnex) to avoid CORS. Default: serverUrl */
741
854
  commandUrl?: string;
855
+ /** Disable the realtime socket connection while still rendering the SDK UI */
856
+ disableSocket?: boolean;
742
857
  /** Identifier for the integrated website, for multi-tenancy */
743
858
  websiteId?: string;
744
859
  /**
@@ -762,4 +877,4 @@ interface ModelNexProviderProps {
762
877
  }
763
878
  declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
764
879
 
765
- 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 RecordingModeHook, RecordingOverlay, type RunCommandResult, StudioOverlay, type TagData, type TagStore, type Tour, type TourFacts, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UseRegisterActionOptions, type UserProfile, type VoiceHook, extractInteractiveElements, generateFingerprint, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRegisterAction, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
880
+ 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 TourFacts, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UseRegisterActionOptions, 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, useRegisterAction, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { z } from 'zod';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  type ExperienceType = 'tour' | 'onboarding';
6
- type TourStepType = 'narrate' | 'act' | 'ask_and_fill' | 'user_input' | 'ask_or_fill';
6
+ type TourStepType = 'narrate' | 'act' | 'input' | 'ask_and_fill' | 'user_input' | 'ask_or_fill' | 'wait_then_act';
7
7
  type TourUserActionEvent = 'click' | 'input' | 'change' | 'blur';
8
8
  interface TourActionTarget {
9
9
  uid?: string;
@@ -58,7 +58,7 @@ interface TourRecordedClick {
58
58
  /** Visible text or placeholder captured at record time */
59
59
  textContaining: string;
60
60
  }
61
- type TourCaptureEventType = 'session_start' | 'route' | 'click' | 'input' | 'note';
61
+ type TourCaptureEventType = 'session_start' | 'route' | 'hover' | 'click' | 'input' | 'note';
62
62
  interface TourCaptureEvent {
63
63
  id: string;
64
64
  type: TourCaptureEventType;
@@ -134,7 +134,7 @@ interface TourStep {
134
134
  /** Optional onboarding-specific step metadata */
135
135
  onboarding?: OnboardingStepMetadata;
136
136
  }
137
- type TourTrigger = 'first_visit' | 'feature_unlocked' | 'feature_unlock' | 'idle_on_empty_state' | 'return_visit' | 'new_feature' | 'manual';
137
+ type TourTrigger = 'first_visit' | 'feature_launch' | 'feature_unlocked' | 'feature_unlock' | 'new_feature' | 'manual';
138
138
  type TourStartPolicy = 'immediate_start' | 'prompt_only' | 'manual_only';
139
139
  type TourNotificationType = 'bubble_card' | 'modal';
140
140
  interface TourVoiceConfig {
@@ -142,13 +142,21 @@ interface TourVoiceConfig {
142
142
  ttsVoice?: string;
143
143
  ttsPrefetchLeadMs?: number;
144
144
  }
145
+ interface ExperienceModalConfig {
146
+ title?: string;
147
+ description?: string;
148
+ buttonText?: string;
149
+ cancelButtonText?: string;
150
+ backgroundColor?: string;
151
+ textColor?: string;
152
+ }
145
153
  interface ExperiencePresentation {
146
- launcher?: 'tour_bubble' | 'onboarding_bubble' | 'checklist' | 'none';
147
154
  theme?: {
148
155
  tone?: 'guide' | 'coach' | 'operator';
149
156
  accentColor?: string;
150
157
  icon?: string;
151
158
  };
159
+ modalConfig?: ExperienceModalConfig;
152
160
  }
153
161
  interface ExperienceGoal {
154
162
  primaryAction?: string;
@@ -171,6 +179,11 @@ interface Tour {
171
179
  goal?: ExperienceGoal;
172
180
  capture?: {
173
181
  experienceType?: ExperienceType;
182
+ instructions?: {
183
+ transcript?: string;
184
+ noteEvents?: TourCaptureEvent[];
185
+ };
186
+ notes?: RecordingStep[];
174
187
  onboardingHints?: {
175
188
  inferredWaitTargets?: number;
176
189
  inferredCompletionSignals?: number;
@@ -196,7 +209,7 @@ interface TourFacts {
196
209
  features?: string[];
197
210
  }
198
211
  /** Playback state machine states */
199
- type TourPlaybackState = 'idle' | 'intro' | 'executing' | 'thinking' | 'waiting_voice' | 'waiting_input' | 'complete';
212
+ type TourPlaybackState = 'idle' | 'intro' | 'executing' | 'thinking' | 'waiting_voice' | 'waiting_input' | 'paused' | 'complete';
200
213
  /** Internal recording step being built */
201
214
  interface RecordingStep {
202
215
  order: number;
@@ -468,23 +481,36 @@ interface ModelNexChatBubbleProps {
468
481
  }>;
469
482
  /** Welcome message when chat is empty */
470
483
  welcomeMessage?: string;
484
+ /** Name of the AI agent displayed in the header */
485
+ agentName?: string;
471
486
  /** Display name of the app — used in tour intro narration */
472
487
  appName?: string;
473
488
  /** Save recorded flows as tours or onboarding without changing the recorder UX */
474
489
  recordingExperienceType?: ExperienceType;
490
+ /** Custom theme overrides */
491
+ theme?: {
492
+ accentColor?: string;
493
+ accentForeground?: string;
494
+ panelWidth?: string;
495
+ panelMaxHeight?: string;
496
+ bubbleSize?: string;
497
+ bubbleIconSize?: string;
498
+ borderRadius?: string;
499
+ zIndex?: number;
500
+ };
475
501
  }
476
502
  /**
477
503
  * Chat interface for natural language commands.
478
504
  * Shows conversation history; on exit, the agent summarizes what it did and suggests next steps.
479
505
  * Use within ModelNexProvider. Omit to use your own UI with useRunCommand.
480
506
  */
481
- declare function ModelNexChatBubble({ placeholder, defaultCommand, className, onCommand, welcomeMessage, appName, recordingExperienceType, }: ModelNexChatBubbleProps): react_jsx_runtime.JSX.Element;
507
+ declare function ModelNexChatBubble({ placeholder, defaultCommand, className, onCommand, welcomeMessage, agentName, appName, recordingExperienceType, theme, }: ModelNexChatBubbleProps): React$1.ReactPortal | null;
482
508
 
483
509
  interface ModelNexOnboardingPanelProps {
484
510
  appName?: string;
485
511
  title?: string;
486
512
  }
487
- declare function ModelNexOnboardingPanel({ appName, title, }: ModelNexOnboardingPanelProps): react_jsx_runtime.JSX.Element | null;
513
+ declare function ModelNexOnboardingPanel({ appName, title, }: ModelNexOnboardingPanelProps): react_jsx_runtime.JSX.Element;
488
514
 
489
515
  /**
490
516
  * Toggle and read the action-highlight overlay state.
@@ -543,10 +569,14 @@ declare global {
543
569
  }
544
570
  }
545
571
  interface VoiceHook {
546
- /** Speak text via Deepgram TTS (proxied through server). Uses WebRTC loopback for AEC when available. */
572
+ /** Speak text via Deepgram TTS (proxied through server). Uses WebRTC loopback for AEC when available.
573
+ * The returned promise always settles when the scheduled playback settles; callers can choose whether to await it.
574
+ */
547
575
  speak: (text: string, voiceId?: string, options?: {
548
576
  onNearEnd?: () => void;
549
577
  prefetchLeadMs?: number;
578
+ waitForCompletion?: boolean;
579
+ interrupt?: boolean;
550
580
  }) => Promise<void>;
551
581
  /** Stop any in-progress TTS playback immediately */
552
582
  stopSpeaking: () => void;
@@ -556,6 +586,8 @@ interface VoiceHook {
556
586
  startListening: (onResult: (transcript: string) => void, onInterruption?: (transcript: string) => void, onError?: (err: string) => void, options?: {
557
587
  continuous?: boolean;
558
588
  lang?: string;
589
+ onSpeechStarted?: () => void;
590
+ onInterimResult?: (transcript: string) => void;
559
591
  }) => void;
560
592
  /** Stop STT listening */
561
593
  stopListening: () => void;
@@ -569,6 +601,10 @@ interface VoiceHook {
569
601
  }
570
602
  declare function useVoice(serverUrl: string): VoiceHook;
571
603
 
604
+ interface StartTourOptions {
605
+ reviewMode?: boolean;
606
+ reviewMetadata?: Record<string, unknown>;
607
+ }
572
608
  interface TourPlaybackHook {
573
609
  /** Whether a tour is currently running */
574
610
  isActive: boolean;
@@ -590,8 +626,10 @@ interface TourPlaybackHook {
590
626
  reviewStatusMessage: string | null;
591
627
  /** Prompted tour awaiting user confirmation */
592
628
  pendingTour: Tour | null;
629
+ /** Latest server-authored state snapshot for this experience */
630
+ serverState: TourServerState | null;
593
631
  /** Start a specific tour manually */
594
- startTour: (tour: Tour) => void;
632
+ startTour: (tour: Tour, options?: StartTourOptions) => void;
595
633
  /** Accept the currently pending prompt and start playback */
596
634
  acceptPendingTour: () => void;
597
635
  /** Dismiss the currently pending prompt */
@@ -600,6 +638,10 @@ interface TourPlaybackHook {
600
638
  advanceStep: () => void;
601
639
  /** Skip the entire tour */
602
640
  skipTour: () => void;
641
+ /** Explicitly pause the tour agent (for feedback/review) */
642
+ pauseTour: () => void;
643
+ /** Resume the tour agent after a pause */
644
+ resumeTour: () => void;
603
645
  /** Repeat current step narration */
604
646
  repeatStep: () => void;
605
647
  /** Handle a voice input during the tour */
@@ -609,6 +651,23 @@ interface TourPlaybackHook {
609
651
  /** Save a correction against the current preview step */
610
652
  submitReviewFeedback: (utterance: string, apply?: boolean) => Promise<void>;
611
653
  }
654
+ interface TourServerState {
655
+ runId: number | null;
656
+ turnId: string | null;
657
+ stepIndex: number;
658
+ phase: string;
659
+ isActive: boolean;
660
+ isPaused: boolean;
661
+ awaitingUserInput: boolean;
662
+ pendingCommandId: string | null;
663
+ pendingCommandBatch: {
664
+ commandBatchId: string | null;
665
+ stepIndex: number | null;
666
+ turnId: string | null;
667
+ } | null;
668
+ currentUrl?: string | null;
669
+ reason?: string;
670
+ }
612
671
  interface UseTourPlaybackOptions {
613
672
  serverUrl: string;
614
673
  /** Base URL for agent commands (e.g. /api/modelnex for same-origin). Default: serverUrl */
@@ -634,8 +693,12 @@ interface UseTourPlaybackOptions {
634
693
  disabled?: boolean;
635
694
  /** Shared runtime, but allow a distinct product surface such as onboarding */
636
695
  experienceType?: ExperienceType;
696
+ /** Whether to show global floating captions (usually true when bubble is minimized, false when expanded) */
697
+ showCaptions?: boolean;
698
+ /** Disable internal pending prompt/query discovery when a higher-level controller owns it */
699
+ enableAutoDiscovery?: boolean;
637
700
  }
638
- declare function useTourPlayback({ serverUrl, commandUrl, toursApiBase, socketId, websiteId, userProfile, tourFacts, voice, appName, extractedElements, tagStore, onStepChange, onTourEnd, disabled, experienceType, }: UseTourPlaybackOptions): TourPlaybackHook;
701
+ declare function useTourPlayback({ serverUrl, commandUrl, toursApiBase, socketId, websiteId, userProfile, tourFacts, voice, appName, extractedElements, tagStore, onStepChange, onTourEnd, disabled, experienceType, showCaptions, enableAutoDiscovery, }: UseTourPlaybackOptions): TourPlaybackHook;
639
702
 
640
703
  type ExperiencePlaybackHook = TourPlaybackHook;
641
704
  declare function useExperiencePlayback(...args: Parameters<typeof useTourPlayback>): TourPlaybackHook;
@@ -680,6 +743,7 @@ interface RecordingModeHook {
680
743
  continueRecording: () => void;
681
744
  undoLastStep: () => void;
682
745
  previewSteps: () => void;
746
+ prepareToStopRecording: () => void;
683
747
  stopRecording: (tourName: string, targetUserTypes: string[]) => Promise<string | null>;
684
748
  toggleVoiceCapture: () => void;
685
749
  /** Abandon recording — discard all steps and exit recording mode */
@@ -694,6 +758,27 @@ interface UseRecordingModeOptions {
694
758
  onPreview?: (steps: RecordingStep[]) => void;
695
759
  experienceType?: ExperienceType;
696
760
  }
761
+ declare function buildRecordingCapturePayload({ experienceType, steps, captureEvents, capturedTranscript, }: {
762
+ experienceType?: ExperienceType;
763
+ steps?: RecordingStep[];
764
+ captureEvents?: TourCaptureEvent[];
765
+ capturedTranscript?: string;
766
+ }): {
767
+ generation: {
768
+ mode: "capture_v1";
769
+ generatedAt: string;
770
+ eventCount: number;
771
+ noteCount: number;
772
+ generatedStepCount: number;
773
+ };
774
+ instructions?: {
775
+ noteEvents?: TourCaptureEvent[] | undefined;
776
+ transcript?: string | undefined;
777
+ } | undefined;
778
+ experienceType: ExperienceType;
779
+ events: TourCaptureEvent[];
780
+ notes: RecordingStep[];
781
+ };
697
782
  declare function useRecordingMode({ serverUrl, toursApiBase, websiteId, voice, onPreview, experienceType, }: UseRecordingModeOptions): RecordingModeHook;
698
783
 
699
784
  interface TourProgressPanelProps {
@@ -734,11 +819,41 @@ interface RecordingOverlayProps {
734
819
  }
735
820
  declare function RecordingOverlay({ stepIndex, stepCount, captureEventCount, capturedTranscript, isVoiceCaptureActive, phase, pendingNarration, polishedNarration, isListening, onMarkStep, onToggleVoiceCapture, onElementSelected, onPageLevelStep, onStepTypeConfirmed, onStartNarration, onSubmitTextNarration, onNarrationApprove, onNarrationRedo, onNarrationEdit, onAddNextStep, onDoneRecording, onCancel, onCancelRecording, onStopRecording, }: RecordingOverlayProps): react_jsx_runtime.JSX.Element;
736
821
 
822
+ declare function isAskDrivenInputStepType(stepType?: string | null): boolean;
823
+ declare function isInteractiveInputStepType(stepType?: string | null): boolean;
824
+ declare function isManualOnboardingStep(step?: Pick<TourStep, 'type' | 'onboarding'> | null): boolean;
825
+ declare function buildRecordingStepGoal(stepType: TourStepType, selectedElement: {
826
+ label?: string;
827
+ textContaining?: string;
828
+ } | null, recordedClicks?: Array<{
829
+ label?: string;
830
+ }>): string | undefined;
831
+ declare function inferOnboardingMetadataForStep(step: Pick<TourStep, 'type' | 'element' | 'goal' | 'ask'>): OnboardingStepMetadata | undefined;
832
+
833
+ declare function shouldShowRecordingOverlay(phase: RecordingPhase): boolean;
834
+ declare function isRecordingDraftGenerating(phase: RecordingPhase): boolean;
835
+ declare function getRecordingDraftActionLabel(phase: RecordingPhase): string;
836
+ declare function getRecordingDraftStatusMessage(phase: RecordingPhase, experienceType: ExperienceType): string;
837
+
838
+ interface SavedDraftPreview {
839
+ id: string;
840
+ experienceType: ExperienceType;
841
+ }
842
+ type PreviewLaunchSource = 'standard' | 'query_param';
843
+ declare function getPreviewQueryParamName(experienceType: ExperienceType): 'modelnex_test_tour' | 'modelnex_test_onboarding';
844
+ declare function buildDraftPreviewUrl(currentUrl: string, draft: SavedDraftPreview): string;
845
+ declare function shouldPromptForPreviewStart(notificationType: TourNotificationType | undefined, _source: PreviewLaunchSource): boolean;
846
+ declare function persistActiveDraftPreview(draft: SavedDraftPreview): void;
847
+ declare function readActiveDraftPreview(): SavedDraftPreview | null;
848
+ declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
849
+
737
850
  interface ModelNexProviderProps {
738
- children: React$1.ReactNode;
851
+ children?: unknown;
739
852
  serverUrl?: string;
740
853
  /** Base URL for agent commands. Use same-origin path (e.g. /api/modelnex) to avoid CORS. Default: serverUrl */
741
854
  commandUrl?: string;
855
+ /** Disable the realtime socket connection while still rendering the SDK UI */
856
+ disableSocket?: boolean;
742
857
  /** Identifier for the integrated website, for multi-tenancy */
743
858
  websiteId?: string;
744
859
  /**
@@ -762,4 +877,4 @@ interface ModelNexProviderProps {
762
877
  }
763
878
  declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
764
879
 
765
- 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 RecordingModeHook, RecordingOverlay, type RunCommandResult, StudioOverlay, type TagData, type TagStore, type Tour, type TourFacts, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UseRegisterActionOptions, type UserProfile, type VoiceHook, extractInteractiveElements, generateFingerprint, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRegisterAction, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
880
+ 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 TourFacts, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UseRegisterActionOptions, 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, useRegisterAction, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };