99from rich .panel import Panel
1010from prompt_toolkit import prompt as pt_prompt
1111from prompt_toolkit .history import FileHistory
12+ from prompt_toolkit .key_binding import KeyBindings
1213
1314from .agent import Agent
1415from .llm import LLM
@@ -118,9 +119,26 @@ def _repl(agent: Agent, config: Config):
118119 hist_path = os .path .expanduser ("~/.corecoder_history" )
119120 history = FileHistory (hist_path )
120121
122+ # Enter submits, Escape+Enter inserts a newline (for pasting code blocks etc.)
123+ kb = KeyBindings ()
124+
125+ @kb .add ("enter" )
126+ def _submit (event ):
127+ event .current_buffer .validate_and_handle ()
128+
129+ @kb .add ("escape" , "enter" )
130+ def _newline (event ):
131+ event .current_buffer .insert_text ("\n " )
132+
121133 while True :
122134 try :
123- user_input = pt_prompt ("You > " , history = history ).strip ()
135+ user_input = pt_prompt (
136+ "You > " ,
137+ history = history ,
138+ multiline = True ,
139+ key_bindings = kb ,
140+ prompt_continuation = "... " ,
141+ ).strip ()
124142 except (EOFError , KeyboardInterrupt ):
125143 console .print ("\n Bye!" )
126144 break
@@ -141,14 +159,20 @@ def _repl(agent: Agent, config: Config):
141159 if user_input == "/tokens" :
142160 p = agent .llm .total_prompt_tokens
143161 c = agent .llm .total_completion_tokens
144- console .print (f"Tokens used this session: [cyan]{ p } [/cyan] prompt + [cyan]{ c } [/cyan] completion = [bold]{ p + c } [/bold] total" )
162+ line = f"Tokens: [cyan]{ p } [/cyan] prompt + [cyan]{ c } [/cyan] completion = [bold]{ p + c } [/bold] total"
163+ cost = agent .llm .estimated_cost
164+ if cost is not None :
165+ line += f" (~${ cost :.4f} )"
166+ console .print (line )
145167 continue
146- if user_input .startswith ("/model " ):
147- new_model = user_input [7 :].strip ()
168+ if user_input == "/model" or user_input .startswith ("/model " ):
169+ new_model = user_input [7 :].strip () if user_input . startswith ( "/model " ) else ""
148170 if new_model :
149171 agent .llm .model = new_model
150172 config .model = new_model
151173 console .print (f"Switched to [cyan]{ new_model } [/cyan]" )
174+ else :
175+ console .print (f"Current model: [cyan]{ config .model } [/cyan]" )
152176 continue
153177 if user_input == "/compact" :
154178 from .context import estimate_tokens
@@ -165,6 +189,15 @@ def _repl(agent: Agent, config: Config):
165189 console .print (f"[green]Session saved: { sid } [/green]" )
166190 console .print (f"Resume with: corecoder -r { sid } " )
167191 continue
192+ if user_input == "/diff" :
193+ from .tools .edit import _changed_files
194+ if not _changed_files :
195+ console .print ("[dim]No files modified this session.[/dim]" )
196+ else :
197+ console .print (f"[bold]Files modified this session ({ len (_changed_files )} ):[/bold]" )
198+ for f in sorted (_changed_files ):
199+ console .print (f" [cyan]{ f } [/cyan]" )
200+ continue
168201 if user_input == "/sessions" :
169202 sessions = list_sessions ()
170203 if not sessions :
@@ -202,12 +235,18 @@ def _show_help():
202235 "[bold]Commands:[/bold]\n "
203236 " /help Show this help\n "
204237 " /reset Clear conversation history\n "
238+ " /model Show current model\n "
205239 " /model <name> Switch model mid-conversation\n "
206240 " /tokens Show token usage\n "
207241 " /compact Compress conversation context\n "
242+ " /diff Show files modified this session\n "
208243 " /save Save session to disk\n "
209244 " /sessions List saved sessions\n "
210- " quit Exit CoreCoder" ,
245+ " quit Exit CoreCoder\n "
246+ "\n "
247+ "[bold]Input:[/bold]\n "
248+ " Enter Submit message\n "
249+ " Esc+Enter Insert newline (for pasting code)" ,
211250 title = "CoreCoder Help" ,
212251 border_style = "dim" ,
213252 ))
0 commit comments