@@ -11,6 +11,7 @@ import {
1111} from "./attachment-state.js" ;
1212import { requireTrustedBlobUrl } from "./attachment-url.js" ;
1313import { latestBrowserPreview } from "./browser-preview.js" ;
14+ import { cameraErrorMessage } from "./camera-state.js" ;
1415import {
1516 formatDynamicContextStatus ,
1617 parseDynamicContextCommand
@@ -442,6 +443,9 @@ async function submitScreenAreaMessage() {
442443 if ( thinking || speaking ) {
443444 return ;
444445 }
446+ await cancelActiveAsr ( ) ;
447+ wakeCommandArmed = false ;
448+ voiceLoop = false ;
445449 const latencyTrace = new VoiceLatencyTrace ( ) ;
446450 const prompt = elements . hudInput . value . trim ( ) || defaultScreenPrompt ;
447451 const turnStarted = performance . now ( ) ;
@@ -457,6 +461,9 @@ async function submitScreenAreaMessage() {
457461 elements . hudOutput . textContent = response . text ;
458462 rememberTurn ( "user" , `[screen] ${ prompt } ` ) ;
459463 rememberTurn ( "iris" , response . text ) ;
464+ if ( response . diagnostic_path ) {
465+ logVoice ( "screen_probe_diagnostic" , response . diagnostic_path ) ;
466+ }
460467 logVoice (
461468 "screen_probe_complete" ,
462469 `model_ms=${ response . model_elapsed_ms } ; total_ms=${ Math . round ( performance . now ( ) - turnStarted ) } `
@@ -1506,7 +1513,9 @@ elements.visionButton.addEventListener("click", () => {
15061513 return ;
15071514 }
15081515 lookWithCamera ( ) . catch ( ( error ) => {
1509- elements . hudOutput . textContent = String ( error ) ;
1516+ logVoice ( "camera_snapshot_error" , String ( error ) ) ;
1517+ elements . hudOutput . textContent = cameraErrorMessage ( error ) ;
1518+ restartListeningIfReady ( ) ;
15101519 } ) ;
15111520} ) ;
15121521
@@ -1657,6 +1666,9 @@ async function readDocumentAttachment(file) {
16571666
16581667async function lookWithCamera ( ) {
16591668 const prompt = elements . hudInput . value . trim ( ) || defaultCameraPrompt ;
1669+ await cancelActiveAsr ( ) ;
1670+ wakeCommandArmed = false ;
1671+ voiceLoop = false ;
16601672 await captureCameraSnapshot ( ) ;
16611673 elements . hudInput . value = "" ;
16621674 resizeComposerInput ( ) ;
@@ -1681,10 +1693,9 @@ async function captureCameraSnapshot() {
16811693 frameRate : { ideal : 5 , max : 10 }
16821694 }
16831695 } ) ;
1684- setImageAttachment (
1685- await snapshotFromStream ( stream ) ,
1686- "Camera snapshot attached. Type what you want Iris to inspect."
1687- ) ;
1696+ const snapshot = await snapshotFromStream ( stream ) ;
1697+ await saveCameraSnapshotDiagnostic ( snapshot ) ;
1698+ setImageAttachment ( snapshot , "Camera snapshot captured. Thinking locally..." ) ;
16881699 } finally {
16891700 if ( stream ) {
16901701 for ( const track of stream . getTracks ( ) ) {
@@ -1725,11 +1736,30 @@ async function snapshotFromStream(stream) {
17251736 return {
17261737 name : "camera-snapshot.jpg" ,
17271738 bytes : Array . from ( new Uint8Array ( buffer ) ) ,
1739+ width,
1740+ height,
17281741 previewUrl : createTrustedAttachmentObjectUrl ( blob ) ,
17291742 kindLabel : "Camera"
17301743 } ;
17311744}
17321745
1746+ async function saveCameraSnapshotDiagnostic ( snapshot ) {
1747+ try {
1748+ const diagnostic = await call ( "save_camera_snapshot_diagnostic" , {
1749+ imageBytes : snapshot . bytes ,
1750+ width : snapshot . width ,
1751+ height : snapshot . height
1752+ } ) ;
1753+ const imagePath = diagnostic . imagePath || diagnostic . image_path || "" ;
1754+ logVoice (
1755+ "camera_snapshot_diagnostic" ,
1756+ `bytes=${ snapshot . bytes . length } ; width=${ snapshot . width } ; height=${ snapshot . height } ; path=${ imagePath } `
1757+ ) ;
1758+ } catch ( error ) {
1759+ logVoice ( "camera_snapshot_diagnostic_error" , String ( error ) ) ;
1760+ }
1761+ }
1762+
17331763async function snapshotFromVideoFile ( file ) {
17341764 validateVideoSize ( file ) ;
17351765 const video = document . createElement ( "video" ) ;
0 commit comments