@@ -10,7 +10,13 @@ import { useMode } from "@/contexts/ModeContext";
1010import { ChatToggles } from "./ChatToggles" ;
1111import { useSendMessageOptions } from "@/hooks/useSendMessageOptions" ;
1212import { getModelKey , getInputKey } from "@/constants/storage" ;
13- import { forkWorkspace } from "@/utils/workspaceFork" ;
13+ import {
14+ handleNewCommand ,
15+ handleCompactCommand ,
16+ forkWorkspace ,
17+ prepareCompactionMessage ,
18+ type CommandHandlerContext ,
19+ } from "@/utils/chatCommands" ;
1420import { ToggleGroup } from "./ToggleGroup" ;
1521import { CUSTOM_EVENTS } from "@/constants/events" ;
1622import type { UIMode } from "@/types/mode" ;
@@ -31,10 +37,7 @@ import {
3137} from "@/utils/imageHandling" ;
3238
3339import type { ThinkingLevel } from "@/types/thinking" ;
34- import type { CmuxFrontendMetadata , CompactionRequestData } from "@/types/message" ;
35- import type { SendMessageOptions } from "@/types/ipc" ;
36- import { applyCompactionOverrides } from "@/utils/messages/compactionOptions" ;
37- import { resolveCompactionModel } from "@/utils/messages/compactionModelPreference" ;
40+ import type { CmuxFrontendMetadata } from "@/types/message" ;
3841import { useTelemetry } from "@/hooks/useTelemetry" ;
3942import { setTelemetryEnabled } from "@/telemetry" ;
4043
@@ -159,49 +162,6 @@ export interface ChatInputProps {
159162}
160163
161164// Helper function to convert parsed command to display toast
162- /**
163- * Prepare compaction message from /compact command
164- * Returns the actual message text (summarization request), metadata, and options
165- */
166- function prepareCompactionMessage (
167- command : string ,
168- sendMessageOptions : SendMessageOptions
169- ) : {
170- messageText : string ;
171- metadata : CmuxFrontendMetadata ;
172- options : Partial < SendMessageOptions > ;
173- } {
174- const parsed = parseCommand ( command ) ;
175- if ( parsed ?. type !== "compact" ) {
176- throw new Error ( "Not a compact command" ) ;
177- }
178-
179- const targetWords = parsed . maxOutputTokens ? Math . round ( parsed . maxOutputTokens / 1.3 ) : 2000 ;
180-
181- const messageText = `Summarize this conversation into a compact form for a new Assistant to continue helping the user. Use approximately ${ targetWords } words.` ;
182-
183- // Handle model preference (sticky globally)
184- const effectiveModel = resolveCompactionModel ( parsed . model ) ;
185-
186- // Create compaction metadata (will be stored in user message)
187- const compactData : CompactionRequestData = {
188- model : effectiveModel ,
189- maxOutputTokens : parsed . maxOutputTokens ,
190- continueMessage : parsed . continueMessage ,
191- } ;
192-
193- const metadata : CmuxFrontendMetadata = {
194- type : "compaction-request" ,
195- rawCommand : command ,
196- parsed : compactData ,
197- } ;
198-
199- // Apply compaction overrides using shared transformation function
200- // This same function is used by useResumeManager to ensure consistency
201- const options = applyCompactionOverrides ( sendMessageOptions , compactData ) ;
202-
203- return { messageText, metadata, options } ;
204- }
205165
206166export const ChatInput : React . FC < ChatInputProps > = ( {
207167 workspaceId,
@@ -572,51 +532,19 @@ export const ChatInput: React.FC<ChatInputProps> = ({
572532
573533 // Handle /compact command
574534 if ( parsed . type === "compact" ) {
575- setInput ( "" ) ; // Clear input immediately
576- setIsSending ( true ) ;
577-
578- try {
579- const {
580- messageText : compactionMessage ,
581- metadata,
582- options,
583- } = prepareCompactionMessage ( messageText , sendMessageOptions ) ;
584-
585- const result = await window . api . workspace . sendMessage ( workspaceId , compactionMessage , {
586- ...sendMessageOptions ,
587- ...options ,
588- cmuxMetadata : metadata ,
589- editMessageId : editingMessage ?. id , // Support editing compaction messages
590- } ) ;
535+ const context : CommandHandlerContext = {
536+ workspaceId,
537+ sendMessageOptions,
538+ editMessageId : editingMessage ?. id ,
539+ setInput,
540+ setIsSending,
541+ setToast,
542+ onCancelEdit,
543+ } ;
591544
592- if ( ! result . success ) {
593- console . error ( "Failed to initiate compaction:" , result . error ) ;
594- setToast ( createErrorToast ( result . error ) ) ;
595- setInput ( messageText ) ; // Restore input on error
596- } else {
597- setToast ( {
598- id : Date . now ( ) . toString ( ) ,
599- type : "success" ,
600- message :
601- metadata . type === "compaction-request" && metadata . parsed . continueMessage
602- ? "Compaction started. Will continue automatically after completion."
603- : "Compaction started. AI will summarize the conversation." ,
604- } ) ;
605- // Clear editing state on success
606- if ( editingMessage && onCancelEdit ) {
607- onCancelEdit ( ) ;
608- }
609- }
610- } catch ( error ) {
611- console . error ( "Compaction error:" , error ) ;
612- setToast ( {
613- id : Date . now ( ) . toString ( ) ,
614- type : "error" ,
615- message : error instanceof Error ? error . message : "Failed to start compaction" ,
616- } ) ;
545+ const result = await handleCompactCommand ( parsed , context ) ;
546+ if ( ! result . clearInput ) {
617547 setInput ( messageText ) ; // Restore input on error
618- } finally {
619- setIsSending ( false ) ;
620548 }
621549 return ;
622550 }
@@ -667,6 +595,23 @@ export const ChatInput: React.FC<ChatInputProps> = ({
667595 return ;
668596 }
669597
598+ // Handle /new command
599+ if ( parsed . type === "new" ) {
600+ const context : CommandHandlerContext = {
601+ workspaceId,
602+ sendMessageOptions,
603+ setInput,
604+ setIsSending,
605+ setToast,
606+ } ;
607+
608+ const result = await handleNewCommand ( parsed , context ) ;
609+ if ( ! result . clearInput ) {
610+ setInput ( messageText ) ; // Restore input on error
611+ }
612+ return ;
613+ }
614+
670615 // Handle all other commands - show display toast
671616 const commandToast = createCommandToast ( parsed ) ;
672617 if ( commandToast ) {
@@ -719,11 +664,17 @@ export const ChatInput: React.FC<ChatInputProps> = ({
719664 const {
720665 messageText : regeneratedText ,
721666 metadata,
722- options,
723- } = prepareCompactionMessage ( messageText , sendMessageOptions ) ;
667+ sendOptions,
668+ } = prepareCompactionMessage ( {
669+ workspaceId,
670+ maxOutputTokens : parsed . maxOutputTokens ,
671+ continueMessage : parsed . continueMessage ,
672+ model : parsed . model ,
673+ sendMessageOptions,
674+ } ) ;
724675 actualMessageText = regeneratedText ;
725676 cmuxMetadata = metadata ;
726- compactionOptions = options ;
677+ compactionOptions = sendOptions ;
727678 }
728679 }
729680
0 commit comments