@@ -157,36 +157,7 @@ export class ChatView extends HTMLElement {
157157 this . #structuredController. resetLastProcessed ( ) ;
158158 }
159159
160- /**
161- * Check if a message is part of an agent session
162- */
163- #isPartOfAgentSession( message : ChatMessage ) : boolean {
164- // Check if there's an AgentSessionMessage in the current messages
165- const hasAgentSession = this . #messages. some ( msg => msg . entity === ChatMessageEntity . AGENT_SESSION ) ;
166-
167- if ( ! hasAgentSession ) {
168- return false ;
169- }
170-
171- // For ModelChatMessage tool calls, check if they're from ConfigurableAgentTool
172- if ( message . entity === ChatMessageEntity . MODEL ) {
173- const modelMsg = message as ModelChatMessage ;
174- if ( modelMsg . action === 'tool' && modelMsg . toolName ) {
175- // Check if there's a corresponding tool result that's from ConfigurableAgentTool
176- const toolResultIndex = this . #messages. findIndex ( ( msg ) =>
177- msg . entity === ChatMessageEntity . TOOL_RESULT &&
178- ( msg as ToolResultMessage ) . toolName === modelMsg . toolName &&
179- ( msg as ToolResultMessage ) . toolCallId === modelMsg . toolCallId
180- ) ;
181- if ( toolResultIndex !== - 1 ) {
182- const toolResult = this . #messages[ toolResultIndex ] as ToolResultMessage ;
183- return toolResult . isFromConfigurableAgent === true ;
184- }
185- }
186- }
187-
188- return false ;
189- }
160+ // Lane-based routing: deprecated session-heuristics removed
190161
191162 // Scroll behavior handled by <ai-message-list>
192163
@@ -399,6 +370,10 @@ export class ChatView extends HTMLElement {
399370 // Render messages based on the combined structure
400371 #renderMessage( message : ChatMessage | ( ModelChatMessage & { resultText ?: string , isError ?: boolean , resultError ?: string , combined ?: boolean } ) | ( ToolResultMessage & { orphaned ?: boolean } ) , combinedIndex ?: number ) : Lit . TemplateResult {
401372 try {
373+ // Lane filter: hide agent-lane items from the main chat feed
374+ if ( ( message as any ) . uiLane === 'agent' ) {
375+ return html `` ;
376+ }
402377 switch ( message . entity ) {
403378 case ChatMessageEntity . USER :
404379 // Render User Message via dedicated renderer
@@ -439,9 +414,7 @@ export class ChatView extends HTMLElement {
439414 case ChatMessageEntity . TOOL_RESULT :
440415 {
441416 const toolResultMessage = message as ( ToolResultMessage & { orphaned ?: boolean } ) ;
442- if ( toolResultMessage . isFromConfigurableAgent ) {
443- return html `` ;
444- }
417+ // Lane-based filter already handled above
445418 if ( toolResultMessage . orphaned ) {
446419 return renderToolResultMessage ( toolResultMessage ) ;
447420 }
@@ -451,14 +424,7 @@ export class ChatView extends HTMLElement {
451424 {
452425 // Cast to the potentially combined type
453426 const modelMessage = message as ( ModelChatMessage & { resultText ?: string , isError ?: boolean , resultError ?: string , combined ?: boolean } ) ;
454-
455- // Hide tool calls that are part of agent sessions
456- if ( modelMessage . action === 'tool' ) {
457- const isPartOfSession = this . #isPartOfAgentSession( modelMessage ) ;
458- if ( isPartOfSession ) {
459- return html `` ;
460- }
461- }
427+ // Lane filter above already hides agent-managed tool calls
462428
463429 // Check if it's a combined message (tool call + result) or just a running tool call / final answer
464430 const isCombined = modelMessage . combined === true ;
@@ -497,79 +463,78 @@ export class ChatView extends HTMLElement {
497463 const icon = ToolDescriptionFormatter . getToolIcon ( toolName ) ;
498464 const descriptionData = ToolDescriptionFormatter . getToolDescription ( toolName , toolArgs ) ;
499465
500- return html ``
501- // return html`
502- // <!-- Reasoning (if any) displayed above the timeline -->
503- // ${toolReasoning ? html`
504- // <div class="message-text reasoning-text" style="margin-bottom: 8px;">
505- // ${renderMarkdown(toolReasoning, this.#markdownRenderer, this.#openInAIAssistantViewer.bind(this))}
506- // </div>
507- // ` : Lit.nothing}
508-
509- // <!-- Timeline Tool Execution -->
510- // <div class="agent-execution-timeline single-tool">
511- // <!-- Tool Header -->
512- // <div class="agent-header">
513- // <div class="agent-marker"></div>
514- // <div class="agent-title">${descriptionData.action}</div>
515- // <div class="agent-divider"></div>
516- // <button class="tool-toggle" @click=${(e: Event) => this.#toggleToolResult(e)}>
517- // <span class="toggle-icon">▼</span>
518- // </button>
519- // </div>
466+ return html `
467+ <!-- Reasoning (if any) displayed above the timeline -->
468+ ${ toolReasoning ? html `
469+ < div class ="message-text reasoning-text " style ="margin-bottom: 8px; ">
470+ ${ renderMarkdown ( toolReasoning , this . #markdownRenderer) }
471+ </ div >
472+ ` : Lit . nothing }
473+
474+ <!-- Timeline Tool Execution -->
475+ < div class ="agent-execution-timeline single-tool ">
476+ <!-- Tool Header -->
477+ < div class ="agent-header ">
478+ < div class ="agent-marker "> </ div >
479+ < div class ="agent-title "> ${ descriptionData . action } </ div >
480+ < div class ="agent-divider "> </ div >
481+ < button class ="tool-toggle " @click =${ ( e : Event ) => this . #toggleToolResult( e ) } >
482+ < span class ="toggle-icon "> ▼</ span >
483+ </ button >
484+ </ div >
520485
521- // <div class="timeline-items" style="display: none;">
522- // <div class="timeline-item">
523- // <div class="tool-line">
524- // ${descriptionData.isMultiLine ? html`
525- // <div class="tool-summary">
526- // <span class="tool-description">
527- // <span class="tool-description-indicator">└─</span>
528- // <div>${(descriptionData.content as Array<{key: string, value: string}>)[0]?.value || 'multiple parameters'}</div>
529- // </span>
530- // <span class="tool-status-marker ${status}" title="${status === 'running' ? 'Running' : status === 'completed' ? 'Completed' : status === 'error' ? 'Error' : 'Unknown'}">●</span>
531- // </div>
532- // ` : html`
533- // <span class="tool-description">
534- // <span class="tool-description-indicator">└─</span>
535- // <div>${descriptionData.content}</div>
536- // </span>
537- // <span class="tool-status-marker ${status}" title="${status === 'running' ? 'Running' : status === 'completed' ? 'Completed' : status === 'error' ? 'Error' : 'Unknown'}">●</span>
538- // `}
539- // </div>
486+ < div class ="timeline-items " style ="display: none; ">
487+ < div class ="timeline-item ">
488+ < div class ="tool-line ">
489+ ${ descriptionData . isMultiLine ? html `
490+ < div class ="tool-summary ">
491+ < span class ="tool-description ">
492+ < span class ="tool-description-indicator "> └─</ span >
493+ < div > ${ ( descriptionData . content as Array < { key : string , value : string } > ) [ 0 ] ?. value || 'multiple parameters' } </ div >
494+ </ span >
495+ < span class ="tool-status-marker ${ status } " title ="${ status === 'running' ? 'Running' : status === 'completed' ? 'Completed' : status === 'error' ? 'Error' : 'Unknown' } "> ●</ span >
496+ </ div >
497+ ` : html `
498+ < span class ="tool-description ">
499+ < span class ="tool-description-indicator "> └─</ span >
500+ < div > ${ descriptionData . content } </ div >
501+ </ span >
502+ < span class ="tool-status-marker ${ status } " title ="${ status === 'running' ? 'Running' : status === 'completed' ? 'Completed' : status === 'error' ? 'Error' : 'Unknown' } "> ●</ span >
503+ ` }
504+ </ div >
540505
541- // <!-- Result Block - Integrated within timeline item -->
542- // ${isCombined && resultText ? html`
543- // <div class="tool-result-integrated ${status}">
544- // Response:
545- // ${this.#formatJsonWithSyntaxHighlighting(resultText)}
546- // </div>
547- // ` : Lit.nothing}
548- // </div>
549- // </div>
506+ <!-- Result Block - Integrated within timeline item -->
507+ ${ isCombined && resultText ? html `
508+ < div class ="tool-result-integrated ${ status } ">
509+ Response:
510+ ${ this . #formatJsonWithSyntaxHighlighting( resultText ) }
511+ </ div >
512+ ` : Lit . nothing }
513+ </ div >
514+ </ div >
550515
551- // <!-- Loading spinner for running tools -->
552- // ${status === 'running' ? html`
553- // <div class="tool-loading">
554- // <svg class="loading-spinner" width="16" height="16" viewBox="0 0 16 16">
555- // <circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="2" fill="none" stroke-dasharray="30 12" stroke-linecap="round">
556- // <animateTransform
557- // attributeName="transform"
558- // attributeType="XML"
559- // type="rotate"
560- // from="0 8 8"
561- // to="360 8 8"
562- // dur="1s"
563- // repeatCount="indefinite" />
564- // </circle>
565- // </svg>
566- // </div>
567- // ` : Lit.nothing}
568-
569- // <!-- Error messages -->
570- // ${modelMessage.error ? html`<div class="message-error tool-error-message">Model Error: ${modelMessage.error}</div>` : Lit.nothing }
571- // </div>
572- // `;
516+ <!-- Loading spinner for running tools -->
517+ ${ status === 'running' ? html `
518+ < div class ="tool-loading ">
519+ < svg class ="loading-spinner " width ="16 " height ="16 " viewBox ="0 0 16 16 ">
520+ < circle cx ="8 " cy ="8 " r ="6 " stroke ="currentColor " stroke-width ="2 " fill ="none " stroke-dasharray ="30 12 " stroke-linecap ="round ">
521+ < animateTransform
522+ attributeName ="transform "
523+ attributeType ="XML "
524+ type ="rotate "
525+ from ="0 8 8 "
526+ to ="360 8 8 "
527+ dur ="1s "
528+ repeatCount ="indefinite " />
529+ </ circle >
530+ </ svg >
531+ </ div >
532+ ` : Lit . nothing }
533+
534+ <!-- Error messages -->
535+ ${ modelMessage . error ? html `< div class ="message-error tool-error-message "> Model Error: ${ modelMessage . error } </ div > ` : Lit . nothing }
536+ </ div >
537+ ` ;
573538 }
574539 default :
575540 // Should not happen, but render a fallback
@@ -976,6 +941,26 @@ export class ChatView extends HTMLElement {
976941 void ComponentHelpers . ScheduledRender . scheduleRender ( this , this . #boundRender) ;
977942 }
978943
944+ /**
945+ * Toggle visibility of tool result details
946+ */
947+ #toggleToolResult( event : Event ) : void {
948+ const button = event . currentTarget as HTMLElement ;
949+ const timeline = button . closest ( '.agent-execution-timeline' ) ;
950+ const items = timeline ?. querySelector ( '.timeline-items' ) as HTMLElement ;
951+ const icon = button . querySelector ( '.toggle-icon' ) as HTMLElement ;
952+
953+ if ( items ) {
954+ if ( items . style . display === 'none' ) {
955+ items . style . display = 'block' ;
956+ icon . textContent = '▲' ;
957+ } else {
958+ items . style . display = 'none' ;
959+ icon . textContent = '▼' ;
960+ }
961+ }
962+ }
963+
979964 // Stable key for message list rendering to avoid node reuse glitches
980965 #messageKey( m : CombinedMessage , index : number ) : string {
981966 // Agent sessions keyed by sessionId to ensure distinct component instances render
0 commit comments