Skip to content

Commit 6608d07

Browse files
committed
Explain: Factor out helper for stepping backwrds into a function.
This was the majority of the implementation for the `reverse_step_into_current_line` tool but it will also be useful for other cases where we need to wind back into to a specific function whilst capturing return values or exceptions.
1 parent 9352913 commit 6608d07

File tree

1 file changed

+44
-29
lines changed

1 file changed

+44
-29
lines changed

explain/explain.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -441,39 +441,17 @@ def tool_reverse_finish(self, target_fn: str) -> None:
441441
orig_frame.select()
442442
raise
443443

444-
@report
445-
@source_context
446-
@revert_time_on_failure
447-
@chain_of_thought
448-
def tool_reverse_step_into_current_line(self, target_fn: str) -> str:
444+
def _reverse_into_target_function(self, target_fn: str) -> str:
449445
"""
450-
Reverse into a function call on the current line of the program.
446+
Reverse from the current line into the previous call of the target function in this thread.
451447
452-
The current line must contain a function call.
448+
This is to be used in the implementation of other tools that need to step into a function.
453449
454450
Params:
455-
target_fn: the function you want to step into
456-
"""
457-
# LLMs prefer to step backwards into a function on the current line,
458-
# rather than reverse up to that line and then step in.
459-
#
460-
# Also, it's possible that there are multiple functions to step into on
461-
# a given line (either because the calls are nested or because there
462-
# are multiple in sequence).
463-
#
464-
# To handle these cases, we ask the LLM what function it wants, then:
465-
# * Step forward past the current line.
466-
# * Set a breakpoint on the start of the target function.
467-
# * Run back to it.
468-
# * Use "finish" to get out (grabbing the return value as we go).
469-
# * Use "reverse-step" to get back into the end of the function.
470-
471-
# Step to next line.
472-
with gdbio.CollectOutput() as collector:
473-
self.udb.execution.next()
474-
if LOG_LEVEL == "DEBUG":
475-
print(f"reverse_step_into_current_line internal step to next line: {collector.output}")
451+
target_fn: the function to reverse into.
476452
453+
Returns: A string describing either the return value or the reason for an early stop.
454+
"""
477455
# Now try to step back into the correct function.
478456
with gdbutils.temporary_breakpoints(), gdbio.CollectOutput() as collector:
479457
# Create a breakpoint on the start of the target function.
@@ -550,10 +528,47 @@ def tool_reverse_step_into_current_line(self, target_fn: str) -> str:
550528
), "Unexpectedly reached the start of the target function."
551529

552530
if LOG_LEVEL == "DEBUG":
553-
print(f"reverse_step_into_current_line internal messages:\n{collector.output}")
531+
print(f"_reverse_into_target_function internal messages:\n{collector.output}")
554532

555533
return f"{target_fn} return value: {return_value}"
556534

535+
@report
536+
@source_context
537+
@revert_time_on_failure
538+
@chain_of_thought
539+
def tool_reverse_step_into_current_line(self, target_fn: str) -> str:
540+
"""
541+
Reverse into a function call on the current line of the program.
542+
543+
The current line must contain a function call.
544+
545+
Params:
546+
target_fn: the function you want to step into
547+
548+
Returns: A string describing either the return value or the reason for an early stop.
549+
"""
550+
# LLMs prefer to step backwards into a function on the current line,
551+
# rather than reverse up to that line and then step in.
552+
#
553+
# Also, it's possible that there are multiple functions to step into on
554+
# a given line (either because the calls are nested or because there
555+
# are multiple in sequence).
556+
#
557+
# To handle these cases, we ask the LLM what function it wants, then:
558+
# * Step forward past the current line.
559+
# * Set a breakpoint on the start of the target function.
560+
# * Run back to it.
561+
# * Use "finish" to get out (grabbing the return value as we go).
562+
# * Use "reverse-step" to get back into the end of the function.
563+
564+
# Step to next line.
565+
with gdbio.CollectOutput() as collector:
566+
self.udb.execution.next()
567+
if LOG_LEVEL == "DEBUG":
568+
print(f"reverse_step_into_current_line internal step to next line: {collector.output}")
569+
570+
return self._reverse_into_target_function(target_fn)
571+
557572
@report
558573
@chain_of_thought
559574
def tool_backtrace(self) -> str:

0 commit comments

Comments
 (0)