server, webui: support continue generation on reasoning models (#22727)

* server, webui : support continue generation on reasoning models (#22727)

Remove the throw blocking assistant prefill on reasoning models and
orchestrate thinking tags around the prefilled message so the parser
routes the next stream chunks correctly. WebUI drops the reasoning
guard on the Continue button, sends reasoning_content with the
prefilled message and persists partial reasoning on stop so the CoT
survives reload and resume.

Scope : templates with a simple thinking_start_tag / thinking_end_tag
pair. Channel-based templates like GPT-OSS are out of scope, pending
a per-template prefill API in common/chat.

First step toward #21754.

* chore: update webui build output

* server: reject reasoning prefill on channel based templates
This commit is contained in:
Pascal
2026-05-13 11:09:51 +02:00
committed by GitHub
parent 3796c94bad
commit 5d44db6008
5 changed files with 250 additions and 193 deletions
+159 -158
View File
@@ -1371,15 +1371,15 @@ type:SettingsFieldType.SELECT,section:SETTINGS_SECTION_SLUGS.GENERAL,options:COL
behave.",defaultValue:"",type:SettingsFieldType.TEXTAREA,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.SYSTEM_MESSAGE,paramType:SyncableParameterType.STRING}},{key:SETTINGS_KEYS.PASTE_LONG_TEXT_TO_FILE_LEN,label:"Paste long text to file length",help:"On pasting long text, it will be converted to a file. You can control the file length by setting the value of this parameter. Value 0 means disable.",defaultValue:2500,type:SettingsFieldType.INPUT,section:SETTINGS_SECTION_SLUGS. behave.",defaultValue:"",type:SettingsFieldType.TEXTAREA,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.SYSTEM_MESSAGE,paramType:SyncableParameterType.STRING}},{key:SETTINGS_KEYS.PASTE_LONG_TEXT_TO_FILE_LEN,label:"Paste long text to file length",help:"On pasting long text, it will be converted to a file. You can control the file length by setting the value of this parameter. Value 0 means disable.",defaultValue:2500,type:SettingsFieldType.INPUT,section:SETTINGS_SECTION_SLUGS.
GENERAL,sync:{serverKey:SETTINGS_KEYS.PASTE_LONG_TEXT_TO_FILE_LEN,paramType:SyncableParameterType.NUMBER}},{key:SETTINGS_KEYS.SEND_ON_ENTER,label:"Send message on Enter",help:"Use Enter to send messages and Shift + Enter for new lines. When disabled, use Ctrl/Cmd + Enter.",defaultValue:!0,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.SEND_ON_ENTER,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT, GENERAL,sync:{serverKey:SETTINGS_KEYS.PASTE_LONG_TEXT_TO_FILE_LEN,paramType:SyncableParameterType.NUMBER}},{key:SETTINGS_KEYS.SEND_ON_ENTER,label:"Send message on Enter",help:"Use Enter to send messages and Shift + Enter for new lines. When disabled, use Ctrl/Cmd + Enter.",defaultValue:!0,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.SEND_ON_ENTER,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT,
label:"Copy text attachments as plain text",help:"When copying a message with text attachments, combine them into a single plain text string instead of a special format that can be pasted back as attachments.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION,label:'Enable "Continue" button',help:'Enable "Co\ label:"Copy text attachments as plain text",help:"When copying a message with text attachments, combine them into a single plain text string instead of a special format that can be pasted back as attachments.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION,label:'Enable "Continue" button',help:'Enable "Co\
ntinue" button for assistant messages. Currently works only with non-reasoning models.',defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,isExperimental:!0,sync:{serverKey:SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.PDF_AS_IMAGE,label:"Parse PDF as image",help:"Parse PDF as image instead of text. Automatically falls back to text processing for non-vision models.",defaultValue:!1,type:SettingsFieldType. ntinue" button for assistant messages, including reasoning models.',defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,isExperimental:!0,sync:{serverKey:SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.PDF_AS_IMAGE,label:"Parse PDF as image",help:"Parse PDF as image instead of text. Automatically falls back to text processing for non-vision models.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.
CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.PDF_AS_IMAGE,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ASK_FOR_TITLE_CONFIRMATION,label:"Ask for confirmation before changing conversation title",help:"Ask for confirmation before automatically changing conversation title when editing the first message.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.ASK_FOR_TITLE_CONFIRMATION,paramType:SyncableParameterType. GENERAL,sync:{serverKey:SETTINGS_KEYS.PDF_AS_IMAGE,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ASK_FOR_TITLE_CONFIRMATION,label:"Ask for confirmation before changing conversation title",help:"Ask for confirmation before automatically changing conversation title when editing the first message.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.ASK_FOR_TITLE_CONFIRMATION,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.
BOOLEAN}},{key:SETTINGS_KEYS.TITLE_GENERATION_USE_FIRST_LINE,label:"Use first non-empty line for conversation title",help:"Use only the first non-empty line of the prompt to generate the conversation title.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.TITLE_GENERATION_USE_FIRST_LINE,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.TITLE_GENERATION_USE_LLM,label:"Use LLM to generate conversation title",help:"Use \ TITLE_GENERATION_USE_FIRST_LINE,label:"Use first non-empty line for conversation title",help:"Use only the first non-empty line of the prompt to generate the conversation title.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,sync:{serverKey:SETTINGS_KEYS.TITLE_GENERATION_USE_FIRST_LINE,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.TITLE_GENERATION_USE_LLM,label:"Use LLM to generate conversation title",help:"Use the LLM to automatically gene\
the LLM to automatically generate conversation titles based on the first message exchange.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,isExperimental:!0},{key:SETTINGS_KEYS.TITLE_GENERATION_PROMPT,label:"LLM title generation prompt",help:"Optional template for the title generation prompt. Use {{USER}} for the user message and {{ASSISTANT}} for the assistant message.",defaultValue:TITLE_GENERATION.DEFAULT_PROMPT,type:SettingsFieldType.TEXTAREA,section:SETTINGS_SECTION_SLUGS. rate conversation titles based on the first message exchange.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.GENERAL,isExperimental:!0},{key:SETTINGS_KEYS.TITLE_GENERATION_PROMPT,label:"LLM title generation prompt",help:"Optional template for the title generation prompt. Use {{USER}} for the user message and {{ASSISTANT}} for the assistant message.",defaultValue:TITLE_GENERATION.DEFAULT_PROMPT,type:SettingsFieldType.TEXTAREA,section:SETTINGS_SECTION_SLUGS.GENERAL}]},
GENERAL}]},[SETTINGS_SECTION_SLUGS.DISPLAY]:{title:SETTINGS_SECTION_TITLES.DISPLAY,slug:SETTINGS_SECTION_SLUGS.DISPLAY,icon:Monitor,settings:[{key:SETTINGS_KEYS.SHOW_MESSAGE_STATS,label:"Show message generation statistics",help:"Display generation statistics (tokens/second, token count, duration) below each assistant message.",defaultValue:!0,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_MESSAGE_STATS,paramType:SyncableParameterType.BOOLEAN}}, [SETTINGS_SECTION_SLUGS.DISPLAY]:{title:SETTINGS_SECTION_TITLES.DISPLAY,slug:SETTINGS_SECTION_SLUGS.DISPLAY,icon:Monitor,settings:[{key:SETTINGS_KEYS.SHOW_MESSAGE_STATS,label:"Show message generation statistics",help:"Display generation statistics (tokens/second, token count, duration) below each assistant message.",defaultValue:!0,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_MESSAGE_STATS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.
{key:SETTINGS_KEYS.SHOW_THOUGHT_IN_PROGRESS,label:"Show thought in progress",help:"Expand thought process by default when generating messages.",defaultValue:!0,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_THOUGHT_IN_PROGRESS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS,label:"Show tool call in progress",help:"Automatically expand tool call details while executing and keep them expanded after c\ SHOW_THOUGHT_IN_PROGRESS,label:"Show thought in progress",help:"Expand thought process by default when generating messages.",defaultValue:!0,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_THOUGHT_IN_PROGRESS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS,label:"Show tool call in progress",help:"Automatically expand tool call details while executing and keep them expanded after completion.",defaultValue:!1,
ompletion.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.KEEP_STATS_VISIBLE,label:"Keep stats visible after generation",help:"Keep processing statistics visible after generation finishes.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.KEEP_STATS_VISIBLE,paramType:SyncableParameterType. type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.KEEP_STATS_VISIBLE,label:"Keep stats visible after generation",help:"Keep processing statistics visible after generation finishes.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.KEEP_STATS_VISIBLE,paramType:SyncableParameterType.BOOLEAN}},{
BOOLEAN}},{key:SETTINGS_KEYS.AUTO_MIC_ON_EMPTY,label:"Show microphone on empty input",help:"Automatically show microphone button instead of send button when textarea is empty for models with audio modality support.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,isExperimental:!0,sync:{serverKey:SETTINGS_KEYS.AUTO_MIC_ON_EMPTY,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN,label:"Render user content as Markdown", key:SETTINGS_KEYS.AUTO_MIC_ON_EMPTY,label:"Show microphone on empty input",help:"Automatically show microphone button instead of send button when textarea is empty for models with audio modality support.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,isExperimental:!0,sync:{serverKey:SETTINGS_KEYS.AUTO_MIC_ON_EMPTY,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN,label:"Render user content as Markdown",help:"Ren\
help:"Render user messages using markdown formatting in the chat.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.FULL_HEIGHT_CODE_BLOCKS,label:"Use full height code blocks",help:"Always display code blocks at their full natural height, overriding any height limits.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS. der user messages using markdown formatting in the chat.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.FULL_HEIGHT_CODE_BLOCKS,label:"Use full height code blocks",help:"Always display code blocks at their full natural height, overriding any height limits.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.
DISPLAY,sync:{serverKey:SETTINGS_KEYS.FULL_HEIGHT_CODE_BLOCKS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.DISABLE_AUTO_SCROLL,label:"Disable automatic scroll",help:"Disable automatic scrolling while messages stream so you can control the viewport position manually.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.DISABLE_AUTO_SCROLL,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ALWAYS_SHOW_SIDEBAR_ON_DESKTOP, DISPLAY,sync:{serverKey:SETTINGS_KEYS.FULL_HEIGHT_CODE_BLOCKS,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.DISABLE_AUTO_SCROLL,label:"Disable automatic scroll",help:"Disable automatic scrolling while messages stream so you can control the viewport position manually.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.DISABLE_AUTO_SCROLL,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ALWAYS_SHOW_SIDEBAR_ON_DESKTOP,
label:"Always show sidebar on desktop",help:"Always keep the sidebar visible on desktop instead of auto-hiding it.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.ALWAYS_SHOW_SIDEBAR_ON_DESKTOP,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.SHOW_RAW_MODEL_NAMES,label:"Show raw model names",help:'Display full raw model identifiers (e.g. "ggml-org/GLM-4.7-Flash-GGUF:Q8_0") instead of parsed names with badges.',defaultValue:!1, label:"Always show sidebar on desktop",help:"Always keep the sidebar visible on desktop instead of auto-hiding it.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.ALWAYS_SHOW_SIDEBAR_ON_DESKTOP,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.SHOW_RAW_MODEL_NAMES,label:"Show raw model names",help:'Display full raw model identifiers (e.g. "ggml-org/GLM-4.7-Flash-GGUF:Q8_0") instead of parsed names with badges.',defaultValue:!1,
type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_RAW_MODEL_NAMES,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS,label:"Always show agentic turns in conversation",help:"Always expand and display agentic loop turns in conversation messages.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS,paramType:SyncableParameterType. type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.SHOW_RAW_MODEL_NAMES,paramType:SyncableParameterType.BOOLEAN}},{key:SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS,label:"Always show agentic turns in conversation",help:"Always expand and display agentic loop turns in conversation messages.",defaultValue:!1,type:SettingsFieldType.CHECKBOX,section:SETTINGS_SECTION_SLUGS.DISPLAY,sync:{serverKey:SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS,paramType:SyncableParameterType.
@@ -6473,140 +6473,141 @@ id,!1);return}console.error("Failed to send message:",error2),this.setChatLoadin
if(isRouterMode()&&!effectiveModel){const conversationModel=this.getConversationModel(allMessages);effectiveModel=selectedModelName()||conversationModel}isRouterMode()&&effectiveModel&&(modelsStore.getModelProps(effectiveModel)||await modelsStore.fetchModelProps(effectiveModel));let currentMessageId=assistantMessage.id,streamedContent="",streamedReasoningContent="",resolvedModel=null,modelPersisted=!1;const convId=assistantMessage.convId,recordModel=(modelName,persistImmediately=!0)=>{if(!modelName) if(isRouterMode()&&!effectiveModel){const conversationModel=this.getConversationModel(allMessages);effectiveModel=selectedModelName()||conversationModel}isRouterMode()&&effectiveModel&&(modelsStore.getModelProps(effectiveModel)||await modelsStore.fetchModelProps(effectiveModel));let currentMessageId=assistantMessage.id,streamedContent="",streamedReasoningContent="",resolvedModel=null,modelPersisted=!1;const convId=assistantMessage.convId,recordModel=(modelName,persistImmediately=!0)=>{if(!modelName)
return;const n=normalizeModelName(modelName);if(!n||n===resolvedModel)return;resolvedModel=n;const idx=conversationsStore.findMessageIndex(currentMessageId);conversationsStore.updateMessageAtIndex(idx,{model:n}),persistImmediately&&!modelPersisted&&(modelPersisted=!0,DatabaseService.updateMessage(currentMessageId,{model:n}).catch(()=>{modelPersisted=!1,resolvedModel=null}))},updateStreamingUI=()=>{this.setChatStreaming(convId,streamedContent,currentMessageId);const idx=conversationsStore.findMessageIndex( return;const n=normalizeModelName(modelName);if(!n||n===resolvedModel)return;resolvedModel=n;const idx=conversationsStore.findMessageIndex(currentMessageId);conversationsStore.updateMessageAtIndex(idx,{model:n}),persistImmediately&&!modelPersisted&&(modelPersisted=!0,DatabaseService.updateMessage(currentMessageId,{model:n}).catch(()=>{modelPersisted=!1,resolvedModel=null}))},updateStreamingUI=()=>{this.setChatStreaming(convId,streamedContent,currentMessageId);const idx=conversationsStore.findMessageIndex(
currentMessageId);conversationsStore.updateMessageAtIndex(idx,{content:streamedContent})},cleanupStreamingState=()=>{this.setStreamingActive(!1),this.setChatLoading(convId,!1),this.clearChatStreaming(convId),this.setProcessingState(convId,null)};this.setStreamingActive(!0),this.setActiveProcessingConversation(convId);const abortController=this.getOrCreateAbortController(convId),streamCallbacks={onChunk:chunk=>{streamedContent+=chunk,updateStreamingUI()},onReasoningChunk:chunk=>{streamedReasoningContent+= currentMessageId);conversationsStore.updateMessageAtIndex(idx,{content:streamedContent})},cleanupStreamingState=()=>{this.setStreamingActive(!1),this.setChatLoading(convId,!1),this.clearChatStreaming(convId),this.setProcessingState(convId,null)};this.setStreamingActive(!0),this.setActiveProcessingConversation(convId);const abortController=this.getOrCreateAbortController(convId),streamCallbacks={onChunk:chunk=>{streamedContent+=chunk,updateStreamingUI()},onReasoningChunk:chunk=>{streamedReasoningContent+=
chunk;const idx=conversationsStore.findMessageIndex(currentMessageId);conversationsStore.updateMessageAtIndex(idx,{reasoningContent:streamedReasoningContent})},onToolCallsStreaming:toolCalls=>{const idx=conversationsStore.findMessageIndex(currentMessageId);conversationsStore.updateMessageAtIndex(idx,{toolCalls:JSON.stringify(toolCalls)})},onAttachments:(messageId,extras)=>{if(!extras.length)return;const idx=conversationsStore.findMessageIndex(messageId);if(idx===-1)return;const updatedExtras=[...conversationsStore. chunk,this.setChatStreaming(convId,streamedContent,currentMessageId);const idx=conversationsStore.findMessageIndex(currentMessageId);conversationsStore.updateMessageAtIndex(idx,{reasoningContent:streamedReasoningContent})},onToolCallsStreaming:toolCalls=>{const idx=conversationsStore.findMessageIndex(currentMessageId);conversationsStore.updateMessageAtIndex(idx,{toolCalls:JSON.stringify(toolCalls)})},onAttachments:(messageId,extras)=>{if(!extras.length)return;const idx=conversationsStore.findMessageIndex(
activeMessages[idx].extra||[],...extras];conversationsStore.updateMessageAtIndex(idx,{extra:updatedExtras}),DatabaseService.updateMessage(messageId,{extra:updatedExtras}).catch(console.error)},onModel:modelName=>recordModel(modelName),onTurnComplete:intermediateTimings=>{const idx=conversationsStore.findMessageIndex(assistantMessage.id);conversationsStore.updateMessageAtIndex(idx,{timings:intermediateTimings})},onTimings:(timings,promptProgress)=>{const tokensPerSecond=timings?.predicted_ms&&timings?. messageId);if(idx===-1)return;const updatedExtras=[...conversationsStore.activeMessages[idx].extra||[],...extras];conversationsStore.updateMessageAtIndex(idx,{extra:updatedExtras}),DatabaseService.updateMessage(messageId,{extra:updatedExtras}).catch(console.error)},onModel:modelName=>recordModel(modelName),onTurnComplete:intermediateTimings=>{const idx=conversationsStore.findMessageIndex(assistantMessage.id);conversationsStore.updateMessageAtIndex(idx,{timings:intermediateTimings})},onTimings:(timings,promptProgress)=>{
predicted_n?timings.predicted_n/timings.predicted_ms*1e3:0;this.updateProcessingStateFromTimings({prompt_n:timings?.prompt_n||0,prompt_ms:timings?.prompt_ms,predicted_n:timings?.predicted_n||0,predicted_per_second:tokensPerSecond,cache_n:timings?.cache_n||0,prompt_progress:promptProgress},convId)},onAssistantTurnComplete:async(content2,reasoningContent,timings,toolCalls)=>{const updateData={content:content2,reasoningContent:reasoningContent||void 0,toolCalls:toolCalls?JSON.stringify(toolCalls):"", const tokensPerSecond=timings?.predicted_ms&&timings?.predicted_n?timings.predicted_n/timings.predicted_ms*1e3:0;this.updateProcessingStateFromTimings({prompt_n:timings?.prompt_n||0,prompt_ms:timings?.prompt_ms,predicted_n:timings?.predicted_n||0,predicted_per_second:tokensPerSecond,cache_n:timings?.cache_n||0,prompt_progress:promptProgress},convId)},onAssistantTurnComplete:async(content2,reasoningContent,timings,toolCalls)=>{const updateData={content:content2,reasoningContent:reasoningContent||
timings};resolvedModel&&!modelPersisted&&(updateData.model=resolvedModel),await DatabaseService.updateMessage(currentMessageId,updateData);const idx=conversationsStore.findMessageIndex(currentMessageId),uiUpdate={content:content2,reasoningContent:reasoningContent||void 0,toolCalls:toolCalls?JSON.stringify(toolCalls):""};timings&&(uiUpdate.timings=timings),resolvedModel&&(uiUpdate.model=resolvedModel),conversationsStore.updateMessageAtIndex(idx,uiUpdate),await conversationsStore.updateCurrentNode( void 0,toolCalls:toolCalls?JSON.stringify(toolCalls):"",timings};resolvedModel&&!modelPersisted&&(updateData.model=resolvedModel),await DatabaseService.updateMessage(currentMessageId,updateData);const idx=conversationsStore.findMessageIndex(currentMessageId),uiUpdate={content:content2,reasoningContent:reasoningContent||void 0,toolCalls:toolCalls?JSON.stringify(toolCalls):""};timings&&(uiUpdate.timings=timings),resolvedModel&&(uiUpdate.model=resolvedModel),conversationsStore.updateMessageAtIndex(
currentMessageId)},createToolResultMessage:async(toolCallId,content2,extras)=>{const msg=await DatabaseService.createMessageBranch({convId,type:MessageType.TEXT,role:MessageRole.TOOL,content:content2,toolCallId,timestamp:Date.now(),toolCalls:"",children:[],extra:extras},currentMessageId);return conversationsStore.addMessageToActive(msg),await conversationsStore.updateCurrentNode(msg.id),msg},createAssistantMessage:async()=>{streamedContent="",streamedReasoningContent="";const lastMsg=conversationsStore. idx,uiUpdate),await conversationsStore.updateCurrentNode(currentMessageId)},createToolResultMessage:async(toolCallId,content2,extras)=>{const msg=await DatabaseService.createMessageBranch({convId,type:MessageType.TEXT,role:MessageRole.TOOL,content:content2,toolCallId,timestamp:Date.now(),toolCalls:"",children:[],extra:extras},currentMessageId);return conversationsStore.addMessageToActive(msg),await conversationsStore.updateCurrentNode(msg.id),msg},createAssistantMessage:async()=>{streamedContent=
activeMessages[conversationsStore.activeMessages.length-1],msg=await DatabaseService.createMessageBranch({convId,type:MessageType.TEXT,role:MessageRole.ASSISTANT,content:"",timestamp:Date.now(),toolCalls:"",children:[],model:resolvedModel},lastMsg.id);return conversationsStore.addMessageToActive(msg),currentMessageId=msg.id,msg},onFlowComplete:finalTimings=>{if(finalTimings){const idx=conversationsStore.findMessageIndex(assistantMessage.id);conversationsStore.updateMessageAtIndex(idx,{timings:finalTimings}), "",streamedReasoningContent="";const lastMsg=conversationsStore.activeMessages[conversationsStore.activeMessages.length-1],msg=await DatabaseService.createMessageBranch({convId,type:MessageType.TEXT,role:MessageRole.ASSISTANT,content:"",timestamp:Date.now(),toolCalls:"",children:[],model:resolvedModel},lastMsg.id);return conversationsStore.addMessageToActive(msg),currentMessageId=msg.id,msg},onFlowComplete:finalTimings=>{if(finalTimings){const idx=conversationsStore.findMessageIndex(assistantMessage.
DatabaseService.updateMessage(assistantMessage.id,{timings:finalTimings}).catch(console.error)}cleanupStreamingState(),onComplete&&onComplete(streamedContent),isRouterMode()&&modelsStore.fetchRouterModels().catch(console.error),config$1().preEncodeConversation&&this.triggerPreEncode(allMessages,assistantMessage,streamedContent,effectiveModel,!!config$1().excludeReasoningFromContext)},onError:error2=>{if(this.setStreamingActive(!1),isAbortError(error2)){cleanupStreamingState();const pending=this. id);conversationsStore.updateMessageAtIndex(idx,{timings:finalTimings}),DatabaseService.updateMessage(assistantMessage.id,{timings:finalTimings}).catch(console.error)}cleanupStreamingState(),onComplete&&onComplete(streamedContent),isRouterMode()&&modelsStore.fetchRouterModels().catch(console.error),config$1().preEncodeConversation&&this.triggerPreEncode(allMessages,assistantMessage,streamedContent,effectiveModel,!!config$1().excludeReasoningFromContext)},onError:error2=>{if(this.setStreamingActive(
consumePendingMessage(convId);pending&&this.sendMessage(pending.content,pending.extras);return}console.error("Streaming error:",error2),cleanupStreamingState(),this.clearPendingMessage(convId);const idx=conversationsStore.findMessageIndex(assistantMessage.id);if(idx!==-1){const failedMessage=conversationsStore.removeMessageAtIndex(idx);failedMessage&&DatabaseService.deleteMessage(failedMessage.id).catch(console.error)}const contextInfo=error2.contextInfo;this.showErrorDialog({type:error2.name=== !1),isAbortError(error2)){cleanupStreamingState();const pending=this.consumePendingMessage(convId);pending&&this.sendMessage(pending.content,pending.extras);return}console.error("Streaming error:",error2),cleanupStreamingState(),this.clearPendingMessage(convId);const idx=conversationsStore.findMessageIndex(assistantMessage.id);if(idx!==-1){const failedMessage=conversationsStore.removeMessageAtIndex(idx);failedMessage&&DatabaseService.deleteMessage(failedMessage.id).catch(console.error)}const contextInfo=error2.
"TimeoutError"?ErrorDialogType.TIMEOUT:ErrorDialogType.SERVER,message:error2.message,contextInfo}),onError&&onError(error2)}},perChatOverrides=conversationsStore.activeConversation?.mcpServerOverrides;if((await agenticStore.runAgenticFlow({conversationId:convId,messages:allMessages,options:{...this.getApiOptions(),...effectiveModel?{model:effectiveModel}:{}},callbacks:streamCallbacks,signal:abortController.signal,perChatOverrides})).handled){firstUserMessageContent&&await this.generateTitleWithLLM( contextInfo;this.showErrorDialog({type:error2.name==="TimeoutError"?ErrorDialogType.TIMEOUT:ErrorDialogType.SERVER,message:error2.message,contextInfo}),onError&&onError(error2)}},perChatOverrides=conversationsStore.activeConversation?.mcpServerOverrides;if((await agenticStore.runAgenticFlow({conversationId:convId,messages:allMessages,options:{...this.getApiOptions(),...effectiveModel?{model:effectiveModel}:{}},callbacks:streamCallbacks,signal:abortController.signal,perChatOverrides})).handled){firstUserMessageContent&&
firstUserMessageContent,streamedContent,convId);const pending=agenticStore.consumePendingSteeringMessage(convId);pending&&await this.sendMessage(pending.content,pending.extras);return}await ChatService.sendMessage(allMessages,{...this.getApiOptions(),...effectiveModel?{model:effectiveModel}:{},stream:!0,onChunk:streamCallbacks.onChunk,onReasoningChunk:streamCallbacks.onReasoningChunk,onModel:streamCallbacks.onModel,onTimings:streamCallbacks.onTimings,onComplete:async(finalContent,reasoningContent,timings,toolCalls)=>{ await this.generateTitleWithLLM(firstUserMessageContent,streamedContent,convId);const pending=agenticStore.consumePendingSteeringMessage(convId);pending&&await this.sendMessage(pending.content,pending.extras);return}await ChatService.sendMessage(allMessages,{...this.getApiOptions(),...effectiveModel?{model:effectiveModel}:{},stream:!0,onChunk:streamCallbacks.onChunk,onReasoningChunk:streamCallbacks.onReasoningChunk,onModel:streamCallbacks.onModel,onTimings:streamCallbacks.onTimings,onComplete:async(finalContent,reasoningContent,timings,toolCalls)=>{
const content2=streamedContent||finalContent||"",reasoning=streamedReasoningContent||reasoningContent,updateData={content:content2,reasoningContent:reasoning||void 0,toolCalls:toolCalls||"",timings};resolvedModel&&!modelPersisted&&(updateData.model=resolvedModel),await DatabaseService.updateMessage(currentMessageId,updateData);const idx=conversationsStore.findMessageIndex(currentMessageId),uiUpdate={content:content2,reasoningContent:reasoning||void 0,toolCalls:toolCalls||""};timings&&(uiUpdate.timings= const content2=streamedContent||finalContent||"",reasoning=streamedReasoningContent||reasoningContent,updateData={content:content2,reasoningContent:reasoning||void 0,toolCalls:toolCalls||"",timings};resolvedModel&&!modelPersisted&&(updateData.model=resolvedModel),await DatabaseService.updateMessage(currentMessageId,updateData);const idx=conversationsStore.findMessageIndex(currentMessageId),uiUpdate={content:content2,reasoningContent:reasoning||void 0,toolCalls:toolCalls||""};timings&&(uiUpdate.timings=
timings),resolvedModel&&(uiUpdate.model=resolvedModel),conversationsStore.updateMessageAtIndex(idx,uiUpdate),await conversationsStore.updateCurrentNode(currentMessageId),cleanupStreamingState(),onComplete&&await onComplete(content2),isRouterMode()&&modelsStore.fetchRouterModels().catch(console.error),firstUserMessageContent&&await this.generateTitleWithLLM(firstUserMessageContent,streamedContent,convId);const pending=this.consumePendingMessage(convId);pending&&await this.sendMessage(pending.content, timings),resolvedModel&&(uiUpdate.model=resolvedModel),conversationsStore.updateMessageAtIndex(idx,uiUpdate),await conversationsStore.updateCurrentNode(currentMessageId),cleanupStreamingState(),onComplete&&await onComplete(content2),isRouterMode()&&modelsStore.fetchRouterModels().catch(console.error),firstUserMessageContent&&await this.generateTitleWithLLM(firstUserMessageContent,streamedContent,convId);const pending=this.consumePendingMessage(convId);pending&&await this.sendMessage(pending.content,
pending.extras)},onError:streamCallbacks.onError},convId,abortController.signal)}async stopGeneration(){const activeConv=conversationsStore.activeConversation;activeConv&&await this.stopGenerationForChat(activeConv.id)}async stopGenerationForChat(convId){await this.savePartialResponseIfNeeded(convId),this.setStreamingActive(!1),this.abortRequest(convId),this.setChatLoading(convId,!1),this.clearChatStreaming(convId),this.setProcessingState(convId,null),this.clearPendingMessage(convId)}async generateTitleWithLLM(userContent,assistantContent,convId){ pending.extras)},onError:streamCallbacks.onError},convId,abortController.signal)}async stopGeneration(){const activeConv=conversationsStore.activeConversation;activeConv&&await this.stopGenerationForChat(activeConv.id)}async stopGenerationForChat(convId){await this.savePartialResponseIfNeeded(convId),this.setStreamingActive(!1),this.abortRequest(convId),this.setChatLoading(convId,!1),this.clearChatStreaming(convId),this.setProcessingState(convId,null),this.clearPendingMessage(convId)}async generateTitleWithLLM(userContent,assistantContent,convId){
const effectiveModel=isRouterMode()&&selectedModelName()?selectedModelName():void 0,configValue=config$1(),titlePrompt=(typeof configValue.titleGenerationPrompt=="string"&&configValue.titleGenerationPrompt.trim()?configValue.titleGenerationPrompt:TITLE_GENERATION.DEFAULT_PROMPT).replace("{{USER}}",String(userContent||"")).replace("{{ASSISTANT}}",String(assistantContent||"")),titleMessage={role:MessageRole.USER,content:titlePrompt},titleResponse=await ChatService.generateTitle(titleMessage,effectiveModel); const effectiveModel=isRouterMode()&&selectedModelName()?selectedModelName():void 0,configValue=config$1(),titlePrompt=(typeof configValue.titleGenerationPrompt=="string"&&configValue.titleGenerationPrompt.trim()?configValue.titleGenerationPrompt:TITLE_GENERATION.DEFAULT_PROMPT).replace("{{USER}}",String(userContent||"")).replace("{{ASSISTANT}}",String(assistantContent||"")),titleMessage={role:MessageRole.USER,content:titlePrompt},titleResponse=await ChatService.generateTitle(titleMessage,effectiveModel);
if(!titleResponse)return;let cleanTitle=titleResponse.trim();if(cleanTitle=cleanTitle.replace(TITLE_GENERATION.PREFIX_PATTERN,"").replace(TITLE_GENERATION.QUOTE_PATTERN,"").trim(),!cleanTitle||cleanTitle.length<TITLE_GENERATION.MIN_LENGTH){const firstLine=userContent.split(` if(!titleResponse)return;let cleanTitle=titleResponse.trim();if(cleanTitle=cleanTitle.replace(TITLE_GENERATION.PREFIX_PATTERN,"").replace(TITLE_GENERATION.QUOTE_PATTERN,"").trim(),!cleanTitle||cleanTitle.length<TITLE_GENERATION.MIN_LENGTH){const firstLine=userContent.split(`
`).find(l=>l.trim().length>0);cleanTitle=firstLine?firstLine.trim():TITLE_GENERATION.FALLBACK}cleanTitle&&cleanTitle.length>=TITLE_GENERATION.MIN_LENGTH&&await conversationsStore.updateConversationName(convId,cleanTitle)}async savePartialResponseIfNeeded(convId){const conversationId=convId||conversationsStore.activeConversation?.id;if(!conversationId)return;const streamingState=this.getChatStreaming(conversationId);if(!streamingState||!streamingState.response.trim())return;const messages=conversationId=== `).find(l=>l.trim().length>0);cleanTitle=firstLine?firstLine.trim():TITLE_GENERATION.FALLBACK}cleanTitle&&cleanTitle.length>=TITLE_GENERATION.MIN_LENGTH&&await conversationsStore.updateConversationName(convId,cleanTitle)}async savePartialResponseIfNeeded(convId){const conversationId=convId||conversationsStore.activeConversation?.id;if(!conversationId)return;const streamingState=this.getChatStreaming(conversationId);if(!streamingState)return;const messages=conversationId===conversationsStore.activeConversation?.
conversationsStore.activeConversation?.id?conversationsStore.activeMessages:await conversationsStore.getConversationMessages(conversationId);if(!messages.length)return;const lastMessage=messages[messages.length-1];if(lastMessage?.role===MessageRole.ASSISTANT)try{const updateData={content:streamingState.response},lastKnownState=this.getProcessingState(conversationId);lastKnownState&&(updateData.timings={prompt_n:lastKnownState.promptTokens||0,prompt_ms:lastKnownState.promptMs,predicted_n:lastKnownState. id?conversationsStore.activeMessages:await conversationsStore.getConversationMessages(conversationId);if(!messages.length)return;const lastMessage=messages[messages.length-1];if(lastMessage?.role!==MessageRole.ASSISTANT)return;const partialContent=streamingState.response,partialReasoning=lastMessage.reasoningContent||"";if(!(!partialContent.trim()&&!partialReasoning.trim()))try{const updateData={content:partialContent};partialReasoning&&(updateData.reasoningContent=partialReasoning);const lastKnownState=this.
tokensDecoded||0,cache_n:lastKnownState.cacheTokens||0,predicted_ms:lastKnownState.tokensPerSecond&&lastKnownState.tokensDecoded?lastKnownState.tokensDecoded/lastKnownState.tokensPerSecond*1e3:void 0}),await DatabaseService.updateMessage(lastMessage.id,updateData),lastMessage.content=streamingState.response,updateData.timings&&(lastMessage.timings=updateData.timings)}catch(error2){lastMessage.content=streamingState.response,console.error("Failed to save partial response:",error2)}}async updateMessage(messageId,newContent){ getProcessingState(conversationId);lastKnownState&&(updateData.timings={prompt_n:lastKnownState.promptTokens||0,prompt_ms:lastKnownState.promptMs,predicted_n:lastKnownState.tokensDecoded||0,cache_n:lastKnownState.cacheTokens||0,predicted_ms:lastKnownState.tokensPerSecond&&lastKnownState.tokensDecoded?lastKnownState.tokensDecoded/lastKnownState.tokensPerSecond*1e3:void 0}),await DatabaseService.updateMessage(lastMessage.id,updateData),lastMessage.content=partialContent,updateData.timings&&(lastMessage.
const activeConv=conversationsStore.activeConversation;if(!activeConv)return;this.isChatLoadingInternal(activeConv.id)&&await this.stopGeneration();const result=this.getMessageByIdWithRole(messageId,MessageRole.USER);if(!result)return;const{message:messageToUpdate,index:messageIndex}=result,originalContent=messageToUpdate.content;try{const rootMessage=(await conversationsStore.getConversationMessages(activeConv.id)).find(m=>m.type==="root"&&m.parent===null),isFirstUserMessage=rootMessage&&messageToUpdate. timings=updateData.timings)}catch(error2){lastMessage.content=partialContent,console.error("Failed to save partial response:",error2)}}async updateMessage(messageId,newContent){const activeConv=conversationsStore.activeConversation;if(!activeConv)return;this.isChatLoadingInternal(activeConv.id)&&await this.stopGeneration();const result=this.getMessageByIdWithRole(messageId,MessageRole.USER);if(!result)return;const{message:messageToUpdate,index:messageIndex}=result,originalContent=messageToUpdate.
parent===rootMessage.id;conversationsStore.updateMessageAtIndex(messageIndex,{content:newContent}),await DatabaseService.updateMessage(messageId,{content:newContent}),isFirstUserMessage&&newContent.trim()&&await conversationsStore.updateConversationTitleWithConfirmation(activeConv.id,generateConversationTitle(newContent,!!config$1().titleGenerationUseFirstLine));const messagesToRemove=conversationsStore.activeMessages.slice(messageIndex+1);for(const message of messagesToRemove)await DatabaseService. content;try{const rootMessage=(await conversationsStore.getConversationMessages(activeConv.id)).find(m=>m.type==="root"&&m.parent===null),isFirstUserMessage=rootMessage&&messageToUpdate.parent===rootMessage.id;conversationsStore.updateMessageAtIndex(messageIndex,{content:newContent}),await DatabaseService.updateMessage(messageId,{content:newContent}),isFirstUserMessage&&newContent.trim()&&await conversationsStore.updateConversationTitleWithConfirmation(activeConv.id,generateConversationTitle(newContent,
deleteMessage(message.id);conversationsStore.sliceActiveMessages(messageIndex+1),conversationsStore.updateConversationTimestamp(),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const assistantMessage=await this.createAssistantMessage();conversationsStore.addMessageToActive(assistantMessage),await conversationsStore.updateCurrentNode(assistantMessage.id),await this.streamChatCompletion(conversationsStore.activeMessages.slice(0,-1),assistantMessage,void 0,()=>{conversationsStore. !!config$1().titleGenerationUseFirstLine));const messagesToRemove=conversationsStore.activeMessages.slice(messageIndex+1);for(const message of messagesToRemove)await DatabaseService.deleteMessage(message.id);conversationsStore.sliceActiveMessages(messageIndex+1),conversationsStore.updateConversationTimestamp(),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const assistantMessage=await this.createAssistantMessage();conversationsStore.addMessageToActive(assistantMessage),
updateMessageAtIndex(conversationsStore.findMessageIndex(messageId),{content:originalContent})})}catch(error2){isAbortError(error2)||console.error("Failed to update message:",error2)}}async regenerateMessage(messageId){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;this.cancelPreEncode();const result=this.getMessageByIdWithRole(messageId,MessageRole.ASSISTANT);if(!result)return;const{index:messageIndex}=result;try{const messagesToRemove=conversationsStore. await conversationsStore.updateCurrentNode(assistantMessage.id),await this.streamChatCompletion(conversationsStore.activeMessages.slice(0,-1),assistantMessage,void 0,()=>{conversationsStore.updateMessageAtIndex(conversationsStore.findMessageIndex(messageId),{content:originalContent})})}catch(error2){isAbortError(error2)||console.error("Failed to update message:",error2)}}async regenerateMessage(messageId){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(
activeMessages.slice(messageIndex);for(const message of messagesToRemove)await DatabaseService.deleteMessage(message.id);conversationsStore.sliceActiveMessages(messageIndex),conversationsStore.updateConversationTimestamp(),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const parentMessageId=conversationsStore.activeMessages.length>0?conversationsStore.activeMessages[conversationsStore.activeMessages.length-1].id:void 0,assistantMessage=await this.createAssistantMessage( activeConv.id))return;this.cancelPreEncode();const result=this.getMessageByIdWithRole(messageId,MessageRole.ASSISTANT);if(!result)return;const{index:messageIndex}=result;try{const messagesToRemove=conversationsStore.activeMessages.slice(messageIndex);for(const message of messagesToRemove)await DatabaseService.deleteMessage(message.id);conversationsStore.sliceActiveMessages(messageIndex),conversationsStore.updateConversationTimestamp(),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(
parentMessageId);conversationsStore.addMessageToActive(assistantMessage),await this.streamChatCompletion(conversationsStore.activeMessages.slice(0,-1),assistantMessage)}catch(error2){isAbortError(error2)||console.error("Failed to regenerate message:",error2),this.setChatLoading(activeConv?.id||"",!1)}}async regenerateMessageWithBranching(messageId,modelOverride){const activeConv=conversationsStore.activeConversation;if(!(!activeConv||this.isChatLoadingInternal(activeConv.id))){this.cancelPreEncode(); activeConv.id);const parentMessageId=conversationsStore.activeMessages.length>0?conversationsStore.activeMessages[conversationsStore.activeMessages.length-1].id:void 0,assistantMessage=await this.createAssistantMessage(parentMessageId);conversationsStore.addMessageToActive(assistantMessage),await this.streamChatCompletion(conversationsStore.activeMessages.slice(0,-1),assistantMessage)}catch(error2){isAbortError(error2)||console.error("Failed to regenerate message:",error2),this.setChatLoading(activeConv?.
try{const idx=conversationsStore.findMessageIndex(messageId);if(idx===-1)return;const msg=conversationsStore.activeMessages[idx];if(msg.role!==MessageRole.ASSISTANT)return;const allMessages=await conversationsStore.getConversationMessages(activeConv.id),parentMessage=findMessageById(allMessages,msg.parent);if(!parentMessage)return;this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const newAssistantMessage=await DatabaseService.createMessageBranch({convId:msg.convId,type:msg. id||"",!1)}}async regenerateMessageWithBranching(messageId,modelOverride){const activeConv=conversationsStore.activeConversation;if(!(!activeConv||this.isChatLoadingInternal(activeConv.id))){this.cancelPreEncode();try{const idx=conversationsStore.findMessageIndex(messageId);if(idx===-1)return;const msg=conversationsStore.activeMessages[idx];if(msg.role!==MessageRole.ASSISTANT)return;const allMessages=await conversationsStore.getConversationMessages(activeConv.id),parentMessage=findMessageById(allMessages,
type,timestamp:Date.now(),role:msg.role,content:"",toolCalls:"",children:[],model:null},parentMessage.id);await conversationsStore.updateCurrentNode(newAssistantMessage.id),conversationsStore.updateConversationTimestamp(),await conversationsStore.refreshActiveMessages();const conversationPath=filterByLeafNodeId(allMessages,parentMessage.id,!1),modelToUse=modelOverride||msg.model||void 0;await this.streamChatCompletion(conversationPath,newAssistantMessage,void 0,void 0,modelToUse)}catch(error2){isAbortError( msg.parent);if(!parentMessage)return;this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const newAssistantMessage=await DatabaseService.createMessageBranch({convId:msg.convId,type:msg.type,timestamp:Date.now(),role:msg.role,content:"",toolCalls:"",children:[],model:null},parentMessage.id);await conversationsStore.updateCurrentNode(newAssistantMessage.id),conversationsStore.updateConversationTimestamp(),await conversationsStore.refreshActiveMessages();const conversationPath=filterByLeafNodeId(
error2)||console.error("Failed to regenerate message with branching:",error2),this.setChatLoading(activeConv?.id||"",!1)}}}async getDeletionInfo(messageId){const activeConv=conversationsStore.activeConversation;if(!activeConv)return{totalCount:0,userMessages:0,assistantMessages:0,messageTypes:[]};const allMessages=await conversationsStore.getConversationMessages(activeConv.id);if(findMessageById(allMessages,messageId)?.role===MessageRole.SYSTEM){const messagesToDelete2=allMessages.filter(m=>m.id=== allMessages,parentMessage.id,!1),modelToUse=modelOverride||msg.model||void 0;await this.streamChatCompletion(conversationPath,newAssistantMessage,void 0,void 0,modelToUse)}catch(error2){isAbortError(error2)||console.error("Failed to regenerate message with branching:",error2),this.setChatLoading(activeConv?.id||"",!1)}}}async getDeletionInfo(messageId){const activeConv=conversationsStore.activeConversation;if(!activeConv)return{totalCount:0,userMessages:0,assistantMessages:0,messageTypes:[]};const allMessages=await conversationsStore.
messageId);let userMessages2=0,assistantMessages2=0;const messageTypes2=[];for(const msg of messagesToDelete2)msg.role===MessageRole.USER?(userMessages2++,messageTypes2.includes("user message")||messageTypes2.push("user message")):msg.role===MessageRole.ASSISTANT&&(assistantMessages2++,messageTypes2.includes("assistant response")||messageTypes2.push("assistant response"));return{totalCount:1,userMessages:userMessages2,assistantMessages:assistantMessages2,messageTypes:messageTypes2}}const descendants=findDescendantMessages( getConversationMessages(activeConv.id);if(findMessageById(allMessages,messageId)?.role===MessageRole.SYSTEM){const messagesToDelete2=allMessages.filter(m=>m.id===messageId);let userMessages2=0,assistantMessages2=0;const messageTypes2=[];for(const msg of messagesToDelete2)msg.role===MessageRole.USER?(userMessages2++,messageTypes2.includes("user message")||messageTypes2.push("user message")):msg.role===MessageRole.ASSISTANT&&(assistantMessages2++,messageTypes2.includes("assistant response")||messageTypes2.
allMessages,messageId),allToDelete=[messageId,...descendants],messagesToDelete=allMessages.filter(m=>allToDelete.includes(m.id));let userMessages=0,assistantMessages=0;const messageTypes=[];for(const msg of messagesToDelete)msg.role===MessageRole.USER?(userMessages++,messageTypes.includes("user message")||messageTypes.push("user message")):msg.role===MessageRole.ASSISTANT&&(assistantMessages++,messageTypes.includes("assistant response")||messageTypes.push("assistant response"));return{totalCount:allToDelete. push("assistant response"));return{totalCount:1,userMessages:userMessages2,assistantMessages:assistantMessages2,messageTypes:messageTypes2}}const descendants=findDescendantMessages(allMessages,messageId),allToDelete=[messageId,...descendants],messagesToDelete=allMessages.filter(m=>allToDelete.includes(m.id));let userMessages=0,assistantMessages=0;const messageTypes=[];for(const msg of messagesToDelete)msg.role===MessageRole.USER?(userMessages++,messageTypes.includes("user message")||messageTypes.
length,userMessages,assistantMessages,messageTypes}}async deleteMessage(messageId){const activeConv=conversationsStore.activeConversation;if(activeConv)try{const allMessages=await conversationsStore.getConversationMessages(activeConv.id),messageToDelete=findMessageById(allMessages,messageId);if(!messageToDelete)return;if(filterByLeafNodeId(allMessages,activeConv.currNode||"",!1).some(m=>m.id===messageId)&&messageToDelete.parent){const siblings2=allMessages.filter(m=>m.parent===messageToDelete.parent&& push("user message")):msg.role===MessageRole.ASSISTANT&&(assistantMessages++,messageTypes.includes("assistant response")||messageTypes.push("assistant response"));return{totalCount:allToDelete.length,userMessages,assistantMessages,messageTypes}}async deleteMessage(messageId){const activeConv=conversationsStore.activeConversation;if(activeConv)try{const allMessages=await conversationsStore.getConversationMessages(activeConv.id),messageToDelete=findMessageById(allMessages,messageId);if(!messageToDelete)
m.id!==messageId);if(siblings2.length>0){const latestSibling=siblings2.reduce((latest,sibling2)=>sibling2.timestamp>latest.timestamp?sibling2:latest);await conversationsStore.updateCurrentNode(findLeafNode(allMessages,latestSibling.id))}else messageToDelete.parent&&await conversationsStore.updateCurrentNode(findLeafNode(allMessages,messageToDelete.parent))}await DatabaseService.deleteMessageCascading(activeConv.id,messageId),await conversationsStore.refreshActiveMessages(),conversationsStore.updateConversationTimestamp()}catch(error2){ return;if(filterByLeafNodeId(allMessages,activeConv.currNode||"",!1).some(m=>m.id===messageId)&&messageToDelete.parent){const siblings2=allMessages.filter(m=>m.parent===messageToDelete.parent&&m.id!==messageId);if(siblings2.length>0){const latestSibling=siblings2.reduce((latest,sibling2)=>sibling2.timestamp>latest.timestamp?sibling2:latest);await conversationsStore.updateCurrentNode(findLeafNode(allMessages,latestSibling.id))}else messageToDelete.parent&&await conversationsStore.updateCurrentNode(
console.error("Failed to delete message:",error2)}}async continueAssistantMessage(messageId){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;const result=this.getMessageByIdWithRole(messageId,MessageRole.ASSISTANT);if(!result)return;const{message:msg,index:idx}=result;try{this.showErrorDialog(null),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const allMessages=await conversationsStore.getConversationMessages( findLeafNode(allMessages,messageToDelete.parent))}await DatabaseService.deleteMessageCascading(activeConv.id,messageId),await conversationsStore.refreshActiveMessages(),conversationsStore.updateConversationTimestamp()}catch(error2){console.error("Failed to delete message:",error2)}}async continueAssistantMessage(messageId){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;const result=this.getMessageByIdWithRole(messageId,MessageRole.
activeConv.id),dbMessage=findMessageById(allMessages,messageId);if(!dbMessage){this.setChatLoading(activeConv.id,!1);return}const originalContent=dbMessage.content,originalReasoning=dbMessage.reasoningContent||"",contextWithContinue=[...conversationsStore.activeMessages.slice(0,idx),{role:MessageRole.ASSISTANT,content:originalContent}];let appendedContent="",appendedReasoning="",hasReceivedContent=!1;const updateStreamingContent=fullContent=>{this.setChatStreaming(msg.convId,fullContent,msg.id), ASSISTANT);if(!result)return;const{message:msg,index:idx}=result;try{this.showErrorDialog(null),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);const allMessages=await conversationsStore.getConversationMessages(activeConv.id),dbMessage=findMessageById(allMessages,messageId);if(!dbMessage){this.setChatLoading(activeConv.id,!1);return}const originalContent=dbMessage.content,originalReasoning=dbMessage.reasoningContent||"",contextWithContinue=[...conversationsStore.activeMessages.
conversationsStore.updateMessageAtIndex(idx,{content:fullContent})},abortController=this.getOrCreateAbortController(msg.convId);await ChatService.sendMessage(contextWithContinue,{...this.getApiOptions(),onChunk:chunk=>{appendedContent+=chunk,hasReceivedContent=!0,updateStreamingContent(originalContent+appendedContent)},onReasoningChunk:chunk=>{appendedReasoning+=chunk,hasReceivedContent=!0,conversationsStore.updateMessageAtIndex(idx,{reasoningContent:originalReasoning+appendedReasoning})},onTimings:(timings,promptProgress)=>{ slice(0,idx),{role:MessageRole.ASSISTANT,content:originalContent,reasoning_content:originalReasoning||void 0}];let appendedContent="",appendedReasoning="",hasReceivedContent=!1;const updateStreamingContent=fullContent=>{this.setChatStreaming(msg.convId,fullContent,msg.id),conversationsStore.updateMessageAtIndex(idx,{content:fullContent})},abortController=this.getOrCreateAbortController(msg.convId);await ChatService.sendMessage(contextWithContinue,{...this.getApiOptions(),onChunk:chunk=>{appendedContent+=
const tokensPerSecond=timings?.predicted_ms&&timings?.predicted_n?timings.predicted_n/timings.predicted_ms*1e3:0;this.updateProcessingStateFromTimings({prompt_n:timings?.prompt_n||0,prompt_ms:timings?.prompt_ms,predicted_n:timings?.predicted_n||0,predicted_per_second:tokensPerSecond,cache_n:timings?.cache_n||0,prompt_progress:promptProgress},msg.convId)},onComplete:async(finalContent,reasoningContent,timings)=>{const finalAppendedContent=hasReceivedContent?appendedContent:finalContent||"",finalAppendedReasoning=hasReceivedContent? chunk,hasReceivedContent=!0,updateStreamingContent(originalContent+appendedContent)},onReasoningChunk:chunk=>{appendedReasoning+=chunk,hasReceivedContent=!0,this.setChatStreaming(msg.convId,originalContent+appendedContent,msg.id),conversationsStore.updateMessageAtIndex(idx,{reasoningContent:originalReasoning+appendedReasoning})},onTimings:(timings,promptProgress)=>{const tokensPerSecond=timings?.predicted_ms&&timings?.predicted_n?timings.predicted_n/timings.predicted_ms*1e3:0;this.updateProcessingStateFromTimings(
appendedReasoning:reasoningContent||"",fullContent=originalContent+finalAppendedContent,fullReasoning=originalReasoning+finalAppendedReasoning||void 0;await DatabaseService.updateMessage(msg.id,{content:fullContent,reasoningContent:fullReasoning,timestamp:Date.now(),timings}),conversationsStore.updateMessageAtIndex(idx,{content:fullContent,reasoningContent:fullReasoning,timestamp:Date.now(),timings}),conversationsStore.updateConversationTimestamp(),this.setChatLoading(msg.convId,!1),this.clearChatStreaming( {prompt_n:timings?.prompt_n||0,prompt_ms:timings?.prompt_ms,predicted_n:timings?.predicted_n||0,predicted_per_second:tokensPerSecond,cache_n:timings?.cache_n||0,prompt_progress:promptProgress},msg.convId)},onComplete:async(finalContent,reasoningContent,timings)=>{const finalAppendedContent=hasReceivedContent?appendedContent:finalContent||"",finalAppendedReasoning=hasReceivedContent?appendedReasoning:reasoningContent||"",fullContent=originalContent+finalAppendedContent,fullReasoning=originalReasoning+
msg.convId),this.setProcessingState(msg.convId,null)},onError:async error2=>{if(isAbortError(error2)){hasReceivedContent&&appendedContent&&(await DatabaseService.updateMessage(msg.id,{content:originalContent+appendedContent,reasoningContent:originalReasoning+appendedReasoning||void 0,timestamp:Date.now()}),conversationsStore.updateMessageAtIndex(idx,{content:originalContent+appendedContent,reasoningContent:originalReasoning+appendedReasoning||void 0,timestamp:Date.now()})),this.setChatLoading(msg. finalAppendedReasoning||void 0;await DatabaseService.updateMessage(msg.id,{content:fullContent,reasoningContent:fullReasoning,timestamp:Date.now(),timings}),conversationsStore.updateMessageAtIndex(idx,{content:fullContent,reasoningContent:fullReasoning,timestamp:Date.now(),timings}),conversationsStore.updateConversationTimestamp(),this.setChatLoading(msg.convId,!1),this.clearChatStreaming(msg.convId),this.setProcessingState(msg.convId,null)},onError:async error2=>{if(isAbortError(error2)){hasReceivedContent&&
convId,!1),this.clearChatStreaming(msg.convId),this.setProcessingState(msg.convId,null);return}console.error("Continue generation error:",error2),conversationsStore.updateMessageAtIndex(idx,{content:originalContent}),await DatabaseService.updateMessage(msg.id,{content:originalContent}),this.setChatLoading(msg.convId,!1),this.clearChatStreaming(msg.convId),this.setProcessingState(msg.convId,null),this.showErrorDialog({type:error2.name==="TimeoutError"?ErrorDialogType.TIMEOUT:ErrorDialogType.SERVER, appendedContent&&(await DatabaseService.updateMessage(msg.id,{content:originalContent+appendedContent,reasoningContent:originalReasoning+appendedReasoning||void 0,timestamp:Date.now()}),conversationsStore.updateMessageAtIndex(idx,{content:originalContent+appendedContent,reasoningContent:originalReasoning+appendedReasoning||void 0,timestamp:Date.now()})),this.setChatLoading(msg.convId,!1),this.clearChatStreaming(msg.convId),this.setProcessingState(msg.convId,null);return}console.error("Continue g\
message:error2.message})}},msg.convId,abortController.signal)}catch(error2){isAbortError(error2)||console.error("Failed to continue message:",error2),activeConv&&this.setChatLoading(activeConv.id,!1)}}async editAssistantMessage(messageId,newContent,shouldBranch){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;const result=this.getMessageByIdWithRole(messageId,MessageRole.ASSISTANT);if(!result)return;const{message:msg,index:idx}=result; eneration error:",error2),conversationsStore.updateMessageAtIndex(idx,{content:originalContent}),await DatabaseService.updateMessage(msg.id,{content:originalContent}),this.setChatLoading(msg.convId,!1),this.clearChatStreaming(msg.convId),this.setProcessingState(msg.convId,null),this.showErrorDialog({type:error2.name==="TimeoutError"?ErrorDialogType.TIMEOUT:ErrorDialogType.SERVER,message:error2.message})}},msg.convId,abortController.signal)}catch(error2){isAbortError(error2)||console.error("Faile\
try{if(shouldBranch){const newMessage=await DatabaseService.createMessageBranch({convId:msg.convId,type:msg.type,timestamp:Date.now(),role:msg.role,content:newContent,toolCalls:msg.toolCalls||"",children:[],model:msg.model},msg.parent);await conversationsStore.updateCurrentNode(newMessage.id)}else await DatabaseService.updateMessage(msg.id,{content:newContent}),conversationsStore.updateMessageAtIndex(idx,{content:newContent});conversationsStore.updateConversationTimestamp(),await conversationsStore. d to continue message:",error2),activeConv&&this.setChatLoading(activeConv.id,!1)}}async editAssistantMessage(messageId,newContent,shouldBranch){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;const result=this.getMessageByIdWithRole(messageId,MessageRole.ASSISTANT);if(!result)return;const{message:msg,index:idx}=result;try{if(shouldBranch){const newMessage=await DatabaseService.createMessageBranch({convId:msg.convId,type:msg.
refreshActiveMessages()}catch(error2){console.error("Failed to edit assistant message:",error2)}}async editUserMessagePreserveResponses(messageId,newContent,newExtras){const activeConv=conversationsStore.activeConversation;if(!activeConv)return;const result=this.getMessageByIdWithRole(messageId,MessageRole.USER);if(!result)return;const{message:msg,index:idx}=result;try{const updateData={content:newContent};newExtras!==void 0&&(updateData.extra=JSON.parse(JSON.stringify(newExtras))),await DatabaseService. type,timestamp:Date.now(),role:msg.role,content:newContent,toolCalls:msg.toolCalls||"",children:[],model:msg.model},msg.parent);await conversationsStore.updateCurrentNode(newMessage.id)}else await DatabaseService.updateMessage(msg.id,{content:newContent}),conversationsStore.updateMessageAtIndex(idx,{content:newContent});conversationsStore.updateConversationTimestamp(),await conversationsStore.refreshActiveMessages()}catch(error2){console.error("Failed to edit assistant message:",error2)}}async editUserMessagePreserveResponses(messageId,newContent,newExtras){
updateMessage(messageId,updateData),conversationsStore.updateMessageAtIndex(idx,updateData);const rootMessage=(await conversationsStore.getConversationMessages(activeConv.id)).find(m=>m.type==="root"&&m.parent===null);rootMessage&&msg.parent===rootMessage.id&&newContent.trim()&&await conversationsStore.updateConversationTitleWithConfirmation(activeConv.id,generateConversationTitle(newContent,!!config$1().titleGenerationUseFirstLine)),conversationsStore.updateConversationTimestamp()}catch(error2){ const activeConv=conversationsStore.activeConversation;if(!activeConv)return;const result=this.getMessageByIdWithRole(messageId,MessageRole.USER);if(!result)return;const{message:msg,index:idx}=result;try{const updateData={content:newContent};newExtras!==void 0&&(updateData.extra=JSON.parse(JSON.stringify(newExtras))),await DatabaseService.updateMessage(messageId,updateData),conversationsStore.updateMessageAtIndex(idx,updateData);const rootMessage=(await conversationsStore.getConversationMessages(
console.error("Failed to edit user message:",error2)}}async editMessageWithBranching(messageId,newContent,newExtras){const activeConv=conversationsStore.activeConversation;if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;let result=this.getMessageByIdWithRole(messageId,MessageRole.USER);if(result||(result=this.getMessageByIdWithRole(messageId,MessageRole.SYSTEM)),!result)return;const{message:msg,index:idx}=result;try{const allMessages=await conversationsStore.getConversationMessages( activeConv.id)).find(m=>m.type==="root"&&m.parent===null);rootMessage&&msg.parent===rootMessage.id&&newContent.trim()&&await conversationsStore.updateConversationTitleWithConfirmation(activeConv.id,generateConversationTitle(newContent,!!config$1().titleGenerationUseFirstLine)),conversationsStore.updateConversationTimestamp()}catch(error2){console.error("Failed to edit user message:",error2)}}async editMessageWithBranching(messageId,newContent,newExtras){const activeConv=conversationsStore.activeConversation;
activeConv.id),rootMessage=allMessages.find(m=>m.type==="root"&&m.parent===null),isFirstUserMessage=msg.role===MessageRole.USER&&rootMessage&&msg.parent===rootMessage.id,extrasToUse=newExtras!==void 0?JSON.parse(JSON.stringify(newExtras)):msg.extra?JSON.parse(JSON.stringify(msg.extra)):void 0;let messageIdForResponse;const dbMsg=findMessageById(allMessages,msg.id);if(dbMsg?dbMsg.children.length>0:msg.children.length>0){const parentId=msg.parent||rootMessage?.id;if(!parentId)return;const newMessage=await DatabaseService. if(!activeConv||this.isChatLoadingInternal(activeConv.id))return;let result=this.getMessageByIdWithRole(messageId,MessageRole.USER);if(result||(result=this.getMessageByIdWithRole(messageId,MessageRole.SYSTEM)),!result)return;const{message:msg,index:idx}=result;try{const allMessages=await conversationsStore.getConversationMessages(activeConv.id),rootMessage=allMessages.find(m=>m.type==="root"&&m.parent===null),isFirstUserMessage=msg.role===MessageRole.USER&&rootMessage&&msg.parent===rootMessage.id,
createMessageBranch({convId:msg.convId,type:msg.type,timestamp:Date.now(),role:msg.role,content:newContent,toolCalls:msg.toolCalls||"",children:[],extra:extrasToUse,model:msg.model},parentId);await conversationsStore.updateCurrentNode(newMessage.id),messageIdForResponse=newMessage.id}else{const updates={content:newContent,timestamp:Date.now(),extra:extrasToUse};await DatabaseService.updateMessage(msg.id,updates),conversationsStore.updateMessageAtIndex(idx,updates),messageIdForResponse=msg.id}conversationsStore. extrasToUse=newExtras!==void 0?JSON.parse(JSON.stringify(newExtras)):msg.extra?JSON.parse(JSON.stringify(msg.extra)):void 0;let messageIdForResponse;const dbMsg=findMessageById(allMessages,msg.id);if(dbMsg?dbMsg.children.length>0:msg.children.length>0){const parentId=msg.parent||rootMessage?.id;if(!parentId)return;const newMessage=await DatabaseService.createMessageBranch({convId:msg.convId,type:msg.type,timestamp:Date.now(),role:msg.role,content:newContent,toolCalls:msg.toolCalls||"",children:[],
updateConversationTimestamp(),isFirstUserMessage&&newContent.trim()&&await conversationsStore.updateConversationTitleWithConfirmation(activeConv.id,generateConversationTitle(newContent,!!config$1().titleGenerationUseFirstLine)),await conversationsStore.refreshActiveMessages(),msg.role===MessageRole.USER&&await this.generateResponseForMessage(messageIdForResponse)}catch(error2){console.error("Failed to edit message with branching:",error2)}}async generateResponseForMessage(userMessageId){const activeConv=conversationsStore. extra:extrasToUse,model:msg.model},parentId);await conversationsStore.updateCurrentNode(newMessage.id),messageIdForResponse=newMessage.id}else{const updates={content:newContent,timestamp:Date.now(),extra:extrasToUse};await DatabaseService.updateMessage(msg.id,updates),conversationsStore.updateMessageAtIndex(idx,updates),messageIdForResponse=msg.id}conversationsStore.updateConversationTimestamp(),isFirstUserMessage&&newContent.trim()&&await conversationsStore.updateConversationTitleWithConfirmation(
activeConversation;if(activeConv){this.showErrorDialog(null),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(activeConv.id);try{const allMessages=await conversationsStore.getConversationMessages(activeConv.id),conversationPath=filterByLeafNodeId(allMessages,userMessageId,!1),assistantMessage=await DatabaseService.createMessageBranch({convId:activeConv.id,type:MessageType.TEXT,timestamp:Date.now(),role:MessageRole.ASSISTANT,content:"",toolCalls:"",children:[],model:null},userMessageId); activeConv.id,generateConversationTitle(newContent,!!config$1().titleGenerationUseFirstLine)),await conversationsStore.refreshActiveMessages(),msg.role===MessageRole.USER&&await this.generateResponseForMessage(messageIdForResponse)}catch(error2){console.error("Failed to edit message with branching:",error2)}}async generateResponseForMessage(userMessageId){const activeConv=conversationsStore.activeConversation;if(activeConv){this.showErrorDialog(null),this.setChatLoading(activeConv.id,!0),this.clearChatStreaming(
conversationsStore.addMessageToActive(assistantMessage),await this.streamChatCompletion(conversationPath,assistantMessage)}catch(error2){console.error("Failed to generate response:",error2),this.setChatLoading(activeConv.id,!1)}}}getContextTotal(){const activeConvId=this.activeConversationId,activeState=activeConvId?this.getProcessingState(activeConvId):null;if(activeState&&typeof activeState.contextTotal=="number"&&activeState.contextTotal>0)return activeState.contextTotal;if(isRouterMode()){const modelContextSize=selectedModelContextSize(); activeConv.id);try{const allMessages=await conversationsStore.getConversationMessages(activeConv.id),conversationPath=filterByLeafNodeId(allMessages,userMessageId,!1),assistantMessage=await DatabaseService.createMessageBranch({convId:activeConv.id,type:MessageType.TEXT,timestamp:Date.now(),role:MessageRole.ASSISTANT,content:"",toolCalls:"",children:[],model:null},userMessageId);conversationsStore.addMessageToActive(assistantMessage),await this.streamChatCompletion(conversationPath,assistantMessage)}catch(error2){
if(typeof modelContextSize=="number"&&modelContextSize>0)return modelContextSize}else{const propsContextSize=contextSize();if(typeof propsContextSize=="number"&&propsContextSize>0)return propsContextSize}return null}updateProcessingStateFromTimings(timingData,conversationId){const processingState=this.parseTimingData(timingData);if(processingState===null){console.warn("Failed to parse timing data - skipping update");return}const targetId=conversationId||this.activeConversationId;targetId&&this.setProcessingState( console.error("Failed to generate response:",error2),this.setChatLoading(activeConv.id,!1)}}}getContextTotal(){const activeConvId=this.activeConversationId,activeState=activeConvId?this.getProcessingState(activeConvId):null;if(activeState&&typeof activeState.contextTotal=="number"&&activeState.contextTotal>0)return activeState.contextTotal;if(isRouterMode()){const modelContextSize=selectedModelContextSize();if(typeof modelContextSize=="number"&&modelContextSize>0)return modelContextSize}else{const propsContextSize=contextSize();
targetId,processingState)}parseTimingData(timingData){const promptTokens=timingData.prompt_n||0,promptMs=timingData.prompt_ms||void 0,predictedTokens=timingData.predicted_n||0,tokensPerSecond=timingData.predicted_per_second||0,cacheTokens=timingData.cache_n||0,promptProgress=timingData.prompt_progress,contextTotal=this.getContextTotal(),currentConfig=config$1(),outputTokensMax=currentConfig.max_tokens||-1,contextUsed=promptTokens+cacheTokens+predictedTokens,outputTokensUsed=predictedTokens,progressCache=promptProgress?. if(typeof propsContextSize=="number"&&propsContextSize>0)return propsContextSize}return null}updateProcessingStateFromTimings(timingData,conversationId){const processingState=this.parseTimingData(timingData);if(processingState===null){console.warn("Failed to parse timing data - skipping update");return}const targetId=conversationId||this.activeConversationId;targetId&&this.setProcessingState(targetId,processingState)}parseTimingData(timingData){const promptTokens=timingData.prompt_n||0,promptMs=timingData.
cache||0,progressActualDone=(promptProgress?.processed??0)-progressCache,progressActualTotal=(promptProgress?.total??0)-progressCache,progressPercent=promptProgress?Math.round(progressActualDone/progressActualTotal*100):void 0;return{status:predictedTokens>0?"generating":promptProgress?"preparing":"idle",tokensDecoded:predictedTokens,tokensRemaining:outputTokensMax-predictedTokens,contextUsed,contextTotal,outputTokensUsed,outputTokensMax,hasNextToken:predictedTokens>0,tokensPerSecond,temperature:currentConfig. prompt_ms||void 0,predictedTokens=timingData.predicted_n||0,tokensPerSecond=timingData.predicted_per_second||0,cacheTokens=timingData.cache_n||0,promptProgress=timingData.prompt_progress,contextTotal=this.getContextTotal(),currentConfig=config$1(),outputTokensMax=currentConfig.max_tokens||-1,contextUsed=promptTokens+cacheTokens+predictedTokens,outputTokensUsed=predictedTokens,progressCache=promptProgress?.cache||0,progressActualDone=(promptProgress?.processed??0)-progressCache,progressActualTotal=(promptProgress?.
temperature??.8,topP:currentConfig.top_p??.95,speculative:!1,progressPercent,promptProgress,promptTokens,promptMs,cacheTokens}}restoreProcessingStateFromMessages(messages,conversationId){for(let i=messages.length-1;i>=0;i--){const message=messages[i];if(message.role===MessageRole.ASSISTANT&&message.timings){const restoredState=this.parseTimingData({prompt_n:message.timings.prompt_n||0,prompt_ms:message.timings.prompt_ms,predicted_n:message.timings.predicted_n||0,predicted_per_second:message.timings. total??0)-progressCache,progressPercent=promptProgress?Math.round(progressActualDone/progressActualTotal*100):void 0;return{status:predictedTokens>0?"generating":promptProgress?"preparing":"idle",tokensDecoded:predictedTokens,tokensRemaining:outputTokensMax-predictedTokens,contextUsed,contextTotal,outputTokensUsed,outputTokensMax,hasNextToken:predictedTokens>0,tokensPerSecond,temperature:currentConfig.temperature??.8,topP:currentConfig.top_p??.95,speculative:!1,progressPercent,promptProgress,promptTokens,
predicted_n&&message.timings.predicted_ms?message.timings.predicted_n/message.timings.predicted_ms*1e3:0,cache_n:message.timings.cache_n||0});if(restoredState){this.setProcessingState(conversationId,restoredState);return}}}}getConversationModel(messages){for(let i=messages.length-1;i>=0;i--){const message=messages[i];if(message.role===MessageRole.ASSISTANT&&message.model)return message.model}return null}getApiOptions(){const currentConfig=config$1(),hasValue=value=>value!=null&&value!=="",apiOptions={ promptMs,cacheTokens}}restoreProcessingStateFromMessages(messages,conversationId){for(let i=messages.length-1;i>=0;i--){const message=messages[i];if(message.role===MessageRole.ASSISTANT&&message.timings){const restoredState=this.parseTimingData({prompt_n:message.timings.prompt_n||0,prompt_ms:message.timings.prompt_ms,predicted_n:message.timings.predicted_n||0,predicted_per_second:message.timings.predicted_n&&message.timings.predicted_ms?message.timings.predicted_n/message.timings.predicted_ms*1e3:
stream:!0,timings_per_token:!0};if(isRouterMode()){const modelName=selectedModelName();modelName&&(apiOptions.model=modelName)}return currentConfig.systemMessage&&(apiOptions.systemMessage=currentConfig.systemMessage),currentConfig.disableReasoningParsing&&(apiOptions.disableReasoningParsing=!0),currentConfig.excludeReasoningFromContext&&(apiOptions.excludeReasoningFromContext=!0),hasValue(currentConfig.temperature)&&(apiOptions.temperature=Number(currentConfig.temperature)),hasValue(currentConfig. 0,cache_n:message.timings.cache_n||0});if(restoredState){this.setProcessingState(conversationId,restoredState);return}}}}getConversationModel(messages){for(let i=messages.length-1;i>=0;i--){const message=messages[i];if(message.role===MessageRole.ASSISTANT&&message.model)return message.model}return null}getApiOptions(){const currentConfig=config$1(),hasValue=value=>value!=null&&value!=="",apiOptions={stream:!0,timings_per_token:!0};if(isRouterMode()){const modelName=selectedModelName();modelName&&
max_tokens)&&(apiOptions.max_tokens=Number(currentConfig.max_tokens)),hasValue(currentConfig.dynatemp_range)&&(apiOptions.dynatemp_range=Number(currentConfig.dynatemp_range)),hasValue(currentConfig.dynatemp_exponent)&&(apiOptions.dynatemp_exponent=Number(currentConfig.dynatemp_exponent)),hasValue(currentConfig.top_k)&&(apiOptions.top_k=Number(currentConfig.top_k)),hasValue(currentConfig.top_p)&&(apiOptions.top_p=Number(currentConfig.top_p)),hasValue(currentConfig.min_p)&&(apiOptions.min_p=Number( (apiOptions.model=modelName)}return currentConfig.systemMessage&&(apiOptions.systemMessage=currentConfig.systemMessage),currentConfig.disableReasoningParsing&&(apiOptions.disableReasoningParsing=!0),currentConfig.excludeReasoningFromContext&&(apiOptions.excludeReasoningFromContext=!0),hasValue(currentConfig.temperature)&&(apiOptions.temperature=Number(currentConfig.temperature)),hasValue(currentConfig.max_tokens)&&(apiOptions.max_tokens=Number(currentConfig.max_tokens)),hasValue(currentConfig.dynatemp_range)&&
currentConfig.min_p)),hasValue(currentConfig.xtc_probability)&&(apiOptions.xtc_probability=Number(currentConfig.xtc_probability)),hasValue(currentConfig.xtc_threshold)&&(apiOptions.xtc_threshold=Number(currentConfig.xtc_threshold)),hasValue(currentConfig.typ_p)&&(apiOptions.typ_p=Number(currentConfig.typ_p)),hasValue(currentConfig.repeat_last_n)&&(apiOptions.repeat_last_n=Number(currentConfig.repeat_last_n)),hasValue(currentConfig.repeat_penalty)&&(apiOptions.repeat_penalty=Number(currentConfig. (apiOptions.dynatemp_range=Number(currentConfig.dynatemp_range)),hasValue(currentConfig.dynatemp_exponent)&&(apiOptions.dynatemp_exponent=Number(currentConfig.dynatemp_exponent)),hasValue(currentConfig.top_k)&&(apiOptions.top_k=Number(currentConfig.top_k)),hasValue(currentConfig.top_p)&&(apiOptions.top_p=Number(currentConfig.top_p)),hasValue(currentConfig.min_p)&&(apiOptions.min_p=Number(currentConfig.min_p)),hasValue(currentConfig.xtc_probability)&&(apiOptions.xtc_probability=Number(currentConfig.
repeat_penalty)),hasValue(currentConfig.presence_penalty)&&(apiOptions.presence_penalty=Number(currentConfig.presence_penalty)),hasValue(currentConfig.frequency_penalty)&&(apiOptions.frequency_penalty=Number(currentConfig.frequency_penalty)),hasValue(currentConfig.dry_multiplier)&&(apiOptions.dry_multiplier=Number(currentConfig.dry_multiplier)),hasValue(currentConfig.dry_base)&&(apiOptions.dry_base=Number(currentConfig.dry_base)),hasValue(currentConfig.dry_allowed_length)&&(apiOptions.dry_allowed_length= xtc_probability)),hasValue(currentConfig.xtc_threshold)&&(apiOptions.xtc_threshold=Number(currentConfig.xtc_threshold)),hasValue(currentConfig.typ_p)&&(apiOptions.typ_p=Number(currentConfig.typ_p)),hasValue(currentConfig.repeat_last_n)&&(apiOptions.repeat_last_n=Number(currentConfig.repeat_last_n)),hasValue(currentConfig.repeat_penalty)&&(apiOptions.repeat_penalty=Number(currentConfig.repeat_penalty)),hasValue(currentConfig.presence_penalty)&&(apiOptions.presence_penalty=Number(currentConfig.presence_penalty)),
Number(currentConfig.dry_allowed_length)),hasValue(currentConfig.dry_penalty_last_n)&&(apiOptions.dry_penalty_last_n=Number(currentConfig.dry_penalty_last_n)),currentConfig.samplers&&(apiOptions.samplers=currentConfig.samplers),apiOptions.backend_sampling=currentConfig.backend_sampling,currentConfig.custom&&(apiOptions.custom=currentConfig.custom),apiOptions}cancelPreEncode(){this.preEncodeAbortController&&(this.preEncodeAbortController.abort(),this.preEncodeAbortController=null)}async triggerPreEncode(allMessages,assistantMessage,assistantContent,model,excludeReasoning){ hasValue(currentConfig.frequency_penalty)&&(apiOptions.frequency_penalty=Number(currentConfig.frequency_penalty)),hasValue(currentConfig.dry_multiplier)&&(apiOptions.dry_multiplier=Number(currentConfig.dry_multiplier)),hasValue(currentConfig.dry_base)&&(apiOptions.dry_base=Number(currentConfig.dry_base)),hasValue(currentConfig.dry_allowed_length)&&(apiOptions.dry_allowed_length=Number(currentConfig.dry_allowed_length)),hasValue(currentConfig.dry_penalty_last_n)&&(apiOptions.dry_penalty_last_n=Number(
this.cancelPreEncode(),this.preEncodeAbortController=new AbortController;const signal=this.preEncodeAbortController.signal;try{if(!await ChatService.areAllSlotsIdle(model,signal)||signal.aborted)return;const messagesWithAssistant=[...allMessages,{...assistantMessage,content:assistantContent}];await ChatService.preEncode(messagesWithAssistant,model,excludeReasoning,signal)}catch(err){isAbortError(err)||console.warn("[ChatStore] Pre-encode failed:",err)}}}const chatStore=new ChatStore,activeProcessingState=()=>chatStore. currentConfig.dry_penalty_last_n)),currentConfig.samplers&&(apiOptions.samplers=currentConfig.samplers),apiOptions.backend_sampling=currentConfig.backend_sampling,currentConfig.custom&&(apiOptions.custom=currentConfig.custom),apiOptions}cancelPreEncode(){this.preEncodeAbortController&&(this.preEncodeAbortController.abort(),this.preEncodeAbortController=null)}async triggerPreEncode(allMessages,assistantMessage,assistantContent,model,excludeReasoning){this.cancelPreEncode(),this.preEncodeAbortController=
activeProcessingState,errorDialog=()=>chatStore.errorDialogState,getAddFilesHandler=()=>chatStore.getAddFilesHandler(),getAllLoadingChats=()=>chatStore.getAllLoadingChats(),isChatStreaming=()=>chatStore.isStreaming(),isEditing=()=>chatStore.isEditing(),isLoading=()=>chatStore.isLoading,pendingEditMessageId=()=>chatStore.pendingEditMessageId,chatPendingMessageContent=convId=>chatStore.pendingMessageContent(convId),chatPendingMessageExtras=convId=>chatStore.pendingMessageExtras(convId),chatClearPendingMessage=convId=>chatStore. new AbortController;const signal=this.preEncodeAbortController.signal;try{if(!await ChatService.areAllSlotsIdle(model,signal)||signal.aborted)return;const messagesWithAssistant=[...allMessages,{...assistantMessage,content:assistantContent}];await ChatService.preEncode(messagesWithAssistant,model,excludeReasoning,signal)}catch(err){isAbortError(err)||console.warn("[ChatStore] Pre-encode failed:",err)}}}const chatStore=new ChatStore,activeProcessingState=()=>chatStore.activeProcessingState,errorDialog=()=>chatStore.
clearPendingMessage(convId),chatInjectPendingMessage=(convId,content2,extras)=>chatStore.injectPendingMessage(convId,content2,extras);var root$1u=from_html('<!> <form><!> <div data-slot="input-area"><!> <div class="flex-column relative min-h-[48px] items-center rounded-3xl py-2 pb-2.25 shadow-sm transition-all focus-within:shadow-md md:!py-3"><!> <!> <!></div></div></form> <!>',1);function ChatForm($$anchor,$$props){push$1($$props,!0);let attachments=prop($$props,"attachments",19,()=>[]),className=prop( errorDialogState,getAddFilesHandler=()=>chatStore.getAddFilesHandler(),getAllLoadingChats=()=>chatStore.getAllLoadingChats(),isChatStreaming=()=>chatStore.isStreaming(),isEditing=()=>chatStore.isEditing(),isLoading=()=>chatStore.isLoading,pendingEditMessageId=()=>chatStore.pendingEditMessageId,chatPendingMessageContent=convId=>chatStore.pendingMessageContent(convId),chatPendingMessageExtras=convId=>chatStore.pendingMessageExtras(convId),chatClearPendingMessage=convId=>chatStore.clearPendingMessage(
$$props,"class",3,""),disabled=prop($$props,"disabled",3,!1),isLoading2=prop($$props,"isLoading",3,!1),placeholder=prop($$props,"placeholder",3,"Type a message..."),showMcpPromptButton=prop($$props,"showMcpPromptButton",3,!1),showAddButton=prop($$props,"showAddButton",3,!0),showModelSelector=prop($$props,"showModelSelector",3,!0),uploadedFiles=prop($$props,"uploadedFiles",31,()=>proxy([])),value=prop($$props,"value",15,""),audioRecorder,chatFormActionsRef=state$1(void 0),fileInputRef=state$1(void 0), convId),chatInjectPendingMessage=(convId,content2,extras)=>chatStore.injectPendingMessage(convId,content2,extras);var root$1u=from_html('<!> <form><!> <div data-slot="input-area"><!> <div class="flex-column relative min-h-[48px] items-center rounded-3xl py-2 pb-2.25 shadow-sm transition-all focus-within:shadow-md md:!py-3"><!> <!> <!></div></div></form> <!>',1);function ChatForm($$anchor,$$props){push$1($$props,!0);let attachments=prop($$props,"attachments",19,()=>[]),className=prop($$props,"cla\
pickersRef=state$1(void 0),textareaRef=state$1(void 0),isRecording=state$1(!1),recordingSupported=state$1(!1),isPromptPickerOpen=state$1(!1),promptSearchQuery=state$1(""),isInlineResourcePickerOpen=state$1(!1),resourceSearchQuery=state$1(""),isResourceDialogOpen=state$1(!1),preSelectedResourceUri=state$1(void 0),currentConfig=user_derived(config$1),pasteLongTextToFileLength=user_derived(()=>{const n=Number(get$3(currentConfig).pasteLongTextToFileLen);return Number.isNaN(n)?Number(SETTING_CONFIG_DEFAULT. ss",3,""),disabled=prop($$props,"disabled",3,!1),isLoading2=prop($$props,"isLoading",3,!1),placeholder=prop($$props,"placeholder",3,"Type a message..."),showMcpPromptButton=prop($$props,"showMcpPromptButton",3,!1),showAddButton=prop($$props,"showAddButton",3,!0),showModelSelector=prop($$props,"showModelSelector",3,!0),uploadedFiles=prop($$props,"uploadedFiles",31,()=>proxy([])),value=prop($$props,"value",15,""),audioRecorder,chatFormActionsRef=state$1(void 0),fileInputRef=state$1(void 0),pickersRef=state$1(
pasteLongTextToFileLen):n}),isRouter=user_derived(isRouterMode),conversationModel=user_derived(()=>chatStore.getConversationModel(activeMessages())),activeModelId=user_derived(()=>{const options=modelOptions();if(!get$3(isRouter))return options.length>0?options[0].model:null;const selectedId=selectedModelId();if(selectedId){const model=options.find(m=>m.id===selectedId);if(model)return model.model}if(get$3(conversationModel)){const model=options.find(m=>m.model===get$3(conversationModel));if(model) void 0),textareaRef=state$1(void 0),isRecording=state$1(!1),recordingSupported=state$1(!1),isPromptPickerOpen=state$1(!1),promptSearchQuery=state$1(""),isInlineResourcePickerOpen=state$1(!1),resourceSearchQuery=state$1(""),isResourceDialogOpen=state$1(!1),preSelectedResourceUri=state$1(void 0),currentConfig=user_derived(config$1),pasteLongTextToFileLength=user_derived(()=>{const n=Number(get$3(currentConfig).pasteLongTextToFileLen);return Number.isNaN(n)?Number(SETTING_CONFIG_DEFAULT.pasteLongTextToFileLen):
return model.model}return null}),hasModelSelected=user_derived(()=>!get$3(isRouter)||!!get$3(conversationModel)||!!selectedModelId()),hasLoadingAttachments=user_derived(()=>uploadedFiles().some(f=>f.isLoading)),hasAttachments=user_derived(()=>attachments()&&attachments().length>0||uploadedFiles()&&uploadedFiles().length>0),canSubmit=user_derived(()=>value().trim().length>0||get$3(hasAttachments));onMount$1(()=>{set$1(recordingSupported,isAudioRecordingSupported(),!0),audioRecorder=new AudioRecorder}); n}),isRouter=user_derived(isRouterMode),conversationModel=user_derived(()=>chatStore.getConversationModel(activeMessages())),activeModelId=user_derived(()=>{const options=modelOptions();if(!get$3(isRouter))return options.length>0?options[0].model:null;const selectedId=selectedModelId();if(selectedId){const model=options.find(m=>m.id===selectedId);if(model)return model.model}if(get$3(conversationModel)){const model=options.find(m=>m.model===get$3(conversationModel));if(model)return model.model}return null}),
function focus2(){get$3(textareaRef)?.focus()}function resetTextareaHeight(){get$3(textareaRef)?.resetHeight()}function openModelSelector(){get$3(chatFormActionsRef)?.openModelSelector()}function checkModelSelected(){return get$3(hasModelSelected)?!0:(get$3(chatFormActionsRef)?.openModelSelector(),!1)}function handleFileSelect(files){$$props.onFilesAdd?.(files)}function handleFileUpload(){get$3(fileInputRef)?.click()}function handleFileRemove(fileId){if(fileId.startsWith("attachment-")){const index2=parseInt( hasModelSelected=user_derived(()=>!get$3(isRouter)||!!get$3(conversationModel)||!!selectedModelId()),hasLoadingAttachments=user_derived(()=>uploadedFiles().some(f=>f.isLoading)),hasAttachments=user_derived(()=>attachments()&&attachments().length>0||uploadedFiles()&&uploadedFiles().length>0),canSubmit=user_derived(()=>value().trim().length>0||get$3(hasAttachments));onMount$1(()=>{set$1(recordingSupported,isAudioRecordingSupported(),!0),audioRecorder=new AudioRecorder});function focus2(){get$3(textareaRef)?.
fileId.replace("attachment-",""),10);!isNaN(index2)&&index2>=0&&index2<attachments().length&&$$props.onAttachmentRemove?.(index2)}else $$props.onUploadedFileRemove?.(fileId)}function handleInput(){const perChatOverrides=conversationsStore.getAllMcpServerOverrides(),hasServers=mcpStore.hasEnabledServers(perChatOverrides);value().startsWith(PROMPT_TRIGGER_PREFIX)&&hasServers?(set$1(isPromptPickerOpen,!0),set$1(promptSearchQuery,value().slice(1),!0),set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery, focus()}function resetTextareaHeight(){get$3(textareaRef)?.resetHeight()}function openModelSelector(){get$3(chatFormActionsRef)?.openModelSelector()}function checkModelSelected(){return get$3(hasModelSelected)?!0:(get$3(chatFormActionsRef)?.openModelSelector(),!1)}function handleFileSelect(files){$$props.onFilesAdd?.(files)}function handleFileUpload(){get$3(fileInputRef)?.click()}function handleFileRemove(fileId){if(fileId.startsWith("attachment-")){const index2=parseInt(fileId.replace("attachme\
"")):value().startsWith(RESOURCE_TRIGGER_PREFIX)&&hasServers&&mcpStore.hasResourcesCapability(perChatOverrides)?(set$1(isInlineResourcePickerOpen,!0),set$1(resourceSearchQuery,value().slice(1),!0),set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,"")):(set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,""),set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""))}function handleKeydown(event2){if(!get$3(pickersRef)?.handleKeydown(event2)){if(event2.key===KeyboardKey.ESCAPE&&get$3( nt-",""),10);!isNaN(index2)&&index2>=0&&index2<attachments().length&&$$props.onAttachmentRemove?.(index2)}else $$props.onUploadedFileRemove?.(fileId)}function handleInput(){const perChatOverrides=conversationsStore.getAllMcpServerOverrides(),hasServers=mcpStore.hasEnabledServers(perChatOverrides);value().startsWith(PROMPT_TRIGGER_PREFIX)&&hasServers?(set$1(isPromptPickerOpen,!0),set$1(promptSearchQuery,value().slice(1),!0),set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,"")):value().
isPromptPickerOpen)){set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,"");return}if(event2.key===KeyboardKey.ESCAPE&&get$3(isInlineResourcePickerOpen)){set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,"");return}if(event2.key===KeyboardKey.ENTER&&!event2.shiftKey&&!isIMEComposing(event2)){const isModifier=event2.ctrlKey||event2.metaKey;if(get$3(currentConfig).sendOnEnter!==!1||isModifier){if(event2.preventDefault(),!get$3(canSubmit)||disabled()||get$3(hasLoadingAttachments))return; startsWith(RESOURCE_TRIGGER_PREFIX)&&hasServers&&mcpStore.hasResourcesCapability(perChatOverrides)?(set$1(isInlineResourcePickerOpen,!0),set$1(resourceSearchQuery,value().slice(1),!0),set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,"")):(set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,""),set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""))}function handleKeydown(event2){if(!get$3(pickersRef)?.handleKeydown(event2)){if(event2.key===KeyboardKey.ESCAPE&&get$3(isPromptPickerOpen)){
$$props.onSubmit?.()}}}}function handlePaste(event2){if(!event2.clipboardData)return;const files=Array.from(event2.clipboardData.items).filter(item=>item.kind==="file").map(item=>item.getAsFile()).filter(file=>file!==null);if(files.length>0){event2.preventDefault(),$$props.onFilesAdd?.(files);return}const text2=event2.clipboardData.getData(MimeTypeText.PLAIN);if(text2.startsWith(CLIPBOARD_CONTENT_QUOTE_PREFIX)){const parsed=parseClipboardContent(text2);if(parsed.textAttachments.length>0||parsed. set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,"");return}if(event2.key===KeyboardKey.ESCAPE&&get$3(isInlineResourcePickerOpen)){set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,"");return}if(event2.key===KeyboardKey.ENTER&&!event2.shiftKey&&!isIMEComposing(event2)){const isModifier=event2.ctrlKey||event2.metaKey;if(get$3(currentConfig).sendOnEnter!==!1||isModifier){if(event2.preventDefault(),!get$3(canSubmit)||disabled()||get$3(hasLoadingAttachments))return;$$props.onSubmit?.()}}}}
mcpPromptAttachments.length>0){if(event2.preventDefault(),value(parsed.message),$$props.onValueChange?.(parsed.message),parsed.textAttachments.length>0){const attachmentFiles=parsed.textAttachments.map(att=>new File([att.content],att.name,{type:MimeTypeText.PLAIN}));$$props.onFilesAdd?.(attachmentFiles)}if(parsed.mcpPromptAttachments.length>0){const mcpPromptFiles=parsed.mcpPromptAttachments.map(att=>({id:uuid$1(),name:att.name,size:att.content.length,type:SpecialFileType.MCP_PROMPT,file:new File( function handlePaste(event2){if(!event2.clipboardData)return;const files=Array.from(event2.clipboardData.items).filter(item=>item.kind==="file").map(item=>item.getAsFile()).filter(file=>file!==null);if(files.length>0){event2.preventDefault(),$$props.onFilesAdd?.(files);return}const text2=event2.clipboardData.getData(MimeTypeText.PLAIN);if(text2.startsWith(CLIPBOARD_CONTENT_QUOTE_PREFIX)){const parsed=parseClipboardContent(text2);if(parsed.textAttachments.length>0||parsed.mcpPromptAttachments.length>
[att.content],`${att.name}${FileExtensionText.TXT}`,{type:MimeTypeText.PLAIN}),isLoading:!1,textContent:att.content,mcpPrompt:{serverName:att.serverName,promptName:att.promptName,arguments:att.arguments}}));uploadedFiles([...uploadedFiles(),...mcpPromptFiles]),$$props.onUploadedFilesChange?.(uploadedFiles())}setTimeout(()=>{get$3(textareaRef)?.focus()},10);return}}if(text2.length>0&&get$3(pasteLongTextToFileLength)>0&&text2.length>get$3(pasteLongTextToFileLength)){event2.preventDefault();const textFile=new File( 0){if(event2.preventDefault(),value(parsed.message),$$props.onValueChange?.(parsed.message),parsed.textAttachments.length>0){const attachmentFiles=parsed.textAttachments.map(att=>new File([att.content],att.name,{type:MimeTypeText.PLAIN}));$$props.onFilesAdd?.(attachmentFiles)}if(parsed.mcpPromptAttachments.length>0){const mcpPromptFiles=parsed.mcpPromptAttachments.map(att=>({id:uuid$1(),name:att.name,size:att.content.length,type:SpecialFileType.MCP_PROMPT,file:new File([att.content],`${att.name}${FileExtensionText.
[text2],"Pasted",{type:MimeTypeText.PLAIN});$$props.onFilesAdd?.([textFile])}}function handlePromptLoadStart(placeholderId,promptInfo,args){value().startsWith(PROMPT_TRIGGER_PREFIX)&&(value(""),$$props.onValueChange?.("")),set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,"");const promptName=promptInfo.title||promptInfo.name,placeholder2={id:placeholderId,name:promptName,size:INITIAL_FILE_SIZE,type:SpecialFileType.MCP_PROMPT,file:new File([],"loading"),isLoading:!0,mcpPrompt:{serverName:promptInfo. TXT}`,{type:MimeTypeText.PLAIN}),isLoading:!1,textContent:att.content,mcpPrompt:{serverName:att.serverName,promptName:att.promptName,arguments:att.arguments}}));uploadedFiles([...uploadedFiles(),...mcpPromptFiles]),$$props.onUploadedFilesChange?.(uploadedFiles())}setTimeout(()=>{get$3(textareaRef)?.focus()},10);return}}if(text2.length>0&&get$3(pasteLongTextToFileLength)>0&&text2.length>get$3(pasteLongTextToFileLength)){event2.preventDefault();const textFile=new File([text2],"Pasted",{type:MimeTypeText.
serverName,promptName:promptInfo.name,arguments:args?{...args}:void 0}};uploadedFiles([...uploadedFiles(),placeholder2]),$$props.onUploadedFilesChange?.(uploadedFiles()),get$3(textareaRef)?.focus()}function handlePromptLoadComplete(placeholderId,result){const promptText=result.messages?.map(msg=>typeof msg.content=="string"?msg.content:msg.content.type===ContentPartType.TEXT?msg.content.text:"").filter(Boolean).join(PROMPT_CONTENT_SEPARATOR);uploadedFiles(uploadedFiles().map(f=>f.id===placeholderId? PLAIN});$$props.onFilesAdd?.([textFile])}}function handlePromptLoadStart(placeholderId,promptInfo,args){value().startsWith(PROMPT_TRIGGER_PREFIX)&&(value(""),$$props.onValueChange?.("")),set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,"");const promptName=promptInfo.title||promptInfo.name,placeholder2={id:placeholderId,name:promptName,size:INITIAL_FILE_SIZE,type:SpecialFileType.MCP_PROMPT,file:new File([],"loading"),isLoading:!0,mcpPrompt:{serverName:promptInfo.serverName,promptName:promptInfo.
{...f,isLoading:!1,textContent:promptText,size:promptText.length,file:new File([promptText],`${f.name}${FileExtensionText.TXT}`,{type:MimeTypeText.PLAIN})}:f)),$$props.onUploadedFilesChange?.(uploadedFiles())}function handlePromptLoadError(placeholderId,error2){uploadedFiles(uploadedFiles().map(f=>f.id===placeholderId?{...f,isLoading:!1,loadError:error2}:f)),$$props.onUploadedFilesChange?.(uploadedFiles())}function handlePromptPickerClose(){set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,""), name,arguments:args?{...args}:void 0}};uploadedFiles([...uploadedFiles(),placeholder2]),$$props.onUploadedFilesChange?.(uploadedFiles()),get$3(textareaRef)?.focus()}function handlePromptLoadComplete(placeholderId,result){const promptText=result.messages?.map(msg=>typeof msg.content=="string"?msg.content:msg.content.type===ContentPartType.TEXT?msg.content.text:"").filter(Boolean).join(PROMPT_CONTENT_SEPARATOR);uploadedFiles(uploadedFiles().map(f=>f.id===placeholderId?{...f,isLoading:!1,textContent:promptText,
get$3(textareaRef)?.focus()}function handleInlineResourcePickerClose(){set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""),get$3(textareaRef)?.focus()}function handleInlineResourceSelect(){value().startsWith(RESOURCE_TRIGGER_PREFIX)&&(value(""),$$props.onValueChange?.("")),set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""),get$3(textareaRef)?.focus()}function handleBrowseResources(){set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""),value().startsWith( size:promptText.length,file:new File([promptText],`${f.name}${FileExtensionText.TXT}`,{type:MimeTypeText.PLAIN})}:f)),$$props.onUploadedFilesChange?.(uploadedFiles())}function handlePromptLoadError(placeholderId,error2){uploadedFiles(uploadedFiles().map(f=>f.id===placeholderId?{...f,isLoading:!1,loadError:error2}:f)),$$props.onUploadedFilesChange?.(uploadedFiles())}function handlePromptPickerClose(){set$1(isPromptPickerOpen,!1),set$1(promptSearchQuery,""),get$3(textareaRef)?.focus()}function handleInlineResourcePickerClose(){
RESOURCE_TRIGGER_PREFIX)&&(value(""),$$props.onValueChange?.("")),set$1(isResourceDialogOpen,!0)}async function handleMicClick(){if(!audioRecorder||!get$3(recordingSupported)){console.warn("Audio recording not supported");return}if(get$3(isRecording)){set$1(isRecording,!1);try{const audioBlob=await audioRecorder.stopRecording(),wavBlob=await convertToWav(audioBlob),audioFile=createAudioFile(wavBlob);$$props.onFilesAdd?.([audioFile])}catch(error2){console.error("Failed to stop recording:",error2)}}else set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""),get$3(textareaRef)?.focus()}function handleInlineResourceSelect(){value().startsWith(RESOURCE_TRIGGER_PREFIX)&&(value(""),$$props.onValueChange?.("")),set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""),get$3(textareaRef)?.focus()}function handleBrowseResources(){set$1(isInlineResourcePickerOpen,!1),set$1(resourceSearchQuery,""),value().startsWith(RESOURCE_TRIGGER_PREFIX)&&(value(""),$$props.onValueChange?.("")),set$1(
try{await audioRecorder.startRecording(),set$1(isRecording,!0)}catch(error2){console.error("Failed to start recording:",error2)}}var $$exports={focus:focus2,resetTextareaHeight,openModelSelector,checkModelSelected},fragment=root$1u(),node2=first_child(fragment);bind_this(ChatFormFileInputInvisible(node2,{onFileSelect:handleFileSelect}),$$value=>set$1(fileInputRef,$$value,!0),()=>get$3(fileInputRef));var form=sibling(node2,2),node_1=child(form);bind_this(ChatFormPickers(node_1,{get isPromptPickerOpen(){ isResourceDialogOpen,!0)}async function handleMicClick(){if(!audioRecorder||!get$3(recordingSupported)){console.warn("Audio recording not supported");return}if(get$3(isRecording)){set$1(isRecording,!1);try{const audioBlob=await audioRecorder.stopRecording(),wavBlob=await convertToWav(audioBlob),audioFile=createAudioFile(wavBlob);$$props.onFilesAdd?.([audioFile])}catch(error2){console.error("Failed to stop recording:",error2)}}else try{await audioRecorder.startRecording(),set$1(isRecording,!0)}catch(error2){
return get$3(isPromptPickerOpen)},get promptSearchQuery(){return get$3(promptSearchQuery)},get isInlineResourcePickerOpen(){return get$3(isInlineResourcePickerOpen)},get resourceSearchQuery(){return get$3(resourceSearchQuery)},onPromptPickerClose:handlePromptPickerClose,onInlineResourcePickerClose:handleInlineResourcePickerClose,onInlineResourceSelect:handleInlineResourceSelect,onPromptLoadStart:handlePromptLoadStart,onPromptLoadComplete:handlePromptLoadComplete,onPromptLoadError:handlePromptLoadError, console.error("Failed to start recording:",error2)}}var $$exports={focus:focus2,resetTextareaHeight,openModelSelector,checkModelSelected},fragment=root$1u(),node2=first_child(fragment);bind_this(ChatFormFileInputInvisible(node2,{onFileSelect:handleFileSelect}),$$value=>set$1(fileInputRef,$$value,!0),()=>get$3(fileInputRef));var form=sibling(node2,2),node_1=child(form);bind_this(ChatFormPickers(node_1,{get isPromptPickerOpen(){return get$3(isPromptPickerOpen)},get promptSearchQuery(){return get$3(
onInlineResourceBrowse:handleBrowseResources}),$$value=>set$1(pickersRef,$$value,!0),()=>get$3(pickersRef));var div=sibling(node_1,2),node_2=child(div);{let $0=user_derived(()=>get$3(activeModelId)??void 0);ChatAttachmentsList(node_2,{get attachments(){return attachments()},onFileRemove:handleFileRemove,limitToSingleRow:!0,class:"py-5",style:"scroll-padding: 1rem;",get activeModelId(){return get$3($0)},get uploadedFiles(){return uploadedFiles()},set uploadedFiles($$value){uploadedFiles($$value)}})} promptSearchQuery)},get isInlineResourcePickerOpen(){return get$3(isInlineResourcePickerOpen)},get resourceSearchQuery(){return get$3(resourceSearchQuery)},onPromptPickerClose:handlePromptPickerClose,onInlineResourcePickerClose:handleInlineResourcePickerClose,onInlineResourceSelect:handleInlineResourceSelect,onPromptLoadStart:handlePromptLoadStart,onPromptLoadComplete:handlePromptLoadComplete,onPromptLoadError:handlePromptLoadError,onInlineResourceBrowse:handleBrowseResources}),$$value=>set$1(pickersRef,
var div_1=sibling(node_2,2),node_3=child(div_1);bind_this(ChatFormTextarea(node_3,{class:"px-5 py-1.5 md:pt-0",onKeydown:handleKeydown,onInput:()=>{handleInput(),$$props.onValueChange?.(value())},get disabled(){return disabled()},get placeholder(){return placeholder()},get value(){return value()},set value($$value){value($$value)}}),$$value=>set$1(textareaRef,$$value,!0),()=>get$3(textareaRef));var node_4=sibling(node_3,2);{var consequent=$$anchor2=>{ChatFormMcpResourcesList($$anchor2,{class:"mb\ $$value,!0),()=>get$3(pickersRef));var div=sibling(node_1,2),node_2=child(div);{let $0=user_derived(()=>get$3(activeModelId)??void 0);ChatAttachmentsList(node_2,{get attachments(){return attachments()},onFileRemove:handleFileRemove,limitToSingleRow:!0,class:"py-5",style:"scroll-padding: 1rem;",get activeModelId(){return get$3($0)},get uploadedFiles(){return uploadedFiles()},set uploadedFiles($$value){uploadedFiles($$value)}})}var div_1=sibling(node_2,2),node_3=child(div_1);bind_this(ChatFormTextarea(
-3",onResourceClick:uri2=>{set$1(preSelectedResourceUri,uri2,!0),set$1(isResourceDialogOpen,!0)}})},d2=user_derived(()=>mcpHasResourceAttachments());if_block(node_4,$$render=>{get$3(d2)&&$$render(consequent)})}var node_5=sibling(node_4,2);{let $0=user_derived(()=>showMcpPromptButton()?()=>set$1(isPromptPickerOpen,!0):void 0);bind_this(ChatFormActions(node_5,{class:"px-3",get canSend(){return get$3(canSubmit)},get disabled(){return disabled()},get isLoading(){return isLoading2()},get isRecording(){ node_3,{class:"px-5 py-1.5 md:pt-0",onKeydown:handleKeydown,onInput:()=>{handleInput(),$$props.onValueChange?.(value())},get disabled(){return disabled()},get placeholder(){return placeholder()},get value(){return value()},set value($$value){value($$value)}}),$$value=>set$1(textareaRef,$$value,!0),()=>get$3(textareaRef));var node_4=sibling(node_3,2);{var consequent=$$anchor2=>{ChatFormMcpResourcesList($$anchor2,{class:"mb-3",onResourceClick:uri2=>{set$1(preSelectedResourceUri,uri2,!0),set$1(isResourceDialogOpen,
return get$3(isRecording)},get showAddButton(){return showAddButton()},get showModelSelector(){return showModelSelector()},get uploadedFiles(){return uploadedFiles()},onFileUpload:handleFileUpload,onMicClick:handleMicClick,get onStop(){return $$props.onStop},onSystemPromptClick:()=>$$props.onSystemPromptClick?.({message:value(),files:uploadedFiles()}),get onMcpPromptClick(){return get$3($0)},onMcpResourcesClick:()=>set$1(isResourceDialogOpen,!0)}),$$value=>set$1(chatFormActionsRef,$$value,!0),()=>get$3( !0)}})},d2=user_derived(()=>mcpHasResourceAttachments());if_block(node_4,$$render=>{get$3(d2)&&$$render(consequent)})}var node_5=sibling(node_4,2);{let $0=user_derived(()=>showMcpPromptButton()?()=>set$1(isPromptPickerOpen,!0):void 0);bind_this(ChatFormActions(node_5,{class:"px-3",get canSend(){return get$3(canSubmit)},get disabled(){return disabled()},get isLoading(){return isLoading2()},get isRecording(){return get$3(isRecording)},get showAddButton(){return showAddButton()},get showModelSelector(){
chatFormActionsRef))}reset(div_1),reset(div),reset(form);var node_6=sibling(form,2);return DialogMcpResourcesBrowser(node_6,{get preSelectedUri(){return get$3(preSelectedResourceUri)},onAttach:resource=>{mcpStore.attachResource(resource.uri)},onOpenChange:newOpen=>{newOpen||set$1(preSelectedResourceUri,void 0)},get open(){return get$3(isResourceDialogOpen)},set open($$value){set$1(isResourceDialogOpen,$$value,!0)}}),template_effect(()=>{set_class(form,1,`relative ${className()??""}`),set_class(div, return showModelSelector()},get uploadedFiles(){return uploadedFiles()},onFileUpload:handleFileUpload,onMicClick:handleMicClick,get onStop(){return $$props.onStop},onSystemPromptClick:()=>$$props.onSystemPromptClick?.({message:value(),files:uploadedFiles()}),get onMcpPromptClick(){return get$3($0)},onMcpResourcesClick:()=>set$1(isResourceDialogOpen,!0)}),$$value=>set$1(chatFormActionsRef,$$value,!0),()=>get$3(chatFormActionsRef))}reset(div_1),reset(div),reset(form);var node_6=sibling(form,2);return DialogMcpResourcesBrowser(
1,`${INPUT_CLASSES??""} overflow-hidden rounded-3xl backdrop-blur-md ${disabled()?"cursor-not-allowed opacity-60":""}`)}),event("submit",form,event2=>{event2.preventDefault(),!(!get$3(canSubmit)||disabled()||get$3(hasLoadingAttachments))&&$$props.onSubmit?.()}),event("paste",div_1,handlePaste),append($$anchor,fragment),pop($$exports)}function Dropdown_menu_content($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),sideOffset=prop($$props,"sideOffset",3,4),restProps=rest_props( node_6,{get preSelectedUri(){return get$3(preSelectedResourceUri)},onAttach:resource=>{mcpStore.attachResource(resource.uri)},onOpenChange:newOpen=>{newOpen||set$1(preSelectedResourceUri,void 0)},get open(){return get$3(isResourceDialogOpen)},set open($$value){set$1(isResourceDialogOpen,$$value,!0)}}),template_effect(()=>{set_class(form,1,`relative ${className()??""}`),set_class(div,1,`${INPUT_CLASSES??""} overflow-hidden rounded-3xl backdrop-blur-md ${disabled()?"cursor-not-allowed opacity-60":
$$props,["$$slots","$$events","$$legacy","ref","sideOffset","portalProps","class"]);var fragment=comment$2(),node2=first_child(fragment);component(node2,()=>Portal$2,($$anchor2,DropdownMenuPrimitive_Portal)=>{DropdownMenuPrimitive_Portal($$anchor2,spread_props(()=>$$props.portalProps,{children:($$anchor3,$$slotProps)=>{var fragment_1=comment$2(),node_1=first_child(fragment_1);{let $0=user_derived(()=>cn$1("z-50 max-h-(--bits-dropdown-menu-content-available-height) min-w-[8rem] origin-(--bits-dro\ ""}`)}),event("submit",form,event2=>{event2.preventDefault(),!(!get$3(canSubmit)||disabled()||get$3(hasLoadingAttachments))&&$$props.onSubmit?.()}),event("paste",div_1,handlePaste),append($$anchor,fragment),pop($$exports)}function Dropdown_menu_content($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),sideOffset=prop($$props,"sideOffset",3,4),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","sideOffset","portalProps","class"]);var fragment=comment$2(),node2=first_child(
pdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-md outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:fill-mode-forwards data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=op\ fragment);component(node2,()=>Portal$2,($$anchor2,DropdownMenuPrimitive_Portal)=>{DropdownMenuPrimitive_Portal($$anchor2,spread_props(()=>$$props.portalProps,{children:($$anchor3,$$slotProps)=>{var fragment_1=comment$2(),node_1=first_child(fragment_1);{let $0=user_derived(()=>cn$1("z-50 max-h-(--bits-dropdown-menu-content-available-height) min-w-[8rem] origin-(--bits-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-popover p-1.5 text-po\
en]:fade-in-0 data-[state=open]:zoom-in-95 dark:border-border/20",$$props.class));component(node_1,()=>Dropdown_menu_content$1,($$anchor4,DropdownMenuPrimitive_Content)=>{DropdownMenuPrimitive_Content($$anchor4,spread_props({"data-slot":"dropdown-menu-content",get sideOffset(){return sideOffset()},get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor3,fragment_1)},$$slots:{default:!0}}))}),append($$anchor,fragment),pop()}function Dropdown_menu_item($$anchor,$$props){ pover-foreground shadow-md outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:fill-mode-forwards data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 dark:border-border/20",$$props.class));component(node_1,()=>Dropdown_menu_content$1,
push$1($$props,!0);let ref2=prop($$props,"ref",15,null),variant=prop($$props,"variant",3,"default"),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","inset","variant"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[disabled]:pointer-events-none data-[disab\ ($$anchor4,DropdownMenuPrimitive_Content)=>{DropdownMenuPrimitive_Content($$anchor4,spread_props({"data-slot":"dropdown-menu-content",get sideOffset(){return sideOffset()},get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor3,fragment_1)},$$slots:{default:!0}}))}),append($$anchor,fragment),pop()}function Dropdown_menu_item($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),variant=prop($$props,"variant",
led]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:data-highlighted:bg-destructive/10 data-[variant=destructive]:data-highlighted:text-destructive dark:data-[variant=destructive]:data-highlighted:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:!text-destructive",$$props.class));component(node2,()=>Menu_item, 3,"default"),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","inset","variant"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[var\
($$anchor2,DropdownMenuPrimitive_Item)=>{DropdownMenuPrimitive_Item($$anchor2,spread_props({"data-slot":"dropdown-menu-item",get"data-inset"(){return $$props.inset},get"data-variant"(){return variant()},get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}function Dropdown_menu_separator($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events", iant=destructive]:data-highlighted:bg-destructive/10 data-[variant=destructive]:data-highlighted:text-destructive dark:data-[variant=destructive]:data-highlighted:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:!text-destructive",$$props.class));component(node2,()=>Menu_item,($$anchor2,DropdownMenuPrimitive_Item)=>{DropdownMenuPrimitive_Item($$anchor2,spread_props(
"$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("-mx-1 my-1 h-px bg-border/20",$$props.class));component(node2,()=>Menu_separator,($$anchor2,DropdownMenuPrimitive_Separator)=>{DropdownMenuPrimitive_Separator($$anchor2,spread_props({"data-slot":"dropdown-menu-separator",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}function Dropdown_menu_trigger($$anchor,$$props){ {"data-slot":"dropdown-menu-item",get"data-inset"(){return $$props.inset},get"data-variant"(){return variant()},get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}function Dropdown_menu_separator($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(
push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref"]);var fragment=comment$2(),node2=first_child(fragment);component(node2,()=>Menu_trigger,($$anchor2,DropdownMenuPrimitive_Trigger)=>{DropdownMenuPrimitive_Trigger($$anchor2,spread_props({"data-slot":"dropdown-menu-trigger"},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))}),append($$anchor,fragment),pop()}function Dropdown_menu_sub_content($$anchor,$$props){ ()=>cn$1("-mx-1 my-1 h-px bg-border/20",$$props.class));component(node2,()=>Menu_separator,($$anchor2,DropdownMenuPrimitive_Separator)=>{DropdownMenuPrimitive_Separator($$anchor2,spread_props({"data-slot":"dropdown-menu-separator",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}function Dropdown_menu_trigger($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,
push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("z-50 max-h-(--bits-dropdown-menu-content-available-height) min-w-[8rem] origin-(--bits-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-md outline-none data-[side=bottom]:slide-\ ["$$slots","$$events","$$legacy","ref"]);var fragment=comment$2(),node2=first_child(fragment);component(node2,()=>Menu_trigger,($$anchor2,DropdownMenuPrimitive_Trigger)=>{DropdownMenuPrimitive_Trigger($$anchor2,spread_props({"data-slot":"dropdown-menu-trigger"},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))}),append($$anchor,fragment),pop()}function Dropdown_menu_sub_content($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props(
in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:fill-mode-forwards data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 dark:border-border/20",$$props.class));component(node2,()=>Menu_sub_content,($$anchor2,DropdownMenuPrimitive_SubContent)=>{DropdownMenuPrimitive_SubContent( $$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("z-50 max-h-(--bits-dropdown-menu-content-available-height) min-w-[8rem] origin-(--bits-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-md outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-\
$$anchor2,spread_props({"data-slot":"dropdown-menu-sub-content",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}var root_1$P=from_html("<!> <!>",1);function Dropdown_menu_sub_trigger($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","inset","children"]);var fragment=comment$2(),node2=first_child(fragment);{ in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:fill-mode-forwards data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 dark:border-border/20",$$props.class));component(node2,()=>Menu_sub_content,($$anchor2,DropdownMenuPrimitive_SubContent)=>{DropdownMenuPrimitive_SubContent($$anchor2,spread_props({"data-slot":"dropdown-menu-sub-content",get class(){
let $0=user_derived(()=>cn$1("flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",$$props.class));component( return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}var root_1$P=from_html("<!> <!>",1);function Dropdown_menu_sub_trigger($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","inset","children"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("flex cursor-default items-center gap-2 rounded\
node2,()=>Menu_sub_trigger,($$anchor2,DropdownMenuPrimitive_SubTrigger)=>{DropdownMenuPrimitive_SubTrigger($$anchor2,spread_props({"data-slot":"dropdown-menu-sub-trigger",get"data-inset"(){return $$props.inset},get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)},children:($$anchor3,$$slotProps)=>{var fragment_1=root_1$P(),node_1=first_child(fragment_1);snippet(node_1,()=>$$props.children??noop$3);var node_2=sibling(node_1,2);Chevron_right(node_2, -sm px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",$$props.class));component(node2,()=>Menu_sub_trigger,($$anchor2,DropdownMenuPrimitive_SubTrigger)=>{
{class:"ml-auto size-4"}),append($$anchor3,fragment_1)},$$slots:{default:!0}}))})}append($$anchor,fragment),pop()}const Sub=Menu_sub,Root$4=Menu;function useAttachmentMenu(getFlags,getCallbacks,close2){const modalityFlags=user_derived(getFlags),callbacks=user_derived(()=>{const cbs=getCallbacks(),wrap2=fn=>()=>{close2(),fn?.()};return{[AttachmentAction.FILE_UPLOAD]:wrap2(cbs.onFileUpload),[AttachmentAction.SYSTEM_PROMPT_CLICK]:wrap2(cbs.onSystemPromptClick),[AttachmentAction.MCP_PROMPT_CLICK]:wrap2( DropdownMenuPrimitive_SubTrigger($$anchor2,spread_props({"data-slot":"dropdown-menu-sub-trigger",get"data-inset"(){return $$props.inset},get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)},children:($$anchor3,$$slotProps)=>{var fragment_1=root_1$P(),node_1=first_child(fragment_1);snippet(node_1,()=>$$props.children??noop$3);var node_2=sibling(node_1,2);Chevron_right(node_2,{class:"ml-auto size-4"}),append($$anchor3,fragment_1)},$$slots:{default:!0}}))})}
cbs.onMcpPromptClick),[AttachmentAction.MCP_RESOURCES_CLICK]:wrap2(cbs.onMcpResourcesClick)}});function isItemEnabled(enabledWhen){return!enabledWhen||enabledWhen==="always"?!0:!!get$3(modalityFlags)[enabledWhen]}function isItemVisible(visibleWhen){return visibleWhen?!!get$3(modalityFlags)[visibleWhen]:!0}function getSystemMessageTooltip(){return page$1.params.id?"Inject custom system message at the beginning of the conversation":"Add custom system message for a new conversation"}return{get callbacks(){ append($$anchor,fragment),pop()}const Sub=Menu_sub,Root$4=Menu;function useAttachmentMenu(getFlags,getCallbacks,close2){const modalityFlags=user_derived(getFlags),callbacks=user_derived(()=>{const cbs=getCallbacks(),wrap2=fn=>()=>{close2(),fn?.()};return{[AttachmentAction.FILE_UPLOAD]:wrap2(cbs.onFileUpload),[AttachmentAction.SYSTEM_PROMPT_CLICK]:wrap2(cbs.onSystemPromptClick),[AttachmentAction.MCP_PROMPT_CLICK]:wrap2(cbs.onMcpPromptClick),[AttachmentAction.MCP_RESOURCES_CLICK]:wrap2(cbs.onMcpResourcesClick)}});
return get$3(callbacks)},isItemEnabled,isItemVisible,getSystemMessageTooltip}}var root_6$s=from_html("<!> <span> </span>",1),root_10$f=from_html("<!> <span> </span>",1),root_11$e=from_html("<p> </p>"),root_8$r=from_html("<!> <!>",1),root_16$6=from_html("<!> <span> </span>",1),root_17$8=from_html("<p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>"),root_13$d=from_html("<!> <!>",1),root_22$2=from_html("<!> <span> </span>",1),root_23$5=from_html("<p> </p>"),root_20$5=from_html( function isItemEnabled(enabledWhen){return!enabledWhen||enabledWhen==="always"?!0:!!get$3(modalityFlags)[enabledWhen]}function isItemVisible(visibleWhen){return visibleWhen?!!get$3(modalityFlags)[visibleWhen]:!0}function getSystemMessageTooltip(){return page$1.params.id?"Inject custom system message at the beginning of the conversation":"Add custom system message for a new conversation"}return{get callbacks(){return get$3(callbacks)},isItemEnabled,isItemVisible,getSystemMessageTooltip}}var root_6$s=from_html(
"<!> <!>",1),root_26$2=from_html("<!> <span> </span>",1),root_3$S=from_html("<!> <!> <!> <!> <!> <!> <!>",1),root_1$O=from_html("<!> <!>",1),root$1t=from_html("<div><!></div>");function ChatFormActionAddDropdown($$anchor,$$props){push$1($$props,!0);let className=prop($$props,"class",3,""),disabled=prop($$props,"disabled",3,!1),hasAudioModality=prop($$props,"hasAudioModality",3,!1),hasVisionModality=prop($$props,"hasVisionModality",3,!1),hasMcpPromptsSupport=prop($$props,"hasMcpPromptsSupport",3, "<!> <span> </span>",1),root_10$f=from_html("<!> <span> </span>",1),root_11$e=from_html("<p> </p>"),root_8$r=from_html("<!> <!>",1),root_16$6=from_html("<!> <span> </span>",1),root_17$8=from_html("<p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>"),root_13$d=from_html("<!> <!>",1),root_22$2=from_html("<!> <span> </span>",1),root_23$5=from_html("<p> </p>"),root_20$5=from_html("<!> <!>",1),root_26$2=from_html("<!> <span> </span>",1),root_3$S=from_html("<!> <!> <!> <!> \
!1),hasMcpResourcesSupport=prop($$props,"hasMcpResourcesSupport",3,!1),dropdownOpen=state$1(!1);function handleMcpSettingsClick(){set$1(dropdownOpen,!1),$$props.onMcpSettingsClick?.()}const attachmentMenu=useAttachmentMenu(()=>({hasVisionModality:hasVisionModality(),hasAudioModality:hasAudioModality(),hasMcpPromptsSupport:hasMcpPromptsSupport(),hasMcpResourcesSupport:hasMcpResourcesSupport()}),()=>({onFileUpload:$$props.onFileUpload,onSystemPromptClick:$$props.onSystemPromptClick,onMcpPromptClick:$$props. <!> <!> <!>",1),root_1$O=from_html("<!> <!>",1),root$1t=from_html("<div><!></div>");function ChatFormActionAddDropdown($$anchor,$$props){push$1($$props,!0);let className=prop($$props,"class",3,""),disabled=prop($$props,"disabled",3,!1),hasAudioModality=prop($$props,"hasAudioModality",3,!1),hasVisionModality=prop($$props,"hasVisionModality",3,!1),hasMcpPromptsSupport=prop($$props,"hasMcpPromptsSupport",3,!1),hasMcpResourcesSupport=prop($$props,"hasMcpResourcesSupport",3,!1),dropdownOpen=state$1(!1);
onMcpPromptClick,onMcpResourcesClick:$$props.onMcpResourcesClick}),()=>{set$1(dropdownOpen,!1)});var div=root$1t(),node2=child(div);component(node2,()=>Root$4,($$anchor2,DropdownMenu_Root)=>{DropdownMenu_Root($$anchor2,{get open(){return get$3(dropdownOpen)},set open($$value){set$1(dropdownOpen,$$value,!0)},children:($$anchor3,$$slotProps)=>{var fragment=root_1$O(),node_1=first_child(fragment);component(node_1,()=>Dropdown_menu_trigger,($$anchor4,DropdownMenu_Trigger)=>{DropdownMenu_Trigger($$anchor4, function handleMcpSettingsClick(){set$1(dropdownOpen,!1),$$props.onMcpSettingsClick?.()}const attachmentMenu=useAttachmentMenu(()=>({hasVisionModality:hasVisionModality(),hasAudioModality:hasAudioModality(),hasMcpPromptsSupport:hasMcpPromptsSupport(),hasMcpResourcesSupport:hasMcpResourcesSupport()}),()=>({onFileUpload:$$props.onFileUpload,onSystemPromptClick:$$props.onSystemPromptClick,onMcpPromptClick:$$props.onMcpPromptClick,onMcpResourcesClick:$$props.onMcpResourcesClick}),()=>{set$1(dropdownOpen,
{name:"Attach files",get disabled(){return disabled()},children:($$anchor5,$$slotProps2)=>{var fragment_1=comment$2(),node_2=first_child(fragment_1);snippet(node_2,()=>$$props.trigger,()=>({disabled:disabled()})),append($$anchor5,fragment_1)},$$slots:{default:!0}})});var node_3=sibling(node_1,2);component(node_3,()=>Dropdown_menu_content,($$anchor4,DropdownMenu_Content)=>{DropdownMenu_Content($$anchor4,{align:"start",class:"w-48",children:($$anchor5,$$slotProps2)=>{var fragment_2=root_3$S(),node_4=first_child( !1)});var div=root$1t(),node2=child(div);component(node2,()=>Root$4,($$anchor2,DropdownMenu_Root)=>{DropdownMenu_Root($$anchor2,{get open(){return get$3(dropdownOpen)},set open($$value){set$1(dropdownOpen,$$value,!0)},children:($$anchor3,$$slotProps)=>{var fragment=root_1$O(),node_1=first_child(fragment);component(node_1,()=>Dropdown_menu_trigger,($$anchor4,DropdownMenu_Trigger)=>{DropdownMenu_Trigger($$anchor4,{name:"Attach files",get disabled(){return disabled()},children:($$anchor5,$$slotProps2)=>{
fragment_2);each(node_4,17,()=>ATTACHMENT_FILE_ITEMS,item=>item.id,($$anchor6,item)=>{const enabled=user_derived(()=>attachmentMenu.isItemEnabled(get$3(item).enabledWhen));var fragment_3=comment$2(),node_5=first_child(fragment_3);{var consequent=$$anchor7=>{var fragment_4=comment$2(),node_6=first_child(fragment_4);{let $0=user_derived(()=>get$3(item).class??"");component(node_6,()=>Dropdown_menu_item,($$anchor8,DropdownMenu_Item)=>{DropdownMenu_Item($$anchor8,{get class(){return`${get$3($0)??""}\ var fragment_1=comment$2(),node_2=first_child(fragment_1);snippet(node_2,()=>$$props.trigger,()=>({disabled:disabled()})),append($$anchor5,fragment_1)},$$slots:{default:!0}})});var node_3=sibling(node_1,2);component(node_3,()=>Dropdown_menu_content,($$anchor4,DropdownMenu_Content)=>{DropdownMenu_Content($$anchor4,{align:"start",class:"w-48",children:($$anchor5,$$slotProps2)=>{var fragment_2=root_3$S(),node_4=first_child(fragment_2);each(node_4,17,()=>ATTACHMENT_FILE_ITEMS,item=>item.id,($$anchor6,item)=>{
flex cursor-pointer items-center gap-2`},onclick:()=>attachmentMenu.callbacks[get$3(item).action](),children:($$anchor9,$$slotProps3)=>{var fragment_5=root_6$s(),node_7=first_child(fragment_5);component(node_7,()=>get$3(item).icon,($$anchor10,item_icon)=>{item_icon($$anchor10,{class:"h-4 w-4"})});var span=sibling(node_7,2),text2=child(span,!0);reset(span),template_effect(()=>set_text(text2,get$3(item).label)),append($$anchor9,fragment_5)},$$slots:{default:!0}})})}append($$anchor7,fragment_4)},consequent_1=$$anchor7=>{ const enabled=user_derived(()=>attachmentMenu.isItemEnabled(get$3(item).enabledWhen));var fragment_3=comment$2(),node_5=first_child(fragment_3);{var consequent=$$anchor7=>{var fragment_4=comment$2(),node_6=first_child(fragment_4);{let $0=user_derived(()=>get$3(item).class??"");component(node_6,()=>Dropdown_menu_item,($$anchor8,DropdownMenu_Item)=>{DropdownMenu_Item($$anchor8,{get class(){return`${get$3($0)??""} flex cursor-pointer items-center gap-2`},onclick:()=>attachmentMenu.callbacks[get$3(item).
var fragment_6=comment$2(),node_8=first_child(fragment_6);component(node_8,()=>Root$5,($$anchor8,Tooltip_Root)=>{Tooltip_Root($$anchor8,{get delayDuration(){return TOOLTIP_DELAY_DURATION},children:($$anchor9,$$slotProps3)=>{var fragment_7=root_8$r(),node_9=first_child(fragment_7);component(node_9,()=>Tooltip_trigger,($$anchor10,Tooltip_Trigger)=>{Tooltip_Trigger($$anchor10,{class:"w-full",children:($$anchor11,$$slotProps4)=>{var fragment_8=comment$2(),node_10=first_child(fragment_8);{let $0=user_derived( action](),children:($$anchor9,$$slotProps3)=>{var fragment_5=root_6$s(),node_7=first_child(fragment_5);component(node_7,()=>get$3(item).icon,($$anchor10,item_icon)=>{item_icon($$anchor10,{class:"h-4 w-4"})});var span=sibling(node_7,2),text2=child(span,!0);reset(span),template_effect(()=>set_text(text2,get$3(item).label)),append($$anchor9,fragment_5)},$$slots:{default:!0}})})}append($$anchor7,fragment_4)},consequent_1=$$anchor7=>{var fragment_6=comment$2(),node_8=first_child(fragment_6);component(
()=>get$3(item).class??"");component(node_10,()=>Dropdown_menu_item,($$anchor12,DropdownMenu_Item_1)=>{DropdownMenu_Item_1($$anchor12,{get class(){return`${get$3($0)??""} flex cursor-pointer items-center gap-2`},disabled:!0,children:($$anchor13,$$slotProps5)=>{var fragment_9=root_10$f(),node_11=first_child(fragment_9);component(node_11,()=>get$3(item).icon,($$anchor14,item_icon_1)=>{item_icon_1($$anchor14,{class:"h-4 w-4"})});var span_1=sibling(node_11,2),text_1=child(span_1,!0);reset(span_1),template_effect( node_8,()=>Root$5,($$anchor8,Tooltip_Root)=>{Tooltip_Root($$anchor8,{get delayDuration(){return TOOLTIP_DELAY_DURATION},children:($$anchor9,$$slotProps3)=>{var fragment_7=root_8$r(),node_9=first_child(fragment_7);component(node_9,()=>Tooltip_trigger,($$anchor10,Tooltip_Trigger)=>{Tooltip_Trigger($$anchor10,{class:"w-full",children:($$anchor11,$$slotProps4)=>{var fragment_8=comment$2(),node_10=first_child(fragment_8);{let $0=user_derived(()=>get$3(item).class??"");component(node_10,()=>Dropdown_menu_item,
()=>set_text(text_1,get$3(item).label)),append($$anchor13,fragment_9)},$$slots:{default:!0}})})}append($$anchor11,fragment_8)},$$slots:{default:!0}})});var node_12=sibling(node_9,2);component(node_12,()=>Tooltip_content,($$anchor10,Tooltip_Content)=>{Tooltip_Content($$anchor10,{side:"right",children:($$anchor11,$$slotProps4)=>{var p2=root_11$e(),text_2=child(p2,!0);reset(p2),template_effect(()=>set_text(text_2,get$3(item).disabledTooltip)),append($$anchor11,p2)},$$slots:{default:!0}})}),append($$anchor9, ($$anchor12,DropdownMenu_Item_1)=>{DropdownMenu_Item_1($$anchor12,{get class(){return`${get$3($0)??""} flex cursor-pointer items-center gap-2`},disabled:!0,children:($$anchor13,$$slotProps5)=>{var fragment_9=root_10$f(),node_11=first_child(fragment_9);component(node_11,()=>get$3(item).icon,($$anchor14,item_icon_1)=>{item_icon_1($$anchor14,{class:"h-4 w-4"})});var span_1=sibling(node_11,2),text_1=child(span_1,!0);reset(span_1),template_effect(()=>set_text(text_1,get$3(item).label)),append($$anchor13,
fragment_7)},$$slots:{default:!0}})}),append($$anchor7,fragment_6)};if_block(node_5,$$render=>{get$3(enabled)?$$render(consequent):get$3(item).disabledTooltip&&$$render(consequent_1,1)})}append($$anchor6,fragment_3)});var node_13=sibling(node_4,2);{var consequent_3=$$anchor6=>{var fragment_10=comment$2(),node_14=first_child(fragment_10);component(node_14,()=>Root$5,($$anchor7,Tooltip_Root_1)=>{Tooltip_Root_1($$anchor7,{get delayDuration(){return TOOLTIP_DELAY_DURATION},children:($$anchor8,$$slotProps3)=>{ fragment_9)},$$slots:{default:!0}})})}append($$anchor11,fragment_8)},$$slots:{default:!0}})});var node_12=sibling(node_9,2);component(node_12,()=>Tooltip_content,($$anchor10,Tooltip_Content)=>{Tooltip_Content($$anchor10,{side:"right",children:($$anchor11,$$slotProps4)=>{var p2=root_11$e(),text_2=child(p2,!0);reset(p2),template_effect(()=>set_text(text_2,get$3(item).disabledTooltip)),append($$anchor11,p2)},$$slots:{default:!0}})}),append($$anchor9,fragment_7)},$$slots:{default:!0}})}),append($$anchor7,
var fragment_11=root_13$d(),node_15=first_child(fragment_11);component(node_15,()=>Tooltip_trigger,($$anchor9,Tooltip_Trigger_1)=>{Tooltip_Trigger_1($$anchor9,{class:"w-full",children:($$anchor10,$$slotProps4)=>{var fragment_12=comment$2(),node_16=first_child(fragment_12);component(node_16,()=>Dropdown_menu_item,($$anchor11,DropdownMenu_Item_2)=>{DropdownMenu_Item_2($$anchor11,{class:"flex cursor-pointer items-center gap-2",get onclick(){return attachmentMenu.callbacks.onFileUpload},children:($$anchor12,$$slotProps5)=>{ fragment_6)};if_block(node_5,$$render=>{get$3(enabled)?$$render(consequent):get$3(item).disabledTooltip&&$$render(consequent_1,1)})}append($$anchor6,fragment_3)});var node_13=sibling(node_4,2);{var consequent_3=$$anchor6=>{var fragment_10=comment$2(),node_14=first_child(fragment_10);component(node_14,()=>Root$5,($$anchor7,Tooltip_Root_1)=>{Tooltip_Root_1($$anchor7,{get delayDuration(){return TOOLTIP_DELAY_DURATION},children:($$anchor8,$$slotProps3)=>{var fragment_11=root_13$d(),node_15=first_child(
const pdfItem=user_derived(()=>ATTACHMENT_FILE_ITEMS.find(i=>i.id===AttachmentMenuItemId.PDF));var fragment_13=comment$2(),node_17=first_child(fragment_13);{var consequent_2=$$anchor13=>{var fragment_14=root_16$6(),node_18=first_child(fragment_14);component(node_18,()=>get$3(pdfItem).icon,($$anchor14,pdfItem_icon)=>{pdfItem_icon($$anchor14,{class:"h-4 w-4"})});var span_2=sibling(node_18,2),text_3=child(span_2,!0);reset(span_2),template_effect(()=>set_text(text_3,get$3(pdfItem).label)),append($$anchor13, fragment_11);component(node_15,()=>Tooltip_trigger,($$anchor9,Tooltip_Trigger_1)=>{Tooltip_Trigger_1($$anchor9,{class:"w-full",children:($$anchor10,$$slotProps4)=>{var fragment_12=comment$2(),node_16=first_child(fragment_12);component(node_16,()=>Dropdown_menu_item,($$anchor11,DropdownMenu_Item_2)=>{DropdownMenu_Item_2($$anchor11,{class:"flex cursor-pointer items-center gap-2",get onclick(){return attachmentMenu.callbacks.onFileUpload},children:($$anchor12,$$slotProps5)=>{const pdfItem=user_derived(
fragment_14)};if_block(node_17,$$render=>{get$3(pdfItem)&&$$render(consequent_2)})}append($$anchor12,fragment_13)},$$slots:{default:!0}})}),append($$anchor10,fragment_12)},$$slots:{default:!0}})});var node_19=sibling(node_15,2);component(node_19,()=>Tooltip_content,($$anchor9,Tooltip_Content_1)=>{Tooltip_Content_1($$anchor9,{side:"right",children:($$anchor10,$$slotProps4)=>{var p_1=root_17$8();append($$anchor10,p_1)},$$slots:{default:!0}})}),append($$anchor8,fragment_11)},$$slots:{default:!0}})}), ()=>ATTACHMENT_FILE_ITEMS.find(i=>i.id===AttachmentMenuItemId.PDF));var fragment_13=comment$2(),node_17=first_child(fragment_13);{var consequent_2=$$anchor13=>{var fragment_14=root_16$6(),node_18=first_child(fragment_14);component(node_18,()=>get$3(pdfItem).icon,($$anchor14,pdfItem_icon)=>{pdfItem_icon($$anchor14,{class:"h-4 w-4"})});var span_2=sibling(node_18,2),text_3=child(span_2,!0);reset(span_2),template_effect(()=>set_text(text_3,get$3(pdfItem).label)),append($$anchor13,fragment_14)};if_block(
append($$anchor6,fragment_10)},d2=user_derived(()=>!attachmentMenu.isItemEnabled("hasVisionModality"));if_block(node_13,$$render=>{get$3(d2)&&$$render(consequent_3)})}var node_20=sibling(node_13,2);component(node_20,()=>Dropdown_menu_separator,($$anchor6,DropdownMenu_Separator)=>{DropdownMenu_Separator($$anchor6,{})});var node_21=sibling(node_20,2);each(node_21,17,()=>ATTACHMENT_EXTRA_ITEMS,item=>item.id,($$anchor6,item)=>{var fragment_15=comment$2(),node_22=first_child(fragment_15);{var consequent_4=$$anchor7=>{ node_17,$$render=>{get$3(pdfItem)&&$$render(consequent_2)})}append($$anchor12,fragment_13)},$$slots:{default:!0}})}),append($$anchor10,fragment_12)},$$slots:{default:!0}})});var node_19=sibling(node_15,2);component(node_19,()=>Tooltip_content,($$anchor9,Tooltip_Content_1)=>{Tooltip_Content_1($$anchor9,{side:"right",children:($$anchor10,$$slotProps4)=>{var p_1=root_17$8();append($$anchor10,p_1)},$$slots:{default:!0}})}),append($$anchor8,fragment_11)},$$slots:{default:!0}})}),append($$anchor6,fragment_10)},
var fragment_16=comment$2(),node_23=first_child(fragment_16);component(node_23,()=>Root$5,($$anchor8,Tooltip_Root_2)=>{Tooltip_Root_2($$anchor8,{get delayDuration(){return TOOLTIP_DELAY_DURATION},children:($$anchor9,$$slotProps3)=>{var fragment_17=root_20$5(),node_24=first_child(fragment_17);component(node_24,()=>Tooltip_trigger,($$anchor10,Tooltip_Trigger_2)=>{Tooltip_Trigger_2($$anchor10,{class:"w-full",children:($$anchor11,$$slotProps4)=>{var fragment_18=comment$2(),node_25=first_child(fragment_18); d2=user_derived(()=>!attachmentMenu.isItemEnabled("hasVisionModality"));if_block(node_13,$$render=>{get$3(d2)&&$$render(consequent_3)})}var node_20=sibling(node_13,2);component(node_20,()=>Dropdown_menu_separator,($$anchor6,DropdownMenu_Separator)=>{DropdownMenu_Separator($$anchor6,{})});var node_21=sibling(node_20,2);each(node_21,17,()=>ATTACHMENT_EXTRA_ITEMS,item=>item.id,($$anchor6,item)=>{var fragment_15=comment$2(),node_22=first_child(fragment_15);{var consequent_4=$$anchor7=>{var fragment_16=comment$2(),
component(node_25,()=>Dropdown_menu_item,($$anchor12,DropdownMenu_Item_3)=>{DropdownMenu_Item_3($$anchor12,{class:"flex cursor-pointer items-center gap-2",onclick:()=>attachmentMenu.callbacks[get$3(item).action](),children:($$anchor13,$$slotProps5)=>{var fragment_19=root_22$2(),node_26=first_child(fragment_19);component(node_26,()=>get$3(item).icon,($$anchor14,item_icon_2)=>{item_icon_2($$anchor14,{class:"h-4 w-4"})});var span_3=sibling(node_26,2),text_4=child(span_3,!0);reset(span_3),template_effect( node_23=first_child(fragment_16);component(node_23,()=>Root$5,($$anchor8,Tooltip_Root_2)=>{Tooltip_Root_2($$anchor8,{get delayDuration(){return TOOLTIP_DELAY_DURATION},children:($$anchor9,$$slotProps3)=>{var fragment_17=root_20$5(),node_24=first_child(fragment_17);component(node_24,()=>Tooltip_trigger,($$anchor10,Tooltip_Trigger_2)=>{Tooltip_Trigger_2($$anchor10,{class:"w-full",children:($$anchor11,$$slotProps4)=>{var fragment_18=comment$2(),node_25=first_child(fragment_18);component(node_25,()=>Dropdown_menu_item,
()=>set_text(text_4,get$3(item).label)),append($$anchor13,fragment_19)},$$slots:{default:!0}})}),append($$anchor11,fragment_18)},$$slots:{default:!0}})});var node_27=sibling(node_24,2);component(node_27,()=>Tooltip_content,($$anchor10,Tooltip_Content_2)=>{Tooltip_Content_2($$anchor10,{side:"right",children:($$anchor11,$$slotProps4)=>{var p_2=root_23$5(),text_5=child(p_2,!0);reset(p_2),template_effect($0=>set_text(text_5,$0),[()=>attachmentMenu.getSystemMessageTooltip()]),append($$anchor11,p_2)}, ($$anchor12,DropdownMenu_Item_3)=>{DropdownMenu_Item_3($$anchor12,{class:"flex cursor-pointer items-center gap-2",onclick:()=>attachmentMenu.callbacks[get$3(item).action](),children:($$anchor13,$$slotProps5)=>{var fragment_19=root_22$2(),node_26=first_child(fragment_19);component(node_26,()=>get$3(item).icon,($$anchor14,item_icon_2)=>{item_icon_2($$anchor14,{class:"h-4 w-4"})});var span_3=sibling(node_26,2),text_4=child(span_3,!0);reset(span_3),template_effect(()=>set_text(text_4,get$3(item).label)),
$$slots:{default:!0}})}),append($$anchor9,fragment_17)},$$slots:{default:!0}})}),append($$anchor7,fragment_16)};if_block(node_22,$$render=>{get$3(item).id===AttachmentMenuItemId.SYSTEM_MESSAGE&&$$render(consequent_4)})}append($$anchor6,fragment_15)});var node_28=sibling(node_21,2);ChatFormActionAddToolsSubmenu(node_28,{});var node_29=sibling(node_28,2);ChatFormActionAddMcpServersSubmenu(node_29,{onMcpSettingsClick:handleMcpSettingsClick});var node_30=sibling(node_29,2);each(node_30,17,()=>ATTACHMENT_MCP_ITEMS, append($$anchor13,fragment_19)},$$slots:{default:!0}})}),append($$anchor11,fragment_18)},$$slots:{default:!0}})});var node_27=sibling(node_24,2);component(node_27,()=>Tooltip_content,($$anchor10,Tooltip_Content_2)=>{Tooltip_Content_2($$anchor10,{side:"right",children:($$anchor11,$$slotProps4)=>{var p_2=root_23$5(),text_5=child(p_2,!0);reset(p_2),template_effect($0=>set_text(text_5,$0),[()=>attachmentMenu.getSystemMessageTooltip()]),append($$anchor11,p_2)},$$slots:{default:!0}})}),append($$anchor9,
item=>item.id,($$anchor6,item)=>{var fragment_20=comment$2(),node_31=first_child(fragment_20);{var consequent_5=$$anchor7=>{var fragment_21=comment$2(),node_32=first_child(fragment_21);component(node_32,()=>Dropdown_menu_item,($$anchor8,DropdownMenu_Item_4)=>{DropdownMenu_Item_4($$anchor8,{class:"flex cursor-pointer items-center gap-2",onclick:()=>attachmentMenu.callbacks[get$3(item).action](),children:($$anchor9,$$slotProps3)=>{var fragment_22=root_26$2(),node_33=first_child(fragment_22);component( fragment_17)},$$slots:{default:!0}})}),append($$anchor7,fragment_16)};if_block(node_22,$$render=>{get$3(item).id===AttachmentMenuItemId.SYSTEM_MESSAGE&&$$render(consequent_4)})}append($$anchor6,fragment_15)});var node_28=sibling(node_21,2);ChatFormActionAddToolsSubmenu(node_28,{});var node_29=sibling(node_28,2);ChatFormActionAddMcpServersSubmenu(node_29,{onMcpSettingsClick:handleMcpSettingsClick});var node_30=sibling(node_29,2);each(node_30,17,()=>ATTACHMENT_MCP_ITEMS,item=>item.id,($$anchor6,item)=>{
node_33,()=>get$3(item).icon,($$anchor10,item_icon_3)=>{item_icon_3($$anchor10,{class:"h-4 w-4"})});var span_4=sibling(node_33,2),text_6=child(span_4,!0);reset(span_4),template_effect(()=>set_text(text_6,get$3(item).label)),append($$anchor9,fragment_22)},$$slots:{default:!0}})}),append($$anchor7,fragment_21)},d_12=user_derived(()=>attachmentMenu.isItemVisible(get$3(item).visibleWhen));if_block(node_31,$$render=>{get$3(d_12)&&$$render(consequent_5)})}append($$anchor6,fragment_20)}),append($$anchor5, var fragment_20=comment$2(),node_31=first_child(fragment_20);{var consequent_5=$$anchor7=>{var fragment_21=comment$2(),node_32=first_child(fragment_21);component(node_32,()=>Dropdown_menu_item,($$anchor8,DropdownMenu_Item_4)=>{DropdownMenu_Item_4($$anchor8,{class:"flex cursor-pointer items-center gap-2",onclick:()=>attachmentMenu.callbacks[get$3(item).action](),children:($$anchor9,$$slotProps3)=>{var fragment_22=root_26$2(),node_33=first_child(fragment_22);component(node_33,()=>get$3(item).icon,
fragment_2)},$$slots:{default:!0}})}),append($$anchor3,fragment)},$$slots:{default:!0}})}),reset(div),template_effect(()=>set_class(div,1,`flex items-center gap-1 ${className()??""}`)),append($$anchor,div),pop()}function Sheet_overlay($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("fixed inset-0 z-50 bg-black/5\ ($$anchor10,item_icon_3)=>{item_icon_3($$anchor10,{class:"h-4 w-4"})});var span_4=sibling(node_33,2),text_6=child(span_4,!0);reset(span_4),template_effect(()=>set_text(text_6,get$3(item).label)),append($$anchor9,fragment_22)},$$slots:{default:!0}})}),append($$anchor7,fragment_21)},d_12=user_derived(()=>attachmentMenu.isItemVisible(get$3(item).visibleWhen));if_block(node_31,$$render=>{get$3(d_12)&&$$render(consequent_5)})}append($$anchor6,fragment_20)}),append($$anchor5,fragment_2)},$$slots:{default:!0}})}),
0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:fill-mode-forwards data-[state=open]:animate-in data-[state=open]:fade-in-0",$$props.class));component(node2,()=>Dialog_overlay$1,($$anchor2,SheetPrimitive_Overlay)=>{SheetPrimitive_Overlay($$anchor2,spread_props({"data-slot":"sheet-overlay",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}const sheetVariants=tv({base:`bor\ append($$anchor3,fragment)},$$slots:{default:!0}})}),reset(div),template_effect(()=>set_class(div,1,`flex items-center gap-1 ${className()??""}`)),append($$anchor,div),pop()}function Sheet_overlay($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data\
der-border/30 dark:border-border/20 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fill-mode-forwards fixed z-50 flex flex-col gap-4 shadow-sm transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 ${PANEL_CLASSES}`,variants:{side:{top:"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",bottom:"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inse\ -[state=closed]:fade-out-0 data-[state=closed]:fill-mode-forwards data-[state=open]:animate-in data-[state=open]:fade-in-0",$$props.class));component(node2,()=>Dialog_overlay$1,($$anchor2,SheetPrimitive_Overlay)=>{SheetPrimitive_Overlay($$anchor2,spread_props({"data-slot":"sheet-overlay",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}const sheetVariants=tv({base:`border-border/30 dark:border-border/20 da\
t-x-0 bottom-0 h-auto border-t",left:"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",right:"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm"}},defaultVariants:{side:"right"}});var root_3$R=from_html('<!> <span class="sr-only">Close</span>',1),root_2$12=from_html("<!> <!>",1),root_1$N=from_html("<!> <!>",1);function Sheet_content($$anchor,$$props){ ta-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fill-mode-forwards fixed z-50 flex flex-col gap-4 shadow-sm transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 ${PANEL_CLASSES}`,variants:{side:{top:"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",bottom:"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",left:"\
push$1($$props,!0);let ref2=prop($$props,"ref",15,null),side=prop($$props,"side",3,"right"),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","side","portalProps","children"]);var fragment=comment$2(),node2=first_child(fragment);component(node2,()=>Portal$2,($$anchor2,SheetPrimitive_Portal)=>{SheetPrimitive_Portal($$anchor2,spread_props(()=>$$props.portalProps,{children:($$anchor3,$$slotProps)=>{var fragment_1=root_1$N(),node_1=first_child(fragment_1);Sheet_overlay(node_1, data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",right:"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm"}},defaultVariants:{side:"right"}});var root_3$R=from_html('<!> <span class="sr-only">Close</span>',1),root_2$12=from_html("<!> <!>",1),root_1$N=from_html("<!> <!>",1);function Sheet_content($$anchor,$$props){push$1($$props,!0);let ref2=prop(
{});var node_2=sibling(node_1,2);{let $0=user_derived(()=>cn$1(sheetVariants({side:side()}),$$props.class));component(node_2,()=>Dialog_content$1,($$anchor4,SheetPrimitive_Content)=>{SheetPrimitive_Content($$anchor4,spread_props({"data-slot":"sheet-content",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)},children:($$anchor5,$$slotProps2)=>{var fragment_2=root_2$12(),node_3=first_child(fragment_2);snippet(node_3,()=>$$props.children??noop$3); $$props,"ref",15,null),side=prop($$props,"side",3,"right"),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","side","portalProps","children"]);var fragment=comment$2(),node2=first_child(fragment);component(node2,()=>Portal$2,($$anchor2,SheetPrimitive_Portal)=>{SheetPrimitive_Portal($$anchor2,spread_props(()=>$$props.portalProps,{children:($$anchor3,$$slotProps)=>{var fragment_1=root_1$N(),node_1=first_child(fragment_1);Sheet_overlay(node_1,{});var node_2=sibling(node_1,
var node_4=sibling(node_3,2);component(node_4,()=>Dialog_close,($$anchor6,SheetPrimitive_Close)=>{SheetPrimitive_Close($$anchor6,{class:"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none",children:($$anchor7,$$slotProps3)=>{var fragment_3=root_3$R(),node_5=first_child(fragment_3);X(node_5,{class:"size-4"}),next$1( 2);{let $0=user_derived(()=>cn$1(sheetVariants({side:side()}),$$props.class));component(node_2,()=>Dialog_content$1,($$anchor4,SheetPrimitive_Content)=>{SheetPrimitive_Content($$anchor4,spread_props({"data-slot":"sheet-content",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)},children:($$anchor5,$$slotProps2)=>{var fragment_2=root_2$12(),node_3=first_child(fragment_2);snippet(node_3,()=>$$props.children??noop$3);var node_4=sibling(node_3,2);component(
2),append($$anchor7,fragment_3)},$$slots:{default:!0}})}),append($$anchor5,fragment_2)},$$slots:{default:!0}}))})}append($$anchor3,fragment_1)},$$slots:{default:!0}}))}),append($$anchor,fragment),pop()}var root$1s=from_html("<div><!></div>");function Sheet_header($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","children"]);var div=root$1s();attribute_effect(div,$0=>({"data-slot":"sheet-header",class:$0, node_4,()=>Dialog_close,($$anchor6,SheetPrimitive_Close)=>{SheetPrimitive_Close($$anchor6,{class:"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none",children:($$anchor7,$$slotProps3)=>{var fragment_3=root_3$R(),node_5=first_child(fragment_3);X(node_5,{class:"size-4"}),next$1(2),append($$anchor7,fragment_3)},$$slots:{
...restProps}),[()=>cn$1("flex flex-col gap-1.5 p-4",$$props.class)]);var node2=child(div);snippet(node2,()=>$$props.children??noop$3),reset(div),bind_this(div,$$value=>ref2($$value),()=>ref2()),append($$anchor,div),pop()}function Sheet_title($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("font-semibold text-fo\ default:!0}})}),append($$anchor5,fragment_2)},$$slots:{default:!0}}))})}append($$anchor3,fragment_1)},$$slots:{default:!0}}))}),append($$anchor,fragment),pop()}var root$1s=from_html("<div><!></div>");function Sheet_header($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class","children"]);var div=root$1s();attribute_effect(div,$0=>({"data-slot":"sheet-header",class:$0,...restProps}),[()=>cn$1("flex fle\
reground",$$props.class));component(node2,()=>Dialog_title$1,($$anchor2,SheetPrimitive_Title)=>{SheetPrimitive_Title($$anchor2,spread_props({"data-slot":"sheet-title",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}function Sheet_description($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(), x-col gap-1.5 p-4",$$props.class)]);var node2=child(div);snippet(node2,()=>$$props.children??noop$3),reset(div),bind_this(div,$$value=>ref2($$value),()=>ref2()),append($$anchor,div),pop()}function Sheet_title($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);{let $0=user_derived(()=>cn$1("font-semibold text-foreground",$$props.class));component(
node2=first_child(fragment);{let $0=user_derived(()=>cn$1("text-sm text-muted-foreground",$$props.class));component(node2,()=>Dialog_description$1,($$anchor2,SheetPrimitive_Description)=>{SheetPrimitive_Description($$anchor2,spread_props({"data-slot":"sheet-description",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}const Root$3=Dialog;var root_3$Q=from_html("<!> <!>",1),root_7$r=from_html('<button type=\ node2,()=>Dialog_title$1,($$anchor2,SheetPrimitive_Title)=>{SheetPrimitive_Title($$anchor2,spread_props({"data-slot":"sheet-title",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}function Sheet_description($$anchor,$$props){push$1($$props,!0);let ref2=prop($$props,"ref",15,null),restProps=rest_props($$props,["$$slots","$$events","$$legacy","ref","class"]);var fragment=comment$2(),node2=first_child(fragment);
"button"><!> <span> </span></button>'),root_10$e=from_html('<button type="button" disabled=""><!> <span> </span></button>'),root_11$d=from_html("<p> </p>"),root_9$k=from_html("<!> <!>",1),root_15$9=from_html('<button type="button"><!> <span> </span></button>'),root_16$5=from_html("<p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>"),root_14$5=from_html("<!> <!>",1),root_20$4=from_html('<button type="button"><!> <span> </span></button>'),root_21$3=from_html("<p> </p>"), {let $0=user_derived(()=>cn$1("text-sm text-muted-foreground",$$props.class));component(node2,()=>Dialog_description$1,($$anchor2,SheetPrimitive_Description)=>{SheetPrimitive_Description($$anchor2,spread_props({"data-slot":"sheet-description",get class(){return get$3($0)}},()=>restProps,{get ref(){return ref2()},set ref($$value){ref2($$value)}}))})}append($$anchor,fragment),pop()}const Root$3=Dialog;var root_3$Q=from_html("<!> <!>",1),root_7$r=from_html('<button type="button"><!> <span> </span><\
root_19$9=from_html("<!> <!>",1),root_23$4=from_html('<button type="button"><!> <span> </span></button>'),root_2$11=from_html('<!> <div class="flex flex-col gap-1 px-1.5 pb-2"><!> <!> <!> <div class="my-2 border-t"></div> <a class="flex items-center gap-3 px-3 py-2"><!> <span class="text-sm">MCP Servers</span></a> <a class="flex items-center gap-3 px-3 py-2"><!> <span class="text-sm">Tools</span></a> <!></div>',1),root_1$M=from_html("<!> <!>",1),root$1r=from_html("<div><!></div>");function ChatFormActionAddSheet($$anchor,$$props){ /button>'),root_10$e=from_html('<button type="button" disabled=""><!> <span> </span></button>'),root_11$d=from_html("<p> </p>"),root_9$k=from_html("<!> <!>",1),root_15$9=from_html('<button type="button"><!> <span> </span></button>'),root_16$5=from_html("<p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>"),root_14$5=from_html("<!> <!>",1),root_20$4=from_html('<button type="button"><!> <span> </span></button>'),root_21$3=from_html("<p> </p>"),root_19$9=from_html("<!> <!\
>",1),root_23$4=from_html('<button type="button"><!> <span> </span></button>'),root_2$11=from_html('<!> <div class="flex flex-col gap-1 px-1.5 pb-2"><!> <!> <!> <div class="my-2 border-t"></div> <a class="flex items-center gap-3 px-3 py-2"><!> <span class="text-sm">MCP Servers</span></a> <a class="flex items-center gap-3 px-3 py-2"><!> <span class="text-sm">Tools</span></a> <!></div>',1),root_1$M=from_html("<!> <!>",1),root$1r=from_html("<div><!></div>");function ChatFormActionAddSheet($$anchor,$$props){
push$1($$props,!0);let className=prop($$props,"class",3,""),disabled=prop($$props,"disabled",3,!1),hasAudioModality=prop($$props,"hasAudioModality",3,!1),hasVisionModality=prop($$props,"hasVisionModality",3,!1),hasMcpPromptsSupport=prop($$props,"hasMcpPromptsSupport",3,!1),hasMcpResourcesSupport=prop($$props,"hasMcpResourcesSupport",3,!1),sheetOpen=state$1(!1);const attachmentMenu=useAttachmentMenu(()=>({hasVisionModality:hasVisionModality(),hasAudioModality:hasAudioModality(),hasMcpPromptsSupport:hasMcpPromptsSupport(), push$1($$props,!0);let className=prop($$props,"class",3,""),disabled=prop($$props,"disabled",3,!1),hasAudioModality=prop($$props,"hasAudioModality",3,!1),hasVisionModality=prop($$props,"hasVisionModality",3,!1),hasMcpPromptsSupport=prop($$props,"hasMcpPromptsSupport",3,!1),hasMcpResourcesSupport=prop($$props,"hasMcpResourcesSupport",3,!1),sheetOpen=state$1(!1);const attachmentMenu=useAttachmentMenu(()=>({hasVisionModality:hasVisionModality(),hasAudioModality:hasAudioModality(),hasMcpPromptsSupport:hasMcpPromptsSupport(),
hasMcpResourcesSupport:hasMcpResourcesSupport()}),()=>({onFileUpload:$$props.onFileUpload,onSystemPromptClick:$$props.onSystemPromptClick,onMcpPromptClick:$$props.onMcpPromptClick,onMcpResourcesClick:$$props.onMcpResourcesClick}),()=>{set$1(sheetOpen,!1)}),sheetItemClass="flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-left text-sm transition-colors hover:bg-accent active:bg-accent disabled:cursor-not-allowed disabled:opacity-50";var div=root$1r(),node2=child(div);component(node2,()=>Root$3, hasMcpResourcesSupport:hasMcpResourcesSupport()}),()=>({onFileUpload:$$props.onFileUpload,onSystemPromptClick:$$props.onSystemPromptClick,onMcpPromptClick:$$props.onMcpPromptClick,onMcpResourcesClick:$$props.onMcpResourcesClick}),()=>{set$1(sheetOpen,!1)}),sheetItemClass="flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-left text-sm transition-colors hover:bg-accent active:bg-accent disabled:cursor-not-allowed disabled:opacity-50";var div=root$1r(),node2=child(div);component(node2,()=>Root$3,
($$anchor2,Sheet_Root)=>{Sheet_Root($$anchor2,{get open(){return get$3(sheetOpen)},set open($$value){set$1(sheetOpen,$$value,!0)},children:($$anchor3,$$slotProps)=>{var fragment=root_1$M(),node_1=first_child(fragment);snippet(node_1,()=>$$props.trigger,()=>({disabled:disabled(),onclick:()=>set$1(sheetOpen,!0)}));var node_2=sibling(node_1,2);component(node_2,()=>Sheet_content,($$anchor4,Sheet_Content)=>{Sheet_Content($$anchor4,{side:"bottom",class:"max-h-[85vh] gap-0 overflow-y-auto",children:($$anchor5,$$slotProps2)=>{ ($$anchor2,Sheet_Root)=>{Sheet_Root($$anchor2,{get open(){return get$3(sheetOpen)},set open($$value){set$1(sheetOpen,$$value,!0)},children:($$anchor3,$$slotProps)=>{var fragment=root_1$M(),node_1=first_child(fragment);snippet(node_1,()=>$$props.trigger,()=>({disabled:disabled(),onclick:()=>set$1(sheetOpen,!0)}));var node_2=sibling(node_1,2);component(node_2,()=>Sheet_content,($$anchor4,Sheet_Content)=>{Sheet_Content($$anchor4,{side:"bottom",class:"max-h-[85vh] gap-0 overflow-y-auto",children:($$anchor5,$$slotProps2)=>{
@@ -6938,8 +6939,8 @@ cache2,percent=Math.round(actualProcessed/actualTotal*100),eta=getETASecs(actual
0&&time_ms>0){const tokensPerSecond=actualProcessed/(time_ms/1e3);return{tokensProcessed:actualProcessed,totalTokens:actualTotal,timeMs:time_ms,tokensPerSecond}}}return get$3(lastKnownProcessingStats)}function getLiveGenerationStats(){if(!get$3(processingState))return null;const{tokensDecoded,tokensPerSecond}=get$3(processingState);if(tokensDecoded<=0)return null;const timeMs=tokensPerSecond&&tokensPerSecond>0?tokensDecoded/tokensPerSecond*1e3:0;return{tokensGenerated:tokensDecoded,timeMs,tokensPerSecond:tokensPerSecond|| 0&&time_ms>0){const tokensPerSecond=actualProcessed/(time_ms/1e3);return{tokensProcessed:actualProcessed,totalTokens:actualTotal,timeMs:time_ms,tokensPerSecond}}}return get$3(lastKnownProcessingStats)}function getLiveGenerationStats(){if(!get$3(processingState))return null;const{tokensDecoded,tokensPerSecond}=get$3(processingState);if(tokensDecoded<=0)return null;const timeMs=tokensPerSecond&&tokensPerSecond>0?tokensDecoded/tokensPerSecond*1e3:0;return{tokensGenerated:tokensDecoded,timeMs,tokensPerSecond:tokensPerSecond||
0}}return{get processingState(){return get$3(processingState)},getProcessingDetails,getTechnicalDetails,getProcessingMessage,getPromptProgressText,getLiveProcessingStats,getLiveGenerationStats,shouldShowDetails,startMonitoring,stopMonitoring}}var root_1$y=from_html('<div class="mt-6 w-full max-w-[48rem]"><div class="processing-container svelte-3902tz"><span class="processing-text svelte-3902tz"> </span></div></div>'),root_4$s=from_html('<pre class="raw-output svelte-3902tz"> </pre>'),root_6$l=from_html( 0}}return{get processingState(){return get$3(processingState)},getProcessingDetails,getTechnicalDetails,getProcessingMessage,getPromptProgressText,getLiveProcessingStats,getLiveGenerationStats,shouldShowDetails,startMonitoring,stopMonitoring}}var root_1$y=from_html('<div class="mt-6 w-full max-w-[48rem]"><div class="processing-container svelte-3902tz"><span class="processing-text svelte-3902tz"> </span></div></div>'),root_4$s=from_html('<pre class="raw-output svelte-3902tz"> </pre>'),root_6$l=from_html(
'<div class="text-sm whitespace-pre-wrap"> </div>'),root_7$j=from_html('<div class="mt-4 w-full max-w-[48rem]"><div class="processing-container svelte-3902tz"><span class="processing-text svelte-3902tz"> </span></div></div>'),root_8$l=from_html('<div class="inline-flex flex-wrap items-start gap-2 text-xs text-muted-foreground"><!> <!></div>'),root$15=from_html('<div role="group" aria-label="Assistant message with actions"><!> <!> <!> <div class="info my-6 grid gap-4 tabular-nums"><!></div> <!></\ '<div class="text-sm whitespace-pre-wrap"> </div>'),root_7$j=from_html('<div class="mt-4 w-full max-w-[48rem]"><div class="processing-container svelte-3902tz"><span class="processing-text svelte-3902tz"> </span></div></div>'),root_8$l=from_html('<div class="inline-flex flex-wrap items-start gap-2 text-xs text-muted-foreground"><!> <!></div>'),root$15=from_html('<div role="group" aria-label="Assistant message with actions"><!> <!> <!> <div class="info my-6 grid gap-4 tabular-nums"><!></div> <!></\
div>');function ChatMessageAssistant($$anchor,$$props){push$1($$props,!0);let className=prop($$props,"class",3,""),isLastAssistantMessage=prop($$props,"isLastAssistantMessage",3,!1),toolMessages=prop($$props,"toolMessages",19,()=>[]),siblingInfo=prop($$props,"siblingInfo",3,null);const editCtx=getMessageEditContext(),isAgentic=user_derived(()=>hasAgenticContent($$props.message,toolMessages())),hasReasoning=user_derived(()=>!!$$props.message.reasoningContent),processingState=useProcessingState(); div>');function ChatMessageAssistant($$anchor,$$props){push$1($$props,!0);let className=prop($$props,"class",3,""),isLastAssistantMessage=prop($$props,"isLastAssistantMessage",3,!1),toolMessages=prop($$props,"toolMessages",19,()=>[]),siblingInfo=prop($$props,"siblingInfo",3,null);const editCtx=getMessageEditContext(),isAgentic=user_derived(()=>hasAgenticContent($$props.message,toolMessages())),processingState=useProcessingState();let currentConfig=user_derived(config$1),isRouter=user_derived(isRouterMode),
let currentConfig=user_derived(config$1),isRouter=user_derived(isRouterMode),showRawOutput=state$1(!1),rawOutputContent=user_derived(()=>{const sections=deriveAgenticSections($$props.message,toolMessages(),[],!1),parts=[];for(const section of sections)switch(section.type){case AgenticSectionType.REASONING:case AgenticSectionType.REASONING_PENDING:parts.push(`${REASONING_TAGS.START} showRawOutput=state$1(!1),rawOutputContent=user_derived(()=>{const sections=deriveAgenticSections($$props.message,toolMessages(),[],!1),parts=[];for(const section of sections)switch(section.type){case AgenticSectionType.REASONING:case AgenticSectionType.REASONING_PENDING:parts.push(`${REASONING_TAGS.START}
${section.content} ${section.content}
${REASONING_TAGS.END}`);break;case AgenticSectionType.TEXT:parts.push(section.content);break;case AgenticSectionType.TOOL_CALL:case AgenticSectionType.TOOL_CALL_PENDING:case AgenticSectionType.TOOL_CALL_STREAMING:{const callObj={name:section.toolName};if(section.toolArgs)try{callObj.arguments=JSON.parse(section.toolArgs)}catch{callObj.arguments=section.toolArgs}parts.push(JSON.stringify(callObj,null,2)),section.toolResult&&parts.push(`[Tool Result] ${REASONING_TAGS.END}`);break;case AgenticSectionType.TEXT:parts.push(section.content);break;case AgenticSectionType.TOOL_CALL:case AgenticSectionType.TOOL_CALL_PENDING:case AgenticSectionType.TOOL_CALL_STREAMING:{const callObj={name:section.toolName};if(section.toolArgs)try{callObj.arguments=JSON.parse(section.toolArgs)}catch{callObj.arguments=section.toolArgs}parts.push(JSON.stringify(callObj,null,2)),section.toolResult&&parts.push(`[Tool Result]
${section.toolResult}`);break}}return parts.join(` ${section.toolResult}`);break}}return parts.join(`
@@ -6959,24 +6960,24 @@ isRouter)?$$render(consequent_5):$$render(alternate_2,-1)})}var node_6=sibling(n
promptProgress=user_derived(()=>processingState.processingState?.promptProgress),isStillProcessingPrompt=user_derived(()=>get$3(promptProgress)&&get$3(promptProgress).processed<get$3(promptProgress).total);var fragment_6=comment$2(),node_7=first_child(fragment_6);{var consequent_7=$$anchor4=>{{let $0=user_derived(()=>!!get$3(isStillProcessingPrompt)),$1=user_derived(()=>get$3(liveStats)?.tokensProcessed),$2=user_derived(()=>get$3(liveStats)?.timeMs),$3=user_derived(()=>get$3(genStats)?.tokensGenerated), promptProgress=user_derived(()=>processingState.processingState?.promptProgress),isStillProcessingPrompt=user_derived(()=>get$3(promptProgress)&&get$3(promptProgress).processed<get$3(promptProgress).total);var fragment_6=comment$2(),node_7=first_child(fragment_6);{var consequent_7=$$anchor4=>{{let $0=user_derived(()=>!!get$3(isStillProcessingPrompt)),$1=user_derived(()=>get$3(liveStats)?.tokensProcessed),$2=user_derived(()=>get$3(liveStats)?.timeMs),$3=user_derived(()=>get$3(genStats)?.tokensGenerated),
$4=user_derived(()=>get$3(genStats)?.timeMs);ChatMessageStatistics($$anchor4,{isLive:!0,get isProcessingPrompt(){return get$3($0)},get promptTokens(){return get$3($1)},get promptMs(){return get$3($2)},get predictedTokens(){return get$3($3)},get predictedMs(){return get$3($4)}})}};if_block(node_7,$$render=>{(get$3(liveStats)||get$3(genStats))&&$$render(consequent_7)})}append($$anchor3,fragment_6)},d2=user_derived(()=>isLoading()&&get$3(currentConfig).showMessageStats);if_block(node_6,$$render=>{get$3( $4=user_derived(()=>get$3(genStats)?.timeMs);ChatMessageStatistics($$anchor4,{isLive:!0,get isProcessingPrompt(){return get$3($0)},get promptTokens(){return get$3($1)},get promptMs(){return get$3($2)},get predictedTokens(){return get$3($3)},get predictedMs(){return get$3($4)}})}};if_block(node_7,$$render=>{(get$3(liveStats)||get$3(genStats))&&$$render(consequent_7)})}append($$anchor3,fragment_6)},d2=user_derived(()=>isLoading()&&get$3(currentConfig).showMessageStats);if_block(node_6,$$render=>{get$3(
currentConfig).showMessageStats&&$$props.message.timings&&$$props.message.timings.predicted_n&&$$props.message.timings.predicted_ms?$$render(consequent_6):get$3(d2)&&$$render(consequent_8,1)})}reset(div_7),bind_this(div_7,$$value=>set$1(statsContainerEl,$$value),()=>get$3(statsContainerEl)),append($$anchor2,div_7)};if_block(node_4,$$render=>{get$3(displayedModel)&&$$render(consequent_9)})}reset(div_6);var node_8=sibling(div_6,2);{var consequent_10=$$anchor2=>{{let $0=user_derived(()=>get$3(currentConfig). currentConfig).showMessageStats&&$$props.message.timings&&$$props.message.timings.predicted_n&&$$props.message.timings.predicted_ms?$$render(consequent_6):get$3(d2)&&$$render(consequent_8,1)})}reset(div_7),bind_this(div_7,$$value=>set$1(statsContainerEl,$$value),()=>get$3(statsContainerEl)),append($$anchor2,div_7)};if_block(node_4,$$render=>{get$3(displayedModel)&&$$render(consequent_9)})}reset(div_6);var node_8=sibling(div_6,2);{var consequent_10=$$anchor2=>{{let $0=user_derived(()=>get$3(currentConfig).
enableContinueGeneration&&!get$3(hasReasoning)?$$props.onContinue:void 0);ChatMessageActionIcons($$anchor2,{get role(){return MessageRole.ASSISTANT},justify:"start",actionsPosition:"left",get siblingInfo(){return siblingInfo()},get showDeleteDialog(){return $$props.showDeleteDialog},get deletionInfo(){return $$props.deletionInfo},get onCopy(){return $$props.onCopy},get onEdit(){return $$props.onEdit},get onRegenerate(){return $$props.onRegenerate},get onContinue(){return get$3($0)},get onForkConversation(){ enableContinueGeneration?$$props.onContinue:void 0);ChatMessageActionIcons($$anchor2,{get role(){return MessageRole.ASSISTANT},justify:"start",actionsPosition:"left",get siblingInfo(){return siblingInfo()},get showDeleteDialog(){return $$props.showDeleteDialog},get deletionInfo(){return $$props.deletionInfo},get onCopy(){return $$props.onCopy},get onEdit(){return $$props.onEdit},get onRegenerate(){return $$props.onRegenerate},get onContinue(){return get$3($0)},get onForkConversation(){return $$props.
return $$props.onForkConversation},get onDelete(){return $$props.onDelete},get onConfirmDelete(){return $$props.onConfirmDelete},get onNavigateToSibling(){return $$props.onNavigateToSibling},get onShowDeleteDialogChange(){return $$props.onShowDeleteDialogChange},get showRawOutputSwitch(){return get$3(currentConfig).showRawOutputSwitch},get rawOutputEnabled(){return get$3(showRawOutput)},onRawOutputToggle:enabled=>set$1(showRawOutput,enabled,!0)})}};if_block(node_8,$$render=>{$$props.message.timestamp&& onForkConversation},get onDelete(){return $$props.onDelete},get onConfirmDelete(){return $$props.onConfirmDelete},get onNavigateToSibling(){return $$props.onNavigateToSibling},get onShowDeleteDialogChange(){return $$props.onShowDeleteDialogChange},get showRawOutputSwitch(){return get$3(currentConfig).showRawOutputSwitch},get rawOutputEnabled(){return get$3(showRawOutput)},onRawOutputToggle:enabled=>set$1(showRawOutput,enabled,!0)})}};if_block(node_8,$$render=>{$$props.message.timestamp&&!editCtx.
!editCtx.isEditing&&$$render(consequent_10)})}reset(div),template_effect(()=>set_class(div,1,`text-md group w-full leading-7.5 ${className()??""}`,"svelte-3902tz")),append($$anchor,div),pop()}var root_1$x=from_html('<div class="flex items-center gap-2"><!> <label for="save-only-switch" class="cursor-pointer text-xs text-muted-foreground">Update without re-sending</label></div>'),root_2$O=from_html('<div class="flex items-center gap-2"><!> <label for="branch-after-edit" class="cursor-pointer text\ isEditing&&$$render(consequent_10)})}reset(div),template_effect(()=>set_class(div,1,`text-md group w-full leading-7.5 ${className()??""}`,"svelte-3902tz")),append($$anchor,div),pop()}var root_1$x=from_html('<div class="flex items-center gap-2"><!> <label for="save-only-switch" class="cursor-pointer text-xs text-muted-foreground">Update without re-sending</label></div>'),root_2$O=from_html('<div class="flex items-center gap-2"><!> <label for="branch-after-edit" class="cursor-pointer text-xs text-\
-xs text-muted-foreground">Branch conversation after edit</label></div>'),root_3$G=from_html("<div></div>"),root_4$r=from_html("<!> Cancel",1),root$14=from_html('<div class="relative w-full max-w-[80%]"><!></div> <div class="mt-2 flex w-full max-w-[80%] items-center justify-between"><!> <!></div> <!>',1);function ChatMessageEditForm($$anchor,$$props){push$1($$props,!0);const editCtx=getMessageEditContext();let saveWithoutRegenerate=state$1(!1),showDiscardDialog=state$1(!1),branchAfterEdit=state$1( muted-foreground">Branch conversation after edit</label></div>'),root_3$G=from_html("<div></div>"),root_4$r=from_html("<!> Cancel",1),root$14=from_html('<div class="relative w-full max-w-[80%]"><!></div> <div class="mt-2 flex w-full max-w-[80%] items-center justify-between"><!> <!></div> <!>',1);function ChatMessageEditForm($$anchor,$$props){push$1($$props,!0);const editCtx=getMessageEditContext();let saveWithoutRegenerate=state$1(!1),showDiscardDialog=state$1(!1),branchAfterEdit=state$1(!1),isUserMessage=user_derived(
!1),isUserMessage=user_derived(()=>editCtx.messageRole===MessageRole.USER),isAssistantMessage=user_derived(()=>editCtx.messageRole===MessageRole.ASSISTANT),hasUnsavedChanges=user_derived(()=>!!(editCtx.editedContent!==editCtx.originalContent||editCtx.editedUploadedFiles.length>0||editCtx.editedExtras.length!==editCtx.originalExtras.length||editCtx.editedExtras.some((extra,i)=>extra!==editCtx.originalExtras[i]))),hasAttachments=user_derived(()=>editCtx.editedExtras&&editCtx.editedExtras.length>0|| ()=>editCtx.messageRole===MessageRole.USER),isAssistantMessage=user_derived(()=>editCtx.messageRole===MessageRole.ASSISTANT),hasUnsavedChanges=user_derived(()=>!!(editCtx.editedContent!==editCtx.originalContent||editCtx.editedUploadedFiles.length>0||editCtx.editedExtras.length!==editCtx.originalExtras.length||editCtx.editedExtras.some((extra,i)=>extra!==editCtx.originalExtras[i]))),hasAttachments=user_derived(()=>editCtx.editedExtras&&editCtx.editedExtras.length>0||editCtx.editedUploadedFiles&&editCtx.
editCtx.editedUploadedFiles&&editCtx.editedUploadedFiles.length>0),canSubmit=user_derived(()=>editCtx.editedContent.trim().length>0||get$3(hasAttachments));function handleGlobalKeydown(event2){event2.key===KeyboardKey.ESCAPE&&(event2.preventDefault(),attemptCancel())}function attemptCancel(){get$3(hasUnsavedChanges)?set$1(showDiscardDialog,!0):editCtx.cancel()}function handleSubmit(){get$3(canSubmit)&&(get$3(isUserMessage)&&get$3(saveWithoutRegenerate)&&editCtx.showSaveOnlyOption?editCtx.saveOnly(): editedUploadedFiles.length>0),canSubmit=user_derived(()=>editCtx.editedContent.trim().length>0||get$3(hasAttachments));function handleGlobalKeydown(event2){event2.key===KeyboardKey.ESCAPE&&(event2.preventDefault(),attemptCancel())}function attemptCancel(){get$3(hasUnsavedChanges)?set$1(showDiscardDialog,!0):editCtx.cancel()}function handleSubmit(){get$3(canSubmit)&&(get$3(isUserMessage)&&get$3(saveWithoutRegenerate)&&editCtx.showSaveOnlyOption?editCtx.saveOnly():(get$3(isAssistantMessage)&&editCtx.
(get$3(isAssistantMessage)&&editCtx.setShouldBranchAfterEdit&&editCtx.setShouldBranchAfterEdit(get$3(branchAfterEdit)),editCtx.save()),set$1(saveWithoutRegenerate,!1),set$1(branchAfterEdit,!1))}function handleAttachmentRemove(index2){const newExtras=[...editCtx.editedExtras];newExtras.splice(index2,1),editCtx.setExtras(newExtras)}function handleUploadedFileRemove(fileId){const newFiles=editCtx.editedUploadedFiles.filter(f=>f.id!==fileId);editCtx.setUploadedFiles(newFiles)}async function handleFilesAdd(files){ setShouldBranchAfterEdit&&editCtx.setShouldBranchAfterEdit(get$3(branchAfterEdit)),editCtx.save()),set$1(saveWithoutRegenerate,!1),set$1(branchAfterEdit,!1))}function handleAttachmentRemove(index2){const newExtras=[...editCtx.editedExtras];newExtras.splice(index2,1),editCtx.setExtras(newExtras)}function handleUploadedFileRemove(fileId){const newFiles=editCtx.editedUploadedFiles.filter(f=>f.id!==fileId);editCtx.setUploadedFiles(newFiles)}async function handleFilesAdd(files){const processed=await processFilesToChatUploaded(
const processed=await processFilesToChatUploaded(files);editCtx.setUploadedFiles([...editCtx.editedUploadedFiles,...processed])}user_effect(()=>(chatStore.setEditModeActive(handleFilesAdd),()=>{chatStore.clearEditMode()}));var fragment=root$14();event("keydown",$window,handleGlobalKeydown);var div=first_child(fragment),node2=child(div);{let $0=user_derived(()=>editCtx.messageRole===MessageRole.USER),$1=user_derived(()=>editCtx.messageRole===MessageRole.USER);ChatForm(node2,{get value(){return editCtx. files);editCtx.setUploadedFiles([...editCtx.editedUploadedFiles,...processed])}user_effect(()=>(chatStore.setEditModeActive(handleFilesAdd),()=>{chatStore.clearEditMode()}));var fragment=root$14();event("keydown",$window,handleGlobalKeydown);var div=first_child(fragment),node2=child(div);{let $0=user_derived(()=>editCtx.messageRole===MessageRole.USER),$1=user_derived(()=>editCtx.messageRole===MessageRole.USER);ChatForm(node2,{get value(){return editCtx.editedContent},get attachments(){return editCtx.
editedContent},get attachments(){return editCtx.editedExtras},placeholder:"Edit your message...",showMcpPromptButton:!0,get showAddButton(){return get$3($0)},get showModelSelector(){return get$3($1)},get onValueChange(){return editCtx.setContent},onAttachmentRemove:handleAttachmentRemove,onUploadedFileRemove:handleUploadedFileRemove,onFilesAdd:handleFilesAdd,onSubmit:handleSubmit,get uploadedFiles(){return editCtx.editedUploadedFiles},set uploadedFiles($$value){editCtx.editedUploadedFiles=$$value}})} editedExtras},placeholder:"Edit your message...",showMcpPromptButton:!0,get showAddButton(){return get$3($0)},get showModelSelector(){return get$3($1)},get onValueChange(){return editCtx.setContent},onAttachmentRemove:handleAttachmentRemove,onUploadedFileRemove:handleUploadedFileRemove,onFilesAdd:handleFilesAdd,onSubmit:handleSubmit,get uploadedFiles(){return editCtx.editedUploadedFiles},set uploadedFiles($$value){editCtx.editedUploadedFiles=$$value}})}reset(div);var div_1=sibling(div,2),node_1=child(
reset(div);var div_1=sibling(div,2),node_1=child(div_1);{var consequent=$$anchor2=>{var div_2=root_1$x(),node_2=child(div_2);Switch(node_2,{id:"save-only-switch",class:"scale-75",get checked(){return get$3(saveWithoutRegenerate)},set checked($$value){set$1(saveWithoutRegenerate,$$value,!0)}}),next$1(2),reset(div_2),append($$anchor2,div_2)},consequent_1=$$anchor2=>{var div_3=root_2$O(),node_3=child(div_3);Switch(node_3,{id:"branch-after-edit",class:"scale-75",get checked(){return get$3(branchAfterEdit)}, div_1);{var consequent=$$anchor2=>{var div_2=root_1$x(),node_2=child(div_2);Switch(node_2,{id:"save-only-switch",class:"scale-75",get checked(){return get$3(saveWithoutRegenerate)},set checked($$value){set$1(saveWithoutRegenerate,$$value,!0)}}),next$1(2),reset(div_2),append($$anchor2,div_2)},consequent_1=$$anchor2=>{var div_3=root_2$O(),node_3=child(div_3);Switch(node_3,{id:"branch-after-edit",class:"scale-75",get checked(){return get$3(branchAfterEdit)},set checked($$value){set$1(branchAfterEdit,
set checked($$value){set$1(branchAfterEdit,$$value,!0)}}),next$1(2),reset(div_3),append($$anchor2,div_3)},alternate=$$anchor2=>{var div_4=root_3$G();append($$anchor2,div_4)};if_block(node_1,$$render=>{get$3(isUserMessage)&&editCtx.showSaveOnlyOption?$$render(consequent):get$3(isAssistantMessage)?$$render(consequent_1,1):$$render(alternate,-1)})}var node_4=sibling(node_1,2);Button(node_4,{class:"h-7 px-3 text-xs",onclick:attemptCancel,size:"sm",variant:"ghost",children:($$anchor2,$$slotProps)=>{var fragment_1=root_4$r(), $$value,!0)}}),next$1(2),reset(div_3),append($$anchor2,div_3)},alternate=$$anchor2=>{var div_4=root_3$G();append($$anchor2,div_4)};if_block(node_1,$$render=>{get$3(isUserMessage)&&editCtx.showSaveOnlyOption?$$render(consequent):get$3(isAssistantMessage)?$$render(consequent_1,1):$$render(alternate,-1)})}var node_4=sibling(node_1,2);Button(node_4,{class:"h-7 px-3 text-xs",onclick:attemptCancel,size:"sm",variant:"ghost",children:($$anchor2,$$slotProps)=>{var fragment_1=root_4$r(),node_5=first_child(
node_5=first_child(fragment_1);X(node_5,{class:"mr-1 h-3 w-3"}),next$1(),append($$anchor2,fragment_1)},$$slots:{default:!0}}),reset(div_1);var node_6=sibling(div_1,2);DialogConfirmation(node_6,{title:"Discard changes?",description:"You have unsaved changes. Are you sure you want to discard them?",confirmText:"Discard",cancelText:"Keep editing",variant:"destructive",get icon(){return Triangle_alert},get onConfirm(){return editCtx.cancel},onCancel:()=>set$1(showDiscardDialog,!1),get open(){return get$3( fragment_1);X(node_5,{class:"mr-1 h-3 w-3"}),next$1(),append($$anchor2,fragment_1)},$$slots:{default:!0}}),reset(div_1);var node_6=sibling(div_1,2);DialogConfirmation(node_6,{title:"Discard changes?",description:"You have unsaved changes. Are you sure you want to discard them?",confirmText:"Discard",cancelText:"Keep editing",variant:"destructive",get icon(){return Triangle_alert},get onConfirm(){return editCtx.cancel},onCancel:()=>set$1(showDiscardDialog,!1),get open(){return get$3(showDiscardDialog)},
showDiscardDialog)},set open($$value){set$1(showDiscardDialog,$$value,!0)}}),append($$anchor,fragment),pop()}var root_3$F=from_html('<div class="max-w-[80%]"><!></div>'),root_2$N=from_html("<!> <!>",1),root$13=from_html('<div aria-label="User message with actions" role="group"><!></div>');function ChatMessageUser($$anchor,$$props){push$1($$props,!0);let className=prop($$props,"class",3,""),siblingInfo=prop($$props,"siblingInfo",3,null);const editCtx=getMessageEditContext();var div=root$13(),node2=child( set open($$value){set$1(showDiscardDialog,$$value,!0)}}),append($$anchor,fragment),pop()}var root_3$F=from_html('<div class="max-w-[80%]"><!></div>'),root_2$N=from_html("<!> <!>",1),root$13=from_html('<div aria-label="User message with actions" role="group"><!></div>');function ChatMessageUser($$anchor,$$props){push$1($$props,!0);let className=prop($$props,"class",3,""),siblingInfo=prop($$props,"siblingInfo",3,null);const editCtx=getMessageEditContext();var div=root$13(),node2=child(div);{var consequent=$$anchor2=>{
div);{var consequent=$$anchor2=>{ChatMessageEditForm($$anchor2,{})},alternate=$$anchor2=>{var fragment_1=root_2$N(),node_1=first_child(fragment_1);ChatMessageUserBubble(node_1,{get content(){return $$props.message.content},get attachments(){return $$props.message.extra},renderMarkdown:!0});var node_2=sibling(node_1,2);{var consequent_1=$$anchor3=>{var div_1=root_3$F(),node_3=child(div_1);ChatMessageActionIcons(node_3,{actionsPosition:"right",get deletionInfo(){return $$props.deletionInfo},justify:"\ ChatMessageEditForm($$anchor2,{})},alternate=$$anchor2=>{var fragment_1=root_2$N(),node_1=first_child(fragment_1);ChatMessageUserBubble(node_1,{get content(){return $$props.message.content},get attachments(){return $$props.message.extra},renderMarkdown:!0});var node_2=sibling(node_1,2);{var consequent_1=$$anchor3=>{var div_1=root_3$F(),node_3=child(div_1);ChatMessageActionIcons(node_3,{actionsPosition:"right",get deletionInfo(){return $$props.deletionInfo},justify:"end",get onConfirmDelete(){return $$props.
end",get onConfirmDelete(){return $$props.onConfirmDelete},get onCopy(){return $$props.onCopy},get onDelete(){return $$props.onDelete},get onEdit(){return $$props.onEdit},get onForkConversation(){return $$props.onForkConversation},get onNavigateToSibling(){return $$props.onNavigateToSibling},get onShowDeleteDialogChange(){return $$props.onShowDeleteDialogChange},get siblingInfo(){return siblingInfo()},get showDeleteDialog(){return $$props.showDeleteDialog},get role(){return MessageRole.USER}}),reset( onConfirmDelete},get onCopy(){return $$props.onCopy},get onDelete(){return $$props.onDelete},get onEdit(){return $$props.onEdit},get onForkConversation(){return $$props.onForkConversation},get onNavigateToSibling(){return $$props.onNavigateToSibling},get onShowDeleteDialogChange(){return $$props.onShowDeleteDialogChange},get siblingInfo(){return siblingInfo()},get showDeleteDialog(){return $$props.showDeleteDialog},get role(){return MessageRole.USER}}),reset(div_1),append($$anchor3,div_1)};if_block(
div_1),append($$anchor3,div_1)};if_block(node_2,$$render=>{$$props.message.timestamp&&$$render(consequent_1)})}append($$anchor2,fragment_1)};if_block(node2,$$render=>{editCtx.isEditing?$$render(consequent):$$render(alternate,-1)})}reset(div),template_effect(()=>set_class(div,1,`group flex flex-col items-end gap-3 md:gap-2 ${className()??""}`)),append($$anchor,div),pop()}var root_1$w=from_html('<div class="mb-2 max-w-[80%]"><!></div>'),root_4$q=from_html("<div><!></div>"),root_5$k=from_html('<spa\ node_2,$$render=>{$$props.message.timestamp&&$$render(consequent_1)})}append($$anchor2,fragment_1)};if_block(node2,$$render=>{editCtx.isEditing?$$render(consequent):$$render(alternate,-1)})}reset(div),template_effect(()=>set_class(div,1,`group flex flex-col items-end gap-3 md:gap-2 ${className()??""}`)),append($$anchor,div),pop()}var root_1$w=from_html('<div class="mb-2 max-w-[80%]"><!></div>'),root_4$q=from_html("<div><!></div>"),root_5$k=from_html('<span class="text-md whitespace-pre-wrap"> </\
n class="text-md whitespace-pre-wrap"> </span>'),root$12=from_html("<!> <!>",1);function ChatMessageUserBubble($$anchor,$$props){push$1($$props,!0);let attachments=prop($$props,"attachments",19,()=>[]),renderMarkdown=prop($$props,"renderMarkdown",3,!1),textColorClass=prop($$props,"textColorClass",3,"text-foreground"),cardBgClass=prop($$props,"cardBgClass",3,"dark:bg-primary/15"),maxHeightStyle=prop($$props,"maxHeightStyle",3,"max-height: var(--max-message-height);"),isMultiline=state$1(!1),messageElement=state$1( span>'),root$12=from_html("<!> <!>",1);function ChatMessageUserBubble($$anchor,$$props){push$1($$props,!0);let attachments=prop($$props,"attachments",19,()=>[]),renderMarkdown=prop($$props,"renderMarkdown",3,!1),textColorClass=prop($$props,"textColorClass",3,"text-foreground"),cardBgClass=prop($$props,"cardBgClass",3,"dark:bg-primary/15"),maxHeightStyle=prop($$props,"maxHeightStyle",3,"max-height: var(--max-message-height);"),isMultiline=state$1(!1),messageElement=state$1(void 0);const currentConfig=config$1();
void 0);const currentConfig=config$1();user_effect(()=>{if(!get$3(messageElement)||!$$props.content.trim())return;if($$props.content.includes(` user_effect(()=>{if(!get$3(messageElement)||!$$props.content.trim())return;if($$props.content.includes(`
`)){set$1(isMultiline,!0);return}const resizeObserver=new ResizeObserver(entries=>{for(const entry of entries){const element2=entry.target;set$1(isMultiline,element2.offsetHeight>24*1.5)}});return resizeObserver.observe(get$3(messageElement)),()=>{resizeObserver.disconnect()}});var fragment=root$12(),node2=first_child(fragment);{var consequent=$$anchor2=>{var div=root_1$w(),node_1=child(div);ChatAttachmentsList(node_1,{get attachments(){return attachments()},readonly:!0,imageHeight:"h-40"}),reset( `)){set$1(isMultiline,!0);return}const resizeObserver=new ResizeObserver(entries=>{for(const entry of entries){const element2=entry.target;set$1(isMultiline,element2.offsetHeight>24*1.5)}});return resizeObserver.observe(get$3(messageElement)),()=>{resizeObserver.disconnect()}});var fragment=root$12(),node2=first_child(fragment);{var consequent=$$anchor2=>{var div=root_1$w(),node_1=child(div);ChatAttachmentsList(node_1,{get attachments(){return attachments()},readonly:!0,imageHeight:"h-40"}),reset(
div),append($$anchor2,div)};if_block(node2,$$render=>{attachments()&&attachments().length>0&&$$render(consequent)})}var node_2=sibling(node2,2);{var consequent_2=$$anchor2=>{{let $0=user_derived(()=>get$3(isMultiline)?"":void 0);Card($$anchor2,{get class(){return`max-w-[80%] overflow-y-auto rounded-[1.125rem] border-none bg-primary/5 px-3.75 py-1.5 ${textColorClass()??""} backdrop-blur-md data-[multiline]:py-2.5 ${cardBgClass()??""}`},get"data-multiline"(){return get$3($0)},get style(){return`${maxHeightStyle()?? div),append($$anchor2,div)};if_block(node2,$$render=>{attachments()&&attachments().length>0&&$$render(consequent)})}var node_2=sibling(node2,2);{var consequent_2=$$anchor2=>{{let $0=user_derived(()=>get$3(isMultiline)?"":void 0);Card($$anchor2,{get class(){return`max-w-[80%] overflow-y-auto rounded-[1.125rem] border-none bg-primary/5 px-3.75 py-1.5 ${textColorClass()??""} backdrop-blur-md data-[multiline]:py-2.5 ${cardBgClass()??""}`},get"data-multiline"(){return get$3($0)},get style(){return`${maxHeightStyle()??
""} overflow-wrap: anywhere; word-break: break-word;`},children:($$anchor3,$$slotProps)=>{var fragment_2=comment$2(),node_3=first_child(fragment_2);{var consequent_1=$$anchor4=>{var div_1=root_4$q(),node_4=child(div_1);MarkdownContent(node_4,{class:"markdown-user-content -my-4",get content(){return $$props.content}}),reset(div_1),bind_this(div_1,$$value=>set$1(messageElement,$$value),()=>get$3(messageElement)),append($$anchor4,div_1)},alternate=$$anchor4=>{var span=root_5$k(),text2=child(span,!0); ""} overflow-wrap: anywhere; word-break: break-word;`},children:($$anchor3,$$slotProps)=>{var fragment_2=comment$2(),node_3=first_child(fragment_2);{var consequent_1=$$anchor4=>{var div_1=root_4$q(),node_4=child(div_1);MarkdownContent(node_4,{class:"markdown-user-content -my-4",get content(){return $$props.content}}),reset(div_1),bind_this(div_1,$$value=>set$1(messageElement,$$value),()=>get$3(messageElement)),append($$anchor4,div_1)},alternate=$$anchor4=>{var span=root_5$k(),text2=child(span,!0);
+42 -5
View File
@@ -1082,11 +1082,12 @@ json oaicompat_chat_params_parse(
throw std::invalid_argument("Cannot have 2 or more assistant messages at the end of the list."); throw std::invalid_argument("Cannot have 2 or more assistant messages at the end of the list.");
} }
/* TODO: test this properly */ // reject reasoning prefill on channel based templates that do not expose explicit thinking tags
inputs.reasoning_format = COMMON_REASONING_FORMAT_NONE; if (!last_message.reasoning_content.empty() && inputs.enable_thinking) {
auto probe_params = common_chat_templates_apply(opt.tmpls.get(), inputs);
if ( inputs.enable_thinking ) { if (probe_params.supports_thinking && probe_params.thinking_end_tag.empty()) {
throw std::invalid_argument("Assistant response prefill is incompatible with enable_thinking."); throw std::invalid_argument("Assistant prefill with reasoning_content is not supported yet for this template.");
}
} }
inputs.add_generation_prompt = true; inputs.add_generation_prompt = true;
@@ -1098,6 +1099,42 @@ json oaicompat_chat_params_parse(
/* Append assistant prefilled message */ /* Append assistant prefilled message */
if (prefill_assistant_message) { if (prefill_assistant_message) {
const bool thinking_active = chat_params.supports_thinking && !chat_params.thinking_end_tag.empty();
const bool has_reasoning = !last_message.reasoning_content.empty();
const bool has_content = !last_message.content.empty() || !last_message.content_parts.empty();
const bool mid_reasoning = has_reasoning && !has_content;
// some templates inject thinking_start in generation_prompt, others let the model emit it
const bool gp_has_think = thinking_active
&& chat_params.generation_prompt.find(chat_params.thinking_start_tag) != std::string::npos;
// open the thinking block when reasoning is present and the template did not inject it
if (has_reasoning) {
if (thinking_active && !gp_has_think) {
chat_params.prompt += chat_params.thinking_start_tag;
}
chat_params.prompt += last_message.reasoning_content;
}
if (thinking_active) {
if (mid_reasoning) {
// model continues inside the thinking block, keep generation_prompt open on think
if (!gp_has_think) {
chat_params.generation_prompt += chat_params.thinking_start_tag;
}
} else {
// close thinking block when reasoning is followed by content, or when the template forced it open
if (has_reasoning || gp_has_think) {
chat_params.prompt += chat_params.thinking_end_tag;
}
// strip thinking_start from generation_prompt so the parser routes model output as content
auto pos = chat_params.generation_prompt.rfind(chat_params.thinking_start_tag);
if (pos != std::string::npos) {
chat_params.generation_prompt = chat_params.generation_prompt.substr(0, pos);
}
}
}
if (!last_message.content_parts.empty()) { if (!last_message.content_parts.empty()) {
for (auto & p : last_message.content_parts) { for (auto & p : last_message.content_parts) {
chat_params.prompt += p.text; chat_params.prompt += p.text;
@@ -74,7 +74,6 @@
const editCtx = getMessageEditContext(); const editCtx = getMessageEditContext();
const isAgentic = $derived(hasAgenticContent(message, toolMessages)); const isAgentic = $derived(hasAgenticContent(message, toolMessages));
const hasReasoning = $derived(!!message.reasoningContent);
const processingState = useProcessingState(); const processingState = useProcessingState();
let currentConfig = $derived(config()); let currentConfig = $derived(config());
@@ -329,7 +328,7 @@
{onCopy} {onCopy}
{onEdit} {onEdit}
{onRegenerate} {onRegenerate}
onContinue={currentConfig.enableContinueGeneration && !hasReasoning ? onContinue : undefined} onContinue={currentConfig.enableContinueGeneration ? onContinue : undefined}
{onForkConversation} {onForkConversation}
{onDelete} {onDelete}
{onConfirmDelete} {onConfirmDelete}
@@ -122,7 +122,7 @@ const SETTINGS_REGISTRY: Record<string, SettingsSectionEntry> = {
{ {
key: SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION, key: SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION,
label: 'Enable "Continue" button', label: 'Enable "Continue" button',
help: 'Enable "Continue" button for assistant messages. Currently works only with non-reasoning models.', help: 'Enable "Continue" button for assistant messages, including reasoning models.',
defaultValue: false, defaultValue: false,
type: SettingsFieldType.CHECKBOX, type: SettingsFieldType.CHECKBOX,
section: SETTINGS_SECTION_SLUGS.GENERAL, section: SETTINGS_SECTION_SLUGS.GENERAL,
@@ -674,7 +674,8 @@ class ChatStore {
}, },
onReasoningChunk: (chunk: string) => { onReasoningChunk: (chunk: string) => {
streamedReasoningContent += chunk; streamedReasoningContent += chunk;
// Update UI to show reasoning is being received // mark streaming state so a stop mid-thinking can persist the partial reasoning
this.setChatStreaming(convId, streamedContent, currentMessageId);
const idx = conversationsStore.findMessageIndex(currentMessageId); const idx = conversationsStore.findMessageIndex(currentMessageId);
conversationsStore.updateMessageAtIndex(idx, { conversationsStore.updateMessageAtIndex(idx, {
reasoningContent: streamedReasoningContent reasoningContent: streamedReasoningContent
@@ -989,38 +990,51 @@ class ChatStore {
const conversationId = convId || conversationsStore.activeConversation?.id; const conversationId = convId || conversationsStore.activeConversation?.id;
if (!conversationId) return; if (!conversationId) return;
const streamingState = this.getChatStreaming(conversationId); const streamingState = this.getChatStreaming(conversationId);
if (!streamingState || !streamingState.response.trim()) return; if (!streamingState) return;
const messages = const messages =
conversationId === conversationsStore.activeConversation?.id conversationId === conversationsStore.activeConversation?.id
? conversationsStore.activeMessages ? conversationsStore.activeMessages
: await conversationsStore.getConversationMessages(conversationId); : await conversationsStore.getConversationMessages(conversationId);
if (!messages.length) return; if (!messages.length) return;
const lastMessage = messages[messages.length - 1]; const lastMessage = messages[messages.length - 1];
if (lastMessage?.role === MessageRole.ASSISTANT) { if (lastMessage?.role !== MessageRole.ASSISTANT) return;
try {
const updateData: { content: string; timings?: ChatMessageTimings } = { const partialContent = streamingState.response;
content: streamingState.response const partialReasoning = lastMessage.reasoningContent || '';
};
const lastKnownState = this.getProcessingState(conversationId); // nothing to persist when both content and reasoning are empty (e.g. stop before any token)
if (lastKnownState) { if (!partialContent.trim() && !partialReasoning.trim()) return;
updateData.timings = {
prompt_n: lastKnownState.promptTokens || 0, try {
prompt_ms: lastKnownState.promptMs, const updateData: {
predicted_n: lastKnownState.tokensDecoded || 0, content: string;
cache_n: lastKnownState.cacheTokens || 0, reasoningContent?: string;
predicted_ms: timings?: ChatMessageTimings;
lastKnownState.tokensPerSecond && lastKnownState.tokensDecoded } = {
? (lastKnownState.tokensDecoded / lastKnownState.tokensPerSecond) * 1000 content: partialContent
: undefined };
}; if (partialReasoning) {
} updateData.reasoningContent = partialReasoning;
await DatabaseService.updateMessage(lastMessage.id, updateData);
lastMessage.content = streamingState.response;
if (updateData.timings) lastMessage.timings = updateData.timings;
} catch (error) {
lastMessage.content = streamingState.response;
console.error('Failed to save partial response:', error);
} }
const lastKnownState = this.getProcessingState(conversationId);
if (lastKnownState) {
updateData.timings = {
prompt_n: lastKnownState.promptTokens || 0,
prompt_ms: lastKnownState.promptMs,
predicted_n: lastKnownState.tokensDecoded || 0,
cache_n: lastKnownState.cacheTokens || 0,
predicted_ms:
lastKnownState.tokensPerSecond && lastKnownState.tokensDecoded
? (lastKnownState.tokensDecoded / lastKnownState.tokensPerSecond) * 1000
: undefined
};
}
await DatabaseService.updateMessage(lastMessage.id, updateData);
lastMessage.content = partialContent;
if (updateData.timings) lastMessage.timings = updateData.timings;
} catch (error) {
lastMessage.content = partialContent;
console.error('Failed to save partial response:', error);
} }
} }
@@ -1265,7 +1279,11 @@ class ChatStore {
const conversationContext = conversationsStore.activeMessages.slice(0, idx); const conversationContext = conversationsStore.activeMessages.slice(0, idx);
const contextWithContinue = [ const contextWithContinue = [
...conversationContext, ...conversationContext,
{ role: MessageRole.ASSISTANT as const, content: originalContent } {
role: MessageRole.ASSISTANT as const,
content: originalContent,
reasoning_content: originalReasoning || undefined
}
]; ];
let appendedContent = ''; let appendedContent = '';
@@ -1291,6 +1309,8 @@ class ChatStore {
onReasoningChunk: (chunk: string) => { onReasoningChunk: (chunk: string) => {
appendedReasoning += chunk; appendedReasoning += chunk;
hasReceivedContent = true; hasReceivedContent = true;
// mark streaming state so a stop mid-thinking can persist the partial reasoning
this.setChatStreaming(msg.convId, originalContent + appendedContent, msg.id);
conversationsStore.updateMessageAtIndex(idx, { conversationsStore.updateMessageAtIndex(idx, {
reasoningContent: originalReasoning + appendedReasoning reasoningContent: originalReasoning + appendedReasoning
}); });