@@ -483,10 +483,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
483483
484484 // Messages displayed in the `ChatView` component.
485485 #messages: ChatMessage [ ] = [ ] ;
486- // Indicates whether the new conversation context is blocked due to cross-origin restrictions.
487- // This happens when the conversation's context has a different
488- // origin than the selected context.
489- #blockedByCrossOrigin = false ;
486+
490487 // Whether the UI should show loading or not.
491488 #isLoading = false ;
492489 // Selected conversation context. The reason we keep this as a
@@ -545,7 +542,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
545542 } ;
546543 }
547544
548- if ( this . #conversation?. type ) {
545+ if ( this . #conversation) {
549546 const emptyStateSuggestions = await getEmptyStateSuggestions ( this . #selectedContext, this . #conversation) ;
550547 const markdownRenderer = getMarkdownRenderer ( this . #selectedContext, this . #conversation) ;
551548 return {
@@ -659,7 +656,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
659656 const isSourcesPanelVisible = viewManager . isViewVisible ( 'sources' ) ;
660657 const isPerformancePanelVisible = viewManager . isViewVisible ( 'timeline' ) ;
661658
662- let targetConversationType : AiAssistanceModel . AiHistoryStorage . ConversationType | undefined = undefined ;
659+ let targetConversationType : AiAssistanceModel . AiHistoryStorage . ConversationType | undefined ;
663660 if ( isElementsPanelVisible && hostConfig . devToolsFreestyler ?. enabled ) {
664661 targetConversationType = AiAssistanceModel . AiHistoryStorage . ConversationType . STYLING ;
665662 } else if ( isNetworkPanelVisible && hostConfig . devToolsAiAssistanceNetworkAgent ?. enabled ) {
@@ -716,8 +713,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
716713 this . #conversation = conversation ;
717714 }
718715
719- this . #onContextSelectionChanged( ) ;
720-
721716 this . requestUpdate ( ) ;
722717 }
723718
@@ -874,10 +869,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
874869 #handleUISourceCodeFlavorChange =
875870 ( ev : Common . EventTarget . EventTargetEvent < Workspace . UISourceCode . UISourceCode > ) : void => {
876871 const newFile = ev . data ;
877- if ( ! newFile ) {
878- return ;
879- }
880- if ( this . #selectedFile?. getItem ( ) === newFile ) {
872+
873+ if ( ! newFile || this . #selectedFile?. getItem ( ) === newFile ) {
881874 return ;
882875 }
883876 this . #selectedFile = new AiAssistanceModel . FileAgent . FileContext ( ev . data ) ;
@@ -1167,15 +1160,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
11671160 serializedConversation =>
11681161 AiAssistanceModel . AiConversation . AiConversation . fromSerializedConversation ( serializedConversation ) ) ;
11691162 for ( const conversation of historicalConversations . reverse ( ) ) {
1170- if ( conversation . isEmpty ) {
1171- continue ;
1172- }
1173- const title = conversation . title ;
1174- if ( ! title ) {
1163+ if ( conversation . isEmpty || ! conversation . title ) {
11751164 continue ;
11761165 }
11771166
1178- contextMenu . defaultSection ( ) . appendCheckboxItem ( title , ( ) => {
1167+ contextMenu . defaultSection ( ) . appendCheckboxItem ( conversation . title , ( ) => {
11791168 void this . #openHistoricConversation( conversation ) ;
11801169 } , { checked : ( this . #conversation === conversation ) , jslogContext : 'freestyler.history-item' } ) ;
11811170 }
@@ -1308,10 +1297,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
13081297 this . #imageInput = { isLoading : true } ;
13091298 this . requestUpdate ( ) ;
13101299 } , SHOW_LOADING_STATE_TIMEOUT ) ;
1311- const reader = new FileReader ( ) ;
1312- let dataUrl : string | undefined ;
13131300 try {
1314- dataUrl = await new Promise < string > ( ( resolve , reject ) => {
1301+ const reader = new FileReader ( ) ;
1302+ const dataUrl = await new Promise < string > ( ( resolve , reject ) => {
13151303 reader . onload = ( ) => {
13161304 if ( typeof reader . result === 'string' ) {
13171305 resolve ( reader . result ) ;
@@ -1321,31 +1309,22 @@ export class AiAssistancePanel extends UI.Panel.Panel {
13211309 } ;
13221310 reader . readAsDataURL ( file ) ;
13231311 } ) ;
1312+ const commaIndex = dataUrl . indexOf ( ',' ) ;
1313+ const bytes = dataUrl . substring ( commaIndex + 1 ) ;
1314+ this . #imageInput = {
1315+ isLoading : false ,
1316+ data : bytes ,
1317+ mimeType : file . type ,
1318+ inputType : AiAssistanceModel . AiAgent . MultimodalInputType . UPLOADED_IMAGE
1319+ } ;
13241320 } catch {
1325- clearTimeout ( showLoadingTimeout ) ;
13261321 this . #imageInput = undefined ;
1327- this . requestUpdate ( ) ;
1328- void this . updateComplete . then ( ( ) => {
1329- this . #viewOutput. chatView ?. focusTextInput ( ) ;
1330- } ) ;
13311322 Snackbars . Snackbar . Snackbar . show ( {
13321323 message : lockedString ( UIStringsNotTranslate . uploadImageFailureMessage ) ,
13331324 } ) ;
1334- return ;
13351325 }
13361326
13371327 clearTimeout ( showLoadingTimeout ) ;
1338- if ( ! dataUrl ) {
1339- return ;
1340- }
1341- const commaIndex = dataUrl . indexOf ( ',' ) ;
1342- const bytes = dataUrl . substring ( commaIndex + 1 ) ;
1343- this . #imageInput = {
1344- isLoading : false ,
1345- data : bytes ,
1346- mimeType : file . type ,
1347- inputType : AiAssistanceModel . AiAgent . MultimodalInputType . UPLOADED_IMAGE
1348- } ;
13491328 this . requestUpdate ( ) ;
13501329 void this . updateComplete . then ( ( ) => {
13511330 this . #viewOutput. chatView ?. focusTextInput ( ) ;
@@ -1357,21 +1336,18 @@ export class AiAssistancePanel extends UI.Panel.Panel {
13571336 this . #runAbortController = new AbortController ( ) ;
13581337 }
13591338
1360- #onContextSelectionChanged( ) : void {
1339+ // Indicates whether the new conversation context is blocked due to cross-origin restrictions.
1340+ // This happens when the conversation's context has a different
1341+ // origin than the selected context.
1342+ get #blockedByCrossOrigin( ) : boolean {
13611343 if ( ! this . #conversation) {
1362- this . #blockedByCrossOrigin = false ;
1363- return ;
1344+ return false ;
13641345 }
13651346 this . #selectedContext = this . #getConversationContext( this . #conversation) ;
13661347 if ( ! this . #selectedContext) {
1367- this . #blockedByCrossOrigin = false ;
1368-
1369- // Clear out any text the user has entered into the input but never
1370- // submitted now they have no active context
1371- this . #viewOutput. chatView ?. clearTextInput ( ) ;
1372- return ;
1348+ return false ;
13731349 }
1374- this . #blockedByCrossOrigin = ! this . #selectedContext. isOriginAllowed ( this . #conversation. origin ) ;
1350+ return ! this . #selectedContext. isOriginAllowed ( this . #conversation. origin ) ;
13751351 }
13761352
13771353 #getConversationContext( conversation ?: AiAssistanceModel . AiConversation . AiConversation ) :
@@ -1398,8 +1374,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
13981374 }
13991375
14001376 async #startConversation(
1401- text : string , imageInput ?: Host . AidaClient . Part ,
1402- multimodalInputType ?: AiAssistanceModel . AiAgent . MultimodalInputType ) : Promise < void > {
1377+ text : string ,
1378+ imageInput ?: Host . AidaClient . Part ,
1379+ multimodalInputType ?: AiAssistanceModel . AiAgent . MultimodalInputType ,
1380+ ) : Promise < void > {
14031381 if ( ! this . #conversation) {
14041382 return ;
14051383 }
@@ -1413,28 +1391,26 @@ export class AiAssistancePanel extends UI.Panel.Panel {
14131391 // invariants do not hold anymore.
14141392 throw new Error ( 'cross-origin context data should not be included' ) ;
14151393 }
1416- if ( this . #conversation? .isEmpty ) {
1394+ if ( this . #conversation. isEmpty ) {
14171395 Badges . UserBadges . instance ( ) . recordAction ( Badges . BadgeAction . STARTED_AI_CONVERSATION ) ;
14181396 }
1419- const image = isAiAssistanceMultimodalInputEnabled ( ) ? imageInput : undefined ;
1420- const imageId = image ? crypto . randomUUID ( ) : undefined ;
1421- const multimodalInput = image && imageId && multimodalInputType ? {
1422- input : image ,
1423- id : imageId ,
1397+ const multimodalInput = isAiAssistanceMultimodalInputEnabled ( ) && imageInput && multimodalInputType ? {
1398+ input : imageInput ,
1399+ id : crypto . randomUUID ( ) ,
14241400 type : multimodalInputType ,
14251401 } :
1426- undefined ;
1427- if ( this . #conversation) {
1428- void VisualLogging . logFunctionCall ( `start-conversation-${ this . #conversation. type } ` , 'ui' ) ;
1429- }
1402+ undefined ;
14301403
1431- const generator = this . #conversation. run (
1432- text , {
1433- signal,
1434- selected : context ,
1435- } ,
1436- multimodalInput ) ;
1437- await this . #doConversation( generator ) ;
1404+ void VisualLogging . logFunctionCall ( `start-conversation-${ this . #conversation. type } ` , 'ui' ) ;
1405+
1406+ await this . #doConversation(
1407+ this . #conversation. run (
1408+ text , {
1409+ signal,
1410+ selected : context ,
1411+ } ,
1412+ multimodalInput ) ,
1413+ ) ;
14381414 }
14391415
14401416 async #doConversation(
@@ -1607,8 +1583,7 @@ export function getResponseMarkdown(message: ModelChatMessage): string {
16071583 contentParts . push ( `### ${ step . title } ` ) ;
16081584 }
16091585 if ( step . contextDetails ) {
1610- contentParts . push (
1611- AiAssistanceModel . AiConversation . AiConversation . generateContextDetailsMarkdown ( step . contextDetails ) ) ;
1586+ contentParts . push ( AiAssistanceModel . AiConversation . generateContextDetailsMarkdown ( step . contextDetails ) ) ;
16121587 }
16131588 if ( step . thought ) {
16141589 contentParts . push ( step . thought ) ;
0 commit comments