Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions cecli/coders/base_coder.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ def __init__(
uuid="",
):
# initialize from args.map_cache_dir
self.interrupt_event = asyncio.Event()
self.uuid = generate_unique_id()
if uuid:
self.uuid = uuid
Expand Down Expand Up @@ -1735,6 +1736,7 @@ def keyboard_interrupt(self):

self.io.tool_warning("\n\n^C KeyboardInterrupt")

self.interrupt_event.set()
self.last_keyboard_interrupt = time.time()

# Old summarization system removed - using context compaction logic instead
Expand Down Expand Up @@ -3039,6 +3041,7 @@ async def check_for_file_mentions(self, content):
return prompts.added_files.format(fnames=", ".join(added_fnames))

async def send(self, messages, model=None, functions=None, tools=None):
self.interrupt_event.clear()
self.got_reasoning_content = False
self.ended_reasoning_content = False

Expand All @@ -3058,15 +3061,33 @@ async def send(self, messages, model=None, functions=None, tools=None):
self.token_profiler.start()

try:
hash_object, completion = await model.send_completion(
messages,
functions,
self.stream,
self.temperature,
# This could include any tools, but for now it is just MCP tools
tools=tools,
override_kwargs=self.model_kwargs.copy(),
completion_task = asyncio.create_task(
model.send_completion(
messages,
functions,
self.stream,
self.temperature,
# This could include any tools, but for now it is just MCP tools
tools=tools,
override_kwargs=self.model_kwargs.copy(),
)
)
interrupt_task = asyncio.create_task(self.interrupt_event.wait())

done, pending = await asyncio.wait(
{completion_task, interrupt_task},
return_when=asyncio.FIRST_COMPLETED,
)

if interrupt_task in done:
completion_task.cancel()
try:
await completion_task
except asyncio.CancelledError:
pass
raise KeyboardInterrupt

hash_object, completion = completion_task.result()
self.chat_completion_call_hashes.append(hash_object.hexdigest())

if not isinstance(completion, ModelResponse):
Expand Down
5 changes: 5 additions & 0 deletions cecli/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,11 @@ def rule(self):
print()

def interrupt_input(self):
if self.coder:
coder = self.coder()
if coder and hasattr(coder, "interrupt_event"):
coder.interrupt_event.set()

if self.prompt_session and self.prompt_session.app:
# Store any partial input before interrupting
self.placeholder = self.prompt_session.app.current_buffer.text
Expand Down
Loading