guideai-app 0.4.3 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +86 -5
  2. package/dist/GuideAI.d.ts +1 -1
  3. package/dist/GuideAI.js +1 -1
  4. package/dist/GuideAI.js.map +1 -1
  5. package/dist/components/AnimatedSettingsItem.d.ts +9 -0
  6. package/dist/components/Microphone.d.ts +19 -0
  7. package/dist/components/MuteButton.d.ts +11 -0
  8. package/dist/components/ResetButton.d.ts +9 -0
  9. package/dist/components/SettingsMenu.d.ts +16 -0
  10. package/dist/components/SettingsToggle.d.ts +7 -0
  11. package/dist/components/TranscriptBox.d.ts +20 -12
  12. package/dist/components/TranscriptMessages.d.ts +8 -0
  13. package/dist/components/TranscriptTextInput.d.ts +12 -0
  14. package/dist/components/TranscriptToggle.d.ts +7 -0
  15. package/dist/hooks/index.d.ts +3 -0
  16. package/dist/hooks/useGuideAIAPI.d.ts +22 -0
  17. package/dist/hooks/useTranscriptState.d.ts +21 -0
  18. package/dist/hooks/useWebRTC.d.ts +71 -0
  19. package/dist/index.d.ts +2 -1
  20. package/dist/styles/GuideAI.styles.d.ts +7 -1
  21. package/dist/types/GuideAI.types.d.ts +25 -21
  22. package/dist/utils/api.d.ts +29 -18
  23. package/dist/utils/constants.d.ts +21 -6
  24. package/dist/utils/conversationManager.d.ts +89 -0
  25. package/dist/utils/dataChannel.d.ts +100 -0
  26. package/dist/utils/elementInteractions.d.ts +38 -2
  27. package/dist/utils/highlightThenClick.d.ts +2 -1
  28. package/dist/utils/hover.d.ts +2 -0
  29. package/dist/utils/hoverThenClick.d.ts +2 -1
  30. package/dist/utils/isChromeExtension.d.ts +5 -0
  31. package/dist/utils/localStorageHelper.d.ts +57 -0
  32. package/dist/utils/logger.d.ts +50 -9
  33. package/dist/utils/messageStorage.d.ts +16 -3
  34. package/dist/utils/positionUtils.d.ts +39 -0
  35. package/dist/utils/toolRegistry.d.ts +33 -0
  36. package/dist/utils/webrtcConnection.d.ts +61 -0
  37. package/dist/visualContext/VisualContextScheduler.d.ts +11 -14
  38. package/dist/visualContext/debug-overlay.d.ts +1 -1
  39. package/dist/visualContext/domChangeTracker.d.ts +16 -0
  40. package/dist/visualContext/index.d.ts +8 -1
  41. package/dist/visualContext/types.d.ts +4 -0
  42. package/dist/visualContext/useVisualContext.d.ts +32 -0
  43. package/package.json +17 -5
  44. package/.workflow-test +0 -1
  45. package/API_DATA_CONTRACTS.md +0 -516
  46. package/API_SESSIONID_TESTING.md +0 -215
  47. package/GuideAI.d.ts +0 -19
  48. package/GuideAI.js +0 -1
  49. package/GuideAI.js.LICENSE.txt +0 -16
  50. package/GuideAI.js.map +0 -1
  51. package/PII_HASHING_EPIC.md +0 -886
  52. package/PII_HASHING_STORIES_SUMMARY.md +0 -275
  53. package/PRODUCTION_RELEASE.md +0 -126
  54. package/SESSION_ID_VERIFICATION.md +0 -122
  55. package/VISIT_COUNT_TESTING.md +0 -453
  56. package/dist/metric/event-listner.d.ts +0 -143
  57. package/dist/metric/index.d.ts +0 -2
  58. package/dist/metric/metadata-tracker.d.ts +0 -50
  59. package/dist/types/metadata.types.d.ts +0 -48
  60. package/dist/utils/gemini.d.ts +0 -5
  61. package/dist/utils/highlightAndClick.d.ts +0 -3
  62. package/dist/utils/hoverAndClick.d.ts +0 -4
  63. package/index.d.ts +0 -7
  64. package/jest.config.js +0 -26
  65. package/jest.setup.js +0 -21
  66. package/metadata-tracking-example.md +0 -324
  67. package/obfuscate.js +0 -40
  68. package/obfuscator.prod.json +0 -24
  69. package/rollup.config.js +0 -34
  70. package/structure.md +0 -128
  71. package/text-input-usage.md +0 -321
  72. package/transcript-toggle-usage.md +0 -267
  73. package/visit-tracking-usage.md +0 -134
  74. package/webpack.config.js +0 -55
  75. package/workflow-trigger-usage.md +0 -398
@@ -0,0 +1,100 @@
1
+ import { StoredMessage } from './messageStorage';
2
+ import { type ToolWithConfig } from './toolRegistry';
3
+ import { ConversationManager } from './conversationManager';
4
+ export type RecordingStatus = 'idle' | 'recording' | 'active' | 'processing' | 'playing';
5
+ export declare const IGNORE_MESSAGE_TYPES: string[];
6
+ export interface DataChannelCallbacks {
7
+ setIsDataChannelOpen: (open: boolean) => void;
8
+ setIsConnecting: (connecting: boolean) => void;
9
+ setStatus: (status: RecordingStatus) => void;
10
+ handleHighlightThenClick: (out: any) => Promise<boolean>;
11
+ handleHoverThenClick: (out: any) => Promise<boolean>;
12
+ handleHover: (out: any) => Promise<boolean>;
13
+ handleGoToAElmLink: (linkText: string, delay?: number) => Promise<boolean>;
14
+ onDataChannelClose: (pc: RTCPeerConnection) => void;
15
+ onDataChannelError: (event: Event) => void;
16
+ onDataChannelMessageError: (message: any) => void;
17
+ setIsResponseActive: (active: boolean) => void;
18
+ updateStreamingMessage: (delta: string) => void;
19
+ /** Reset streaming state when a new response starts (call on response.created) */
20
+ resetStreamingMessage?: () => void;
21
+ allMessages: StoredMessage[];
22
+ status: RecordingStatus;
23
+ organizationKey: string;
24
+ /** Ref to ConversationManager - use .current when logging (set in onSessionData before data channel opens) */
25
+ conversationManagerRef: {
26
+ current: ConversationManager | null;
27
+ };
28
+ updateSessionId?: (sessionId: string | null) => void;
29
+ }
30
+ export interface DataChannelConfig {
31
+ audioStream: MediaStream | null;
32
+ callbacks: DataChannelCallbacks;
33
+ /** Tools from server (initialize response). If undefined = old server, use built-in. If [] = new server, no tools. */
34
+ tools?: ToolWithConfig[];
35
+ /** Prop tools: Record<functionName, { description, parameters, execute }> - always custom handler */
36
+ propTools?: Record<string, {
37
+ description: string;
38
+ parameters: object;
39
+ execute: (args: Record<string, unknown>) => Promise<unknown>;
40
+ }>;
41
+ }
42
+ export declare const BUFFERED_AMOUNT_THRESHOLD = 65536;
43
+ export declare class DataChannelManager {
44
+ private dataChannel;
45
+ private peerConnection;
46
+ private callbacks;
47
+ private audioStream;
48
+ private sendQueue;
49
+ private toolsConfig;
50
+ private serverToolsReceived;
51
+ private propTools?;
52
+ constructor(config: DataChannelConfig);
53
+ /** Set tools from server (call after initialize, before channel opens) */
54
+ setTools(tools: ToolWithConfig[]): void;
55
+ /**
56
+ * Create a new data channel on the peer connection
57
+ */
58
+ createDataChannel(pc: RTCPeerConnection): RTCDataChannel;
59
+ /**
60
+ * Setup all event handlers for the data channel
61
+ */
62
+ private setupEventHandlers;
63
+ /**
64
+ * Handle data channel open event
65
+ */
66
+ private handleChannelOpen;
67
+ /**
68
+ * Handle incoming messages from the data channel
69
+ */
70
+ private handleMessage;
71
+ /**
72
+ * Flush queued messages when buffer has drained
73
+ */
74
+ private flushSendQueue;
75
+ /**
76
+ * Send a message through the data channel.
77
+ * Queues the message if bufferedAmount exceeds threshold; it will be sent when buffer drains.
78
+ */
79
+ sendMessage(message: any): void;
80
+ /**
81
+ * Check if the data channel is open and ready
82
+ */
83
+ isOpen(): boolean;
84
+ /**
85
+ * Get the current buffered amount in bytes
86
+ */
87
+ getBufferedAmount(): number;
88
+ /**
89
+ * Check if the send buffer is full (above threshold)
90
+ */
91
+ isBufferFull(): boolean;
92
+ /**
93
+ * Get the current data channel
94
+ */
95
+ getDataChannel(): RTCDataChannel | null;
96
+ /**
97
+ * Close and cleanup the data channel
98
+ */
99
+ close(): void;
100
+ }
@@ -1,7 +1,11 @@
1
1
  import { ElementInteractionType } from './constants';
2
+ export interface ToolInput {
3
+ arguments: string;
4
+ name?: string;
5
+ }
2
6
  export declare const HOVER_EFFECT_KEEP_ALIVE_TIME = 3000;
3
7
  export declare const createHoverEffect: (element: Element, initialRect: DOMRect, cursorElement?: HTMLElement | null, duration?: number) => Promise<void>;
4
- export declare const clickElement: (element: Element, rect: DOMRect, withEffects?: boolean) => Promise<void>;
8
+ export declare const clickElement: (element: Element, rect: DOMRect, withEffects?: boolean, cursorElement?: HTMLElement | null) => Promise<void>;
5
9
  export declare const parseCustomSelector: (selector: string) => {
6
10
  type: "text" | "css" | "xpath";
7
11
  cssSelector?: string;
@@ -12,7 +16,8 @@ export declare const findElementBySelectorStrict: (selector: string) => Element
12
16
  export declare const findElementBySelector: (selector: string) => Element | null;
13
17
  export declare const interactWithElement: (element: Element, cursorElement: HTMLElement | null, state: ElementInteractionType, hoverTime?: number) => Promise<HTMLElement | null>;
14
18
  export declare const processSelectorsInteraction: (selectors: string | string[], isInteracting: boolean, setIsInteracting: (interacting: boolean) => void, onEachElement: (element: Element, cursor: HTMLElement | null, index: number) => Promise<HTMLElement | null>, onComplete?: (lastElement: Element | null, cursor: HTMLElement | null) => Promise<void>) => Promise<boolean>;
15
- export declare const Highlight_Tool: {
19
+ export declare const parseArgs: (argsToUse: string) => Promise<any>;
20
+ export declare const Highlight_Click_Tool: {
16
21
  type: string;
17
22
  name: string;
18
23
  description: string;
@@ -37,6 +42,37 @@ export declare const Highlight_Tool: {
37
42
  required: string[];
38
43
  };
39
44
  };
45
+ export declare const Hover_Click_Tool: {
46
+ type: string;
47
+ name: string;
48
+ description: string;
49
+ parameters: {
50
+ type: string;
51
+ properties: {
52
+ selector: {
53
+ oneOf: ({
54
+ type: string;
55
+ description: string;
56
+ items?: undefined;
57
+ } | {
58
+ type: string;
59
+ items: {
60
+ type: string;
61
+ };
62
+ description: string;
63
+ })[];
64
+ description: string;
65
+ };
66
+ hoverTime: {
67
+ type: string;
68
+ description: string;
69
+ minimum: number;
70
+ maximum: number;
71
+ };
72
+ };
73
+ required: string[];
74
+ };
75
+ };
40
76
  export declare const Hover_Tool: {
41
77
  type: string;
42
78
  name: string;
@@ -1 +1,2 @@
1
- export declare const highlightThenClick: (selector: string | string[], isHighlighting: boolean, setIsHighlighting: (highlighting: boolean) => void) => Promise<boolean>;
1
+ import { ToolInput } from './elementInteractions';
2
+ export declare const highlightThenClick: (out: ToolInput, isHighlighting: boolean, setIsHighlighting: (highlighting: boolean) => void) => Promise<boolean>;
@@ -0,0 +1,2 @@
1
+ import { ToolInput } from './elementInteractions';
2
+ export declare const hover: (out: ToolInput, isHovering: boolean, setIsHovering: (hovering: boolean) => void) => Promise<boolean>;
@@ -1 +1,2 @@
1
- export declare const hoverThenClick: (selector: string | string[], isHovering: boolean, setIsHovering: (hovering: boolean) => void, hoverTime?: number) => Promise<boolean>;
1
+ import { ToolInput } from './elementInteractions';
2
+ export declare const hoverThenClick: (out: ToolInput, isHovering: boolean, setIsHovering: (hovering: boolean) => void) => Promise<boolean>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Detects if the code is running inside a Chrome extension content script.
3
+ * Used for audio setup and other extension-specific behavior.
4
+ */
5
+ export declare function isChromeExtension(): boolean;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Centralized localStorage helper
3
+ * Tracks all localStorage keys used in the application
4
+ */
5
+ declare const STORAGE_KEYS: {
6
+ readonly USER_UUID: "guideAI_userUUID";
7
+ readonly SESSION_ID: "guideAI_sessionId";
8
+ readonly CONVERSATION: "guideAI_conversation";
9
+ readonly HAS_INTERACTED: "guideAI_hasInteracted";
10
+ readonly IS_MUTED: "guideAI_isMuted";
11
+ readonly LOGGER_ENABLED: "guideAI_loggerEnabled";
12
+ };
13
+ /**
14
+ * Check if localStorage is available
15
+ */
16
+ export declare const isLocalStorageAvailable: () => boolean;
17
+ /**
18
+ * Get or create user UUID
19
+ * Creates a new UUID if one doesn't exist
20
+ */
21
+ export declare const getUserUUID: () => string;
22
+ /**
23
+ * Get session ID (active OpenAI session)
24
+ */
25
+ export declare const getSessionId: () => string | null;
26
+ /**
27
+ * Set session ID
28
+ */
29
+ export declare const setSessionId: (sessionId: string | null) => void;
30
+ /**
31
+ * Get has interacted flag
32
+ */
33
+ export declare const getHasInteracted: () => boolean;
34
+ /**
35
+ * Set has interacted flag
36
+ */
37
+ export declare const setHasInteracted: (value: boolean) => void;
38
+ /**
39
+ * Get is muted flag
40
+ */
41
+ export declare const getIsMuted: () => boolean;
42
+ /**
43
+ * Set is muted flag
44
+ */
45
+ export declare const setIsMuted: (value: boolean) => void;
46
+ /**
47
+ * Get logger enabled flag (used by Logger to persist enable state)
48
+ */
49
+ export declare const getLoggerEnabled: () => boolean;
50
+ /**
51
+ * Set logger enabled flag
52
+ */
53
+ export declare const setLoggerEnabled: (value: boolean) => void;
54
+ /**
55
+ * Export storage keys for reference (read-only)
56
+ */
57
+ export { STORAGE_KEYS };
@@ -1,10 +1,55 @@
1
- /**
2
- * Standardized logging utility for GuideAI package
3
- * Provides consistent formatting and development gating across all components
4
- */
5
- type Component = 'GuideAI' | 'UserMetadata' | 'API' | 'TranscriptBox' | 'Onboarding';
1
+ type Component = 'GuideAI' | 'API' | 'TranscriptBox' | 'Onboarding' | 'VisualContext' | 'MessageStorage' | 'DataChannel' | 'ConversationManager' | 'LocalStorageHelper' | 'WebRTCConnection' | 'ToolRegistry';
6
2
  declare class Logger {
7
3
  private static formatMessage;
4
+ private static checkLoggingEnabled;
5
+ /**
6
+ * Initialize logger and attach to window for console access
7
+ * Call Logger.init() from browser console to enable logging.
8
+ * Restores persisted enabled state from localStorage if previously enabled.
9
+ */
10
+ static init(): void;
11
+ /**
12
+ * Enable logging from console, or for a specific component.
13
+ * Usage: GuideAILogger.enable() or GuideAILogger.enable('API')
14
+ */
15
+ static enable(component?: Component): void;
16
+ /**
17
+ * Disable logging from console, or for a specific component.
18
+ * Usage: GuideAILogger.disable() or GuideAILogger.disable('API')
19
+ */
20
+ static disable(component?: Component): void;
21
+ /**
22
+ * Enable or disable logging for a specific component
23
+ * Usage: GuideAILogger.setComponentEnabled('API', true)
24
+ */
25
+ static setComponentEnabled(component: Component, enabled: boolean): void;
26
+ /**
27
+ * Get current logging status
28
+ * Usage: GuideAILogger.getStatus()
29
+ */
30
+ static getStatus(): {
31
+ manualEnabled: boolean;
32
+ components: Record<Component, boolean>;
33
+ };
34
+ /**
35
+ * Disable logging for all components
36
+ * Usage: GuideAILogger.disableAllComponents()
37
+ */
38
+ static disableAllComponents(): void;
39
+ /**
40
+ * Enable logging for all components
41
+ * Usage: GuideAILogger.enableAllComponents()
42
+ */
43
+ static enableAllComponents(): void;
44
+ /**
45
+ * Display help information listing all available Logger functions
46
+ * Usage: GuideAILogger.help()
47
+ */
48
+ static help(): void;
49
+ /**
50
+ * Standard info logging - only in development
51
+ */
52
+ static info(component: Component, action: string, data?: any): void;
8
53
  /**
9
54
  * Standard info logging - only in development
10
55
  */
@@ -29,9 +74,5 @@ declare class Logger {
29
74
  * Conversation flow tracking
30
75
  */
31
76
  static conversation(action: string, data?: any): void;
32
- /**
33
- * Metadata tracking logging
34
- */
35
- static metadata(action: string, data?: any): void;
36
77
  }
37
78
  export default Logger;
@@ -1,19 +1,27 @@
1
1
  export interface StoredMessage {
2
2
  content: string;
3
- sender: 'GUIDEAI' | 'HUMAN';
3
+ sender: 'GUIDEAI' | 'HUMAN' | 'SYSTEM';
4
4
  timestamp: number;
5
5
  }
6
6
  export interface StoredConversation {
7
7
  conversationId: string;
8
+ conversationKey?: string;
8
9
  messages: StoredMessage[];
9
10
  timestamp: number;
10
11
  organizationKey: string;
12
+ keyExpiresAt?: number;
13
+ sessionExpiresAt?: number;
14
+ user?: string;
11
15
  }
12
- export declare const CONVERSATION_STORAGE_KEY = "guideai_conversation";
16
+ export declare const CONVERSATION_STORAGE_KEY = "guideAI_conversation";
13
17
  export declare const CONVERSATION_EXPIRY_MINUTES = 30;
14
18
  export declare const MAX_STORED_MESSAGES = 100;
15
19
  export declare const isLocalStorageAvailable: () => boolean;
16
- export declare const isConversationExpired: (conversation: StoredConversation) => boolean;
20
+ export declare const initializeConversationStorage: (organizationKey: string, conversationId: string) => void;
21
+ export declare const isSessionExpired: (organizationKey: string) => boolean;
22
+ export declare const isConversationExpired: (organizationKey: string) => boolean;
23
+ export declare const updateSessionExpiresAt: (organizationKey: string, sessionExpiresAt: number) => void;
24
+ export declare const getConversationId: (organizationKey: string) => string | null;
17
25
  export declare const saveConversationToStorage: (conversation: StoredConversation) => void;
18
26
  export declare const loadConversationFromStorage: () => StoredConversation | null;
19
27
  export declare const clearConversationStorage: () => void;
@@ -24,3 +32,8 @@ export declare const checkForStoredConversation: (currentOrganizationKey: string
24
32
  messages: StoredMessage[] | null;
25
33
  };
26
34
  export declare const formatConversationContext: (messages: StoredMessage[], maxMessages?: number) => string;
35
+ /**
36
+ * Get messages from localStorage as the single source of truth
37
+ * This ensures all components read from the same storage location
38
+ */
39
+ export declare const getMessagesFromStorage: (organizationKey: string) => StoredMessage[];
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Position and layout utilities for GuideAI components.
3
+ * Handles mic position, popup position, transcript position, and z-index config.
4
+ */
5
+ import type { GuideAIPosition, PopupPosition, TranscriptPosition } from '../types/GuideAI.types';
6
+ export declare const DEFAULT_POSITION: {
7
+ readonly bottom: "20px";
8
+ readonly left: "50%";
9
+ readonly transform: "translateX(-50%)";
10
+ };
11
+ export interface ZIndexConfig {
12
+ main: number;
13
+ transcript: number;
14
+ microphone: number;
15
+ onboarding: number;
16
+ }
17
+ /**
18
+ * Get default mic position (bottom center).
19
+ */
20
+ export declare function getDefaultPosition(): typeof DEFAULT_POSITION;
21
+ /**
22
+ * Calculate popup position based on mic position prop.
23
+ * Used for onboarding and welcome bubble placement.
24
+ */
25
+ export declare function calculatePositionFromProp(position?: GuideAIPosition | null): PopupPosition;
26
+ /**
27
+ * Get transcript box position (left or right) based on mic position.
28
+ */
29
+ export declare function getTranscriptPosition(transcriptOptions?: {
30
+ position?: TranscriptPosition;
31
+ } | null, position?: GuideAIPosition | null): TranscriptPosition;
32
+ /**
33
+ * Get z-index configuration from position prop.
34
+ */
35
+ export declare function getZIndexConfig(position?: GuideAIPosition | null): ZIndexConfig;
36
+ /**
37
+ * Get position styles for mic/base component (position only, no z-index).
38
+ */
39
+ export declare function getPositionStyles(position?: GuideAIPosition | null): Record<string, string>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tool execution registry.
3
+ * Maps function names to handlers for built-in types and api_call.
4
+ * No eval - only registered handlers or HTTP fetch for api_call.
5
+ */
6
+ export type ToolHandler = (args: Record<string, unknown>, callbacks: {
7
+ handleHighlightThenClick: (out: any) => Promise<boolean>;
8
+ handleHoverThenClick: (out: any) => Promise<boolean>;
9
+ handleHover: (out: any) => Promise<boolean>;
10
+ handleGoToAElmLink: (linkText: string, delay?: number) => Promise<boolean>;
11
+ }) => Promise<unknown>;
12
+ export interface ToolWithConfig {
13
+ toolConfig: {
14
+ type: string;
15
+ name: string;
16
+ description?: string;
17
+ parameters?: object;
18
+ };
19
+ functionConfig: {
20
+ handlerType: string;
21
+ url?: string;
22
+ };
23
+ }
24
+ /**
25
+ * Execute a tool by name using server-provided tools config and callbacks.
26
+ * Returns the result for function_call_output.
27
+ */
28
+ export declare function executeTool(name: string, args: string, toolsConfig: ToolWithConfig[], callbacks: {
29
+ handleHighlightThenClick: (out: any) => Promise<boolean>;
30
+ handleHoverThenClick: (out: any) => Promise<boolean>;
31
+ handleHover: (out: any) => Promise<boolean>;
32
+ handleGoToAElmLink: (linkText: string, delay?: number) => Promise<boolean>;
33
+ }, propHandlers?: Record<string, (args: Record<string, unknown>) => Promise<unknown>>): Promise<unknown>;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * WebRTC connection manager for OpenAI Realtime API.
3
+ * Uses unified initialize endpoint (conversation + WebRTC SDP exchange).
4
+ * See: https://developers.openai.com/api/docs/guides/realtime-webrtc
5
+ */
6
+ import { DataChannelManager, DataChannelConfig } from './dataChannel';
7
+ /** Ref-like holder for mutable references (avoids React dependency in utils) */
8
+ export interface RefLike<T> {
9
+ current: T | null;
10
+ }
11
+ export interface InitializeSessionData {
12
+ id: string;
13
+ }
14
+ export interface WebRTCConnectionConfig {
15
+ /** Microphone stream, or null for text-only mode */
16
+ audioStream: MediaStream | null;
17
+ /** Initialize endpoint URL (e.g. /api/initialize) - returns { id, answerSdp } */
18
+ initializeEndpoint: string;
19
+ /** Payload for initialize (organizationKey, user, conversationId, propTools) */
20
+ initializePayload: {
21
+ organizationKey: string;
22
+ user?: string;
23
+ conversationId?: string | null;
24
+ propTools?: {
25
+ name: string;
26
+ description: string;
27
+ parameters: object;
28
+ }[];
29
+ };
30
+ /** Called when session data is received (id) */
31
+ onSessionData?: (data: InitializeSessionData) => void;
32
+ /** Whether running in Chrome extension content script (affects audio setup) */
33
+ isContentScript?: boolean;
34
+ /** Config for the data channel manager */
35
+ dataChannelConfig: DataChannelConfig;
36
+ /** Optional refs to populate with created objects */
37
+ refs?: {
38
+ peerConnection?: RefLike<RTCPeerConnection>;
39
+ dataChannelManager?: RefLike<DataChannelManager>;
40
+ audioElement?: RefLike<HTMLAudioElement>;
41
+ };
42
+ /** Optional existing audio element to reuse (avoids duplicate elements on reconnect) */
43
+ existingAudioElement?: HTMLAudioElement | null;
44
+ }
45
+ /**
46
+ * Manages WebRTC connection via unified initialize endpoint.
47
+ * Handles peer connection setup, SDP exchange (via initialize), and data channel creation.
48
+ */
49
+ export declare class WebRTCConnection {
50
+ private config;
51
+ private peerConnection;
52
+ private dataChannelManager;
53
+ private audioElement;
54
+ constructor(config: WebRTCConnectionConfig);
55
+ /**
56
+ * Establish WebRTC connection via initialize endpoint.
57
+ */
58
+ connect(): Promise<boolean>;
59
+ private createAudioElement;
60
+ close(): void;
61
+ }
@@ -4,40 +4,37 @@ export declare class VisualContextScheduler {
4
4
  private screenshotProvider;
5
5
  private isRunning;
6
6
  private isCaptureInFlight;
7
- private hasPendingCapture;
8
- private pendingReason;
9
- private lastHash;
10
7
  private lastCaptureAt;
11
- private lastScrollAt;
12
- private lastDomBurstAt;
13
- private domChangeCounter;
14
- private domBurstWindowMs;
15
- private domBurstThreshold;
16
8
  private minIntervalMs;
17
- private scrollDebounceMs;
18
- private scrollTimer;
19
9
  private mode;
20
10
  private buttonObserver;
21
- private domObserver;
11
+ private intervalId;
22
12
  private targetWidth;
23
13
  private rootElement;
24
14
  private quality;
25
15
  private minQuality;
26
16
  private maxBytes;
27
17
  private onFrame;
18
+ private isBufferFull;
19
+ private hasSignificantDomChange;
20
+ private markDomChangeConsumed;
21
+ private onError;
22
+ private pendingRequestResolve;
28
23
  constructor(getContainer: () => HTMLElement | null, screenshotProvider: ScreenshotProvider, onFrame: (frame: ScreenshotFrame) => void, options?: {
29
24
  targetWidth?: number;
30
25
  quality?: number;
31
26
  minQuality?: number;
32
27
  maxBytes?: number;
28
+ isBufferFull?: () => boolean;
29
+ hasSignificantDomChange?: () => boolean;
30
+ markDomChangeConsumed?: () => void;
31
+ onError?: (message: string, data?: any) => void;
33
32
  });
34
33
  setRootElement(root: HTMLElement | ShadowRoot | Document): void;
35
34
  start(): void;
36
35
  stop(): void;
37
36
  private observeButtonState;
38
- private observeDomChanges;
39
- private observeScroll;
40
37
  scheduleCapture(reason: 'preview' | 'final' | 'change'): void;
38
+ requestCapture(): Promise<ScreenshotFrame | null>;
41
39
  private performCapture;
42
- private maybeRunPending;
43
40
  }
@@ -6,5 +6,5 @@ interface DebugOverlayProps {
6
6
  onToggleGallery?: () => void;
7
7
  showGallery?: boolean;
8
8
  }
9
- export declare const DebugOverlay: ({ React, frames, latencyMs, onToggleGallery, showGallery }: DebugOverlayProps) => import("react").DetailedReactHTMLElement<import("react").HTMLAttributes<HTMLElement>, HTMLElement>;
9
+ export declare const DebugOverlay: ({ React, frames, latencyMs, onToggleGallery, showGallery, }: DebugOverlayProps) => import("react").DetailedReactHTMLElement<import("react").HTMLAttributes<HTMLElement>, HTMLElement>;
10
10
  export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * DOM change tracker that detects significant host-page changes.
3
+ * Excludes only the GuideAI widget container (transcript, mic, etc.) - not by class name.
4
+ * Detects SPA navigation (route changes, visibility changes) and structural DOM changes.
5
+ */
6
+ export interface DomChangeTrackerOptions {
7
+ /** Returns the GuideAI widget root element - mutations inside it are excluded */
8
+ getGuideaiRoot: () => HTMLElement | null;
9
+ }
10
+ export interface DomChangeTracker {
11
+ hasSignificantChange: () => boolean;
12
+ markCaptured: () => void;
13
+ start: () => void;
14
+ stop: () => void;
15
+ }
16
+ export declare function createDomChangeTracker(options: DomChangeTrackerOptions): DomChangeTracker;
@@ -1,5 +1,12 @@
1
+ /**
2
+ * Visual Context module for GuideAI
3
+ * Provides screenshot capture, storage, image sending, debug overlay,
4
+ * and the useVisualContext hook for integration.
5
+ */
1
6
  export { VisualContextStore } from './VisualContextStore';
2
7
  export { VisualContextScheduler } from './VisualContextScheduler';
3
8
  export { DebugOverlay } from './debug-overlay';
9
+ export { useVisualContext } from './useVisualContext';
4
10
  export { createDefaultScreenshotProvider, getDefaultScreenshotProvider } from './defaultProvider';
5
- export type { ScreenshotResponse, ScreenshotFrame, ScreenshotOptions, ScreenshotProvider, VisualContextConfig } from './types';
11
+ export type { ScreenshotResponse, ScreenshotFrame, ScreenshotDetail, ScreenshotOptions, ScreenshotProvider, VisualContextConfig, } from './types';
12
+ export { MAX_IMAGE_MESSAGE_BYTES } from './types';
@@ -24,6 +24,10 @@ export type ScreenshotFrame = {
24
24
  sentToLLM?: boolean;
25
25
  llmReceivedAt?: number;
26
26
  };
27
+ /** Alias for ScreenshotFrame, used for event payload compatibility */
28
+ export type ScreenshotDetail = ScreenshotFrame;
29
+ /** Max size for WebRTC image message payload (bytes) */
30
+ export declare const MAX_IMAGE_MESSAGE_BYTES = 200000;
27
31
  export type ScreenshotOptions = {
28
32
  targetElement?: HTMLElement;
29
33
  targetWidth?: number;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * useVisualContext - React hook that encapsulates screenshot capture, storage,
3
+ * image sending, and debug overlay for the GuideAI visual context feature.
4
+ */
5
+ import { ScreenshotFrame, VisualContextConfig } from './types';
6
+ export type RecordingStatus = 'idle' | 'recording' | 'active' | 'processing' | 'playing';
7
+ export interface UseVisualContextParams {
8
+ options: VisualContextConfig;
9
+ sendMessage: (msg: any) => void;
10
+ isDataChannelOpen: () => boolean;
11
+ status: RecordingStatus;
12
+ isConversationActive: boolean;
13
+ getContainer: () => HTMLElement | null;
14
+ onLogVisualContext: (content: string, data?: any) => void;
15
+ onVisualContextError?: (message: string, data?: any) => void;
16
+ isBufferFull?: () => boolean;
17
+ }
18
+ export interface UseVisualContextReturn {
19
+ frames: ScreenshotFrame[];
20
+ debugEnabled: boolean;
21
+ setDebugEnabled: (value: boolean | ((prev: boolean) => boolean)) => void;
22
+ showGallery: boolean;
23
+ setShowGallery: (value: boolean | ((prev: boolean) => boolean)) => void;
24
+ latencyMs: number | null;
25
+ windowAPI: Record<string, any>;
26
+ captureForMessage: () => Promise<{
27
+ type: 'input_image';
28
+ image_url: string;
29
+ } | null>;
30
+ cleanupOnConversationEnd: () => void;
31
+ }
32
+ export declare function useVisualContext(React: typeof import('react'), params: UseVisualContextParams): UseVisualContextReturn;