@@ -6,6 +6,8 @@ const defaultIcon = 'zeuz.png';
66var zeuz_url ;
77var zeuz_key ;
88var zeuz_node_id ;
9+ const _aiContentTimers = { } ; // per-tab debounce for node_ai_contents
10+ const _aiContentHashes = { } ; // per-tab hashes to avoid resending unchanged contents
911
1012fetch ( "data.json" )
1113 . then ( Response => Response . json ( ) )
@@ -135,7 +137,7 @@ if (navigator.userAgentData.platform.toLowerCase().includes('mac')) {
135137}
136138browserAppData . runtime . onMessage . addListener (
137139 function ( request , sender , sendResponse ) {
138-
140+
139141 if ( request . action === 'toggle_from_content_script' ) {
140142 // allows the floating button to trigger the toggle logic
141143 toggle ( sender . tab ) ;
@@ -171,36 +173,71 @@ browserAppData.runtime.onMessage.addListener(
171173 . then ( text => { console . log ( text ) ; sendResponse ( text ) ; } )
172174
173175 return true ; // Will respond asynchronously.
174- } else if ( request . apiName == 'node_ai_contents' ) {
175- var url = `${ zeuz_url } /node_ai_contents/` ;
176- fetch ( url , {
177- method : "POST" ,
178- headers : {
179- // "Content-Type": "application/json",
180- "X-Api-Key" : zeuz_key ,
181- } ,
182- body : JSON . stringify ( {
183- "dom_web" : { "dom" : request . dom } ,
184- "node_id" : zeuz_node_id
185- } ) ,
186- } )
187- . then ( response => response . json ( ) )
188- . then ( text => { console . log ( text ) ; sendResponse ( text ) ; } )
176+ } else if ( request . apiName == 'node_ai_contents' ) {
177+ const tabId = sender . tab ? sender . tab . id : 'unknown' ;
178+ if ( _aiContentTimers [ tabId ] ) clearTimeout ( _aiContentTimers [ tabId ] ) ;
179+ _aiContentTimers [ tabId ] = setTimeout ( async ( ) => {
180+ delete _aiContentTimers [ tabId ] ;
181+
182+ const contentObj = { "dom" : request . dom , "page_map" : request . page_map , "page_map_json" : request . page_map_json } ;
183+ const contentStr = JSON . stringify ( contentObj ) ;
184+
185+ let hash = '' ;
186+ try {
187+ const msgUint8 = new TextEncoder ( ) . encode ( contentStr ) ;
188+ const hashBuffer = await crypto . subtle . digest ( 'SHA-256' , msgUint8 ) ;
189+ const hashArray = Array . from ( new Uint8Array ( hashBuffer ) ) ;
190+ hash = hashArray . map ( b => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ;
191+ } catch ( e ) {
192+ console . error ( "Error generating hash" , e ) ;
193+ hash = contentStr . length . toString ( ) ; // Fallback
194+ }
195+
196+ if ( _aiContentHashes [ tabId ] === hash ) {
197+ console . log ( 'node_ai_contents skipped, content unchanged for tab:' , tabId , 'hash:' , hash ) ;
198+ try { sendResponse ( { status : "skipped" } ) ; } catch ( e ) { }
199+ return ;
200+ }
201+ _aiContentHashes [ tabId ] = hash ;
202+ console . log ( 'node_ai_contents sending, new hash for tab:' , tabId , 'hash:' , hash ) ;
203+
204+ var url = `${ zeuz_url } /node_ai_contents/` ;
205+ fetch ( url , {
206+ method : "POST" ,
207+ headers : {
208+ // "Content-Type": "application/json",
209+ "X-Api-Key" : zeuz_key ,
210+ } ,
211+ body : JSON . stringify ( {
212+ "dom_web" : contentObj ,
213+ "node_id" : zeuz_node_id
214+ } ) ,
215+ } )
216+ . then ( response => {
217+ if ( ! response . ok ) {
218+ console . error ( "node_ai_contents failed with status:" , response . status , response . statusText ) ;
219+ }
220+ return response . json ( ) ;
221+ } )
222+ . then ( text => { console . log ( "node_ai_contents response:" , text ) ; try { sendResponse ( text ) ; } catch ( e ) { } } )
223+ . catch ( e => console . error ( "node_ai_contents fetch error:" , e ) ) ;
224+ } , 2000 ) ;
225+ return true ; // Will respond asynchronously.
189226 }
190227 }
191228) ;
192229
193230// add AI Inspector to the right click menu
194231browserAppData . runtime . onInstalled . addListener ( ( ) => {
195- browserAppData . contextMenus . create ( {
196- id : "toggle-ai-inspect" ,
197- title : "Inspect with AI" ,
198- contexts : [ "all" ]
199- } ) ;
232+ browserAppData . contextMenus . create ( {
233+ id : "toggle-ai-inspect" ,
234+ title : "Inspect with AI" ,
235+ contexts : [ "all" ]
236+ } ) ;
200237} ) ;
201238
202239browserAppData . contextMenus . onClicked . addListener ( ( info , tab ) => {
203- if ( info . menuItemId === "toggle-ai-inspect" && tab ) {
204- toggle ( tab ) ;
205- }
240+ if ( info . menuItemId === "toggle-ai-inspect" && tab ) {
241+ toggle ( tab ) ;
242+ }
206243} ) ;
0 commit comments