@@ -700,16 +700,17 @@ const AgentChatPanel: Component = () => {
700700 </ div >
701701 </ Show >
702702
703+ { /* Input row: attach | textarea | send - all on one line */ }
703704 < div
704- class = "flex items-end gap-2 rounded-xl px-3 py-2"
705+ class = "flex flex-row items-end gap-2 rounded-xl px-3 py-2"
705706 style = { {
706707 background : "var(--bg-base)" ,
707708 border : "1px solid var(--border-default)" ,
708709 } }
709710 >
710- { /* Attach file button */ }
711+ { /* Attach file button - LEFT */ }
711712 < button
712- class = "flex items-center justify-center shrink-0 rounded p-1 mb-0.5 "
713+ class = "flex items-center justify-center shrink-0 rounded p-1"
713714 style = { {
714715 color : "var(--text-muted)" ,
715716 background : "transparent" ,
@@ -730,6 +731,7 @@ const AgentChatPanel: Component = () => {
730731 </ svg >
731732 </ button >
732733
734+ { /* Textarea - CENTER */ }
733735 < textarea
734736 ref = { inputRef }
735737 class = "flex-1 resize-none outline-none"
@@ -746,10 +748,10 @@ const AgentChatPanel: Component = () => {
746748 } }
747749 placeholder = {
748750 queuedMessages ( ) . length > 0
749- ? `Message queued ( ${ queuedMessages ( ) . length } in line) — Shift+Enter to force push `
751+ ? `${ queuedMessages ( ) . length } queued — Shift+Enter to force`
750752 : ( agentStreaming ( ) || clifInitializing ( ) )
751- ? "Type to queue next message ..."
752- : "Ask the agent... (paste images with ⌘V )"
753+ ? "Type to queue..."
754+ : "Ask the agent... (@ for files )"
753755 }
754756 rows = { 1 }
755757 value = { inputValue ( ) }
@@ -778,166 +780,119 @@ const AgentChatPanel: Component = () => {
778780 onPaste = { handlePaste }
779781 />
780782
781- { /* Queued messages badge */ }
782- < Show when = { queuedMessages ( ) . length > 0 } >
783- < button
784- class = "absolute top-[-8px] right-[-8px] z-10 flex items-center justify-center rounded-full"
785- style = { {
786- background : "var(--accent-primary)" ,
787- color : "#fff" ,
788- "font-size" : "11px" ,
789- "min-width" : "20px" ,
790- height : "20px" ,
791- padding : "0 6px" ,
792- "font-weight" : "600" ,
793- border : "2px solid var(--bg-base)" ,
794- cursor : "pointer" ,
795- } }
796- onClick = { ( ) => handleSend ( true ) }
797- title = { `Force push: cancel current agent and send next message (${ queuedMessages ( ) . length } queued)` }
798- >
799- { queuedMessages ( ) . length }
800- </ button >
801- </ Show >
802- </ div >
803-
804- < div class = "flex items-center justify-between mt-1 px-1" >
805- { /* Send / Stop streaming button */ }
783+ { /* Send / Stop / Queue button - RIGHT */ }
806784 < Show
807- when = { ! agentStreaming ( ) }
785+ when = { agentStreaming ( ) }
808786 fallback = {
809787 < Show
810- when = { inputValue ( ) . trim ( ) }
788+ when = { queuedMessages ( ) . length > 0 }
811789 fallback = {
812790 < button
813- class = "flex items-center justify-center shrink-0 rounded-lg p-1.5 mb-0.5 transition-colors"
791+ class = "flex items-center justify-center shrink-0 rounded-lg p-1.5 transition-colors"
814792 style = { {
815- background : "color-mix(in srgb, var(--accent-red) 12%, transparent)" ,
816- color : "var(--accent-red)" ,
817- border : "1px solid color-mix(in srgb, var(--accent-red) 25%, transparent)" ,
818- cursor : "pointer" ,
793+ background : ( inputValue ( ) . trim ( ) || pastedImages ( ) . length > 0 )
794+ ? "var(--accent-primary)"
795+ : "var(--bg-hover)" ,
796+ color : ( inputValue ( ) . trim ( ) || pastedImages ( ) . length > 0 ) ? "#fff" : "var(--text-muted)" ,
797+ border : "none" ,
798+ cursor : ( inputValue ( ) . trim ( ) || pastedImages ( ) . length > 0 ) ? "pointer" : "default" ,
819799 } }
820- onClick = { stopAgent }
821- title = "Stop streaming response"
800+ onClick = { ( ) => handleSend ( false ) }
801+ disabled = { ! inputValue ( ) . trim ( ) && pastedImages ( ) . length === 0 }
802+ title = "Send message"
822803 >
823- < StopIcon />
804+ < SendIcon />
824805 </ button >
825806 }
826807 >
827- { /* Queue button — send after agent finishes */ }
828808 < button
829- class = "flex items-center justify-center shrink-0 rounded-lg p-1.5 mb-0.5 transition-colors"
809+ class = "flex items-center justify-center shrink-0 rounded-lg px-2 py-1 transition-colors"
830810 style = { {
831- background : "color-mix(in srgb, var(--accent-primary) 15%, transparent )" ,
832- color : "var(--accent-primary) " ,
833- border : "1px solid color-mix(in srgb, var(--accent-primary) 30%, transparent) " ,
811+ background : "var(--accent-primary)" ,
812+ color : "#fff " ,
813+ border : "none " ,
834814 cursor : "pointer" ,
815+ "font-size" : "11px" ,
816+ "font-weight" : "500" ,
835817 } }
836- onClick = { ( ) => handleSend ( false ) }
837- title = "Queue message — sends when agent finishes "
818+ onClick = { ( ) => handleSend ( true ) }
819+ title = "Force send now "
838820 >
839- < svg width = "13" height = "13" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2.5" stroke-linecap = "round" stroke-linejoin = "round" >
840- < line x1 = "12" y1 = "5" x2 = "12" y2 = "19" /> < polyline points = "19 12 12 19 5 12" />
841- </ svg >
821+ { queuedMessages ( ) . length }
822+ < span style = { { opacity : 0.8 , "margin-left" : "4px" } } > Force</ span >
842823 </ button >
843824 </ Show >
844825 }
845826 >
846827 < button
847- class = "flex items-center justify-center shrink-0 rounded-lg p-1.5 mb-0.5 transition-colors"
828+ class = "flex items-center justify-center shrink-0 rounded-lg p-1.5 transition-colors"
848829 style = { {
849- background : ( inputValue ( ) . trim ( ) || pastedImages ( ) . length > 0 )
850- ? "var(--accent-primary)"
851- : "var(--bg-hover)" ,
852- color : ( inputValue ( ) . trim ( ) || pastedImages ( ) . length > 0 ) ? "#fff" : "var(--text-muted)" ,
830+ background : "var(--accent-red)" ,
831+ color : "#fff" ,
853832 border : "none" ,
854- cursor : ( inputValue ( ) . trim ( ) || pastedImages ( ) . length > 0 ) ? "pointer" : "default ",
833+ cursor : "pointer" ,
855834 } }
856- onClick = { ( ) => handleSend ( false ) }
857- disabled = { ! inputValue ( ) . trim ( ) && pastedImages ( ) . length === 0 }
858- title = "Send message"
835+ onClick = { stopAgent }
836+ title = "Stop agent"
859837 >
860- < SendIcon />
838+ < StopIcon />
861839 </ button >
862840 </ Show >
863841 </ div >
842+
843+ { /* Status bar: streaming | web search + tokens - ONE LINE */ }
864844 < div
865- class = "flex items-center justify-between mt-1 px-1"
866- style = { { " font-size" : ` ${ fontSize ( ) - 4 } px` , color : "var(--text-muted)" } }
845+ class = "flex flex-row items-center justify-between mt-2 px-1"
846+ style = { { height : "20px" , " font-size" : "12px" , color : "var(--text-muted)" } }
867847 >
868- { /* Left: status or hint */ }
869- < Show when = { agentStreaming ( ) }
870- fallback = { < span > Enter to send, Shift+Enter for newline</ span > }
871- >
872- < div class = "flex items-center gap-1.5" >
873- < span
874- class = "inline-block animate-pulse"
875- style = { { width : "5px" , height : "5px" , "border-radius" : "50%" , background : "var(--accent-yellow)" , "flex-shrink" : "0" } }
876- />
877- < span > Agent running</ span >
878- < button
879- class = "flex items-center gap-1 rounded px-1.5 py-0.5 transition-colors"
880- style = { {
881- background : "transparent" , color : "var(--text-muted)" ,
882- border : "1px solid var(--border-default)" , cursor : "pointer" ,
883- "font-size" : `${ fontSize ( ) - 4 } px` , "font-weight" : "600" ,
884- } }
885- onMouseEnter = { ( e ) => {
886- ( e . currentTarget as HTMLElement ) . style . background = "color-mix(in srgb, var(--accent-red) 10%, transparent)" ;
887- ( e . currentTarget as HTMLElement ) . style . color = "var(--accent-red)" ;
888- ( e . currentTarget as HTMLElement ) . style . borderColor = "color-mix(in srgb, var(--accent-red) 25%, transparent)" ;
889- } }
890- onMouseLeave = { ( e ) => {
891- ( e . currentTarget as HTMLElement ) . style . background = "transparent" ;
892- ( e . currentTarget as HTMLElement ) . style . color = "var(--text-muted)" ;
893- ( e . currentTarget as HTMLElement ) . style . borderColor = "var(--border-default)" ;
894- } }
895- onClick = { stopAgent }
896- title = "Stop all agent tasks"
897- >
898- < StopIcon />
899- Stop
900- </ button >
901- </ div >
902- </ Show >
903- < div class = "flex items-center gap-2" >
904- { /* Web search toggle */ }
848+ { /* Left: streaming indicator */ }
849+ < div class = "flex items-center" style = { { "min-width" : "0" } } >
850+ < Show when = { agentStreaming ( ) } >
851+ < div class = "flex items-center gap-2" >
852+ < span
853+ class = "inline-block animate-pulse"
854+ style = { { width : "8px" , height : "8px" , "border-radius" : "50%" , background : "var(--accent-yellow)" , "flex-shrink" : "0" } }
855+ />
856+ < span style = { { "font-weight" : "500" } } > Running...</ span >
857+ </ div >
858+ </ Show >
859+ </ div >
860+
861+ { /* Right: web search + tokens */ }
862+ < div class = "flex items-center gap-4" style = { { "flex-shrink" : "0" } } >
905863 < Show when = { settings ( ) . aiProvider === "openrouter" } >
906864 < button
907- class = "flex items-center gap-1 rounded px-1.5 py-0.5 transition-all "
865+ class = "flex items-center gap-1.5 px-2 py-1 rounded-md transition-colors "
908866 style = { {
909- background : webSearchEnabled ( )
910- ? "color-mix(in srgb, var(--accent-blue) 15%, transparent)"
911- : "transparent" ,
912867 color : webSearchEnabled ( ) ? "var(--accent-blue)" : "var(--text-muted)" ,
913- border : webSearchEnabled ( )
914- ? "1px solid color-mix(in srgb, var(--accent-blue) 30%, transparent)"
915- : "1px solid transparent" ,
868+ background : webSearchEnabled ( ) ? "rgba(59, 130, 246, 0.1)" : "transparent" ,
869+ border : "none" ,
916870 cursor : "pointer" ,
917- "font-size" : ` ${ fontSize ( ) - 4 } px` ,
918- "font-family " : "var(--font-sans) " ,
871+ "font-size" : "12px" ,
872+ "font-weight " : "500 " ,
919873 } }
920- onMouseEnter = { ( e ) => { if ( ! webSearchEnabled ( ) ) ( e . currentTarget as HTMLElement ) . style . background = "var(--bg-hover)" ; } }
921- onMouseLeave = { ( e ) => { if ( ! webSearchEnabled ( ) ) ( e . currentTarget as HTMLElement ) . style . background = "transparent" ; } }
922874 onClick = { ( ) => setWebSearchEnabled ( ! webSearchEnabled ( ) ) }
923- title = { webSearchEnabled ( )
924- ? "Web search ON — model will fetch live results ($0.004/search)"
925- : "Enable web search — appends :online to model via OpenRouter" }
875+ title = { webSearchEnabled ( ) ? "Web search enabled" : "Enable web search" }
926876 >
927- < svg width = "10" height = "10" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2.5" stroke-linecap = "round" stroke-linejoin = "round" >
928- < circle cx = "12" cy = "12" r = "10" /> < line x1 = "2" y1 = "12" x2 = "22" y2 = "12" /> < path d = "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
877+ < svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2.5" stroke-linecap = "round" stroke-linejoin = "round" >
878+ < circle cx = "12" cy = "12" r = "10" />
879+ < line x1 = "2" y1 = "12" x2 = "22" y2 = "12" />
880+ < path d = "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
929881 </ svg >
930- { webSearchEnabled ( ) ? "Search on" : "Search" }
882+ < span >
883+ { webSearchEnabled ( ) ? "Web on" : "Web" }
884+ </ span >
931885 </ button >
932886 </ Show >
887+
933888 < Show when = { agentTokens ( ) . prompt > 0 } >
934- < span style = { { "font-family" : "var(--font-mono, monospace)" } } >
889+ < span style = { { "font-family" : "var(--font-mono, monospace)" , opacity : 0.8 , "font-size" : "12px" } } >
935890 { ( ( ) => {
936891 const t = agentTokens ( ) ;
937892 const total = t . prompt + t . completion ;
938893 const cost = ( t . prompt * 3 + t . completion * 15 ) / 1_000_000 ;
939894 const totalStr = total >= 1000 ? `${ ( total / 1000 ) . toFixed ( 1 ) } k` : `${ total } ` ;
940- return `${ totalStr } tokens · ~ $${ cost . toFixed ( 4 ) } ` ;
895+ return `${ totalStr } · $${ cost . toFixed ( 4 ) } ` ;
941896 } ) ( ) }
942897 </ span >
943898 </ Show >
0 commit comments