Improve agent interruption UX by allowing user to specify feedback or exit the program entirely.
This commit is contained in:
parent
35a1fb716f
commit
f7523e86d8
|
|
@ -1,5 +1,5 @@
|
||||||
from .__version__ import __version__
|
from .__version__ import __version__
|
||||||
from .console.formatting import print_stage_header, print_task_header, print_error
|
from .console.formatting import print_stage_header, print_task_header, print_error, print_interrupt
|
||||||
from .console.output import print_agent_output
|
from .console.output import print_agent_output
|
||||||
from .text.processing import truncate_output
|
from .text.processing import truncate_output
|
||||||
from .agent_utils import run_agent_with_retry
|
from .agent_utils import run_agent_with_retry
|
||||||
|
|
@ -10,6 +10,7 @@ __all__ = [
|
||||||
'print_agent_output',
|
'print_agent_output',
|
||||||
'truncate_output',
|
'truncate_output',
|
||||||
'print_error',
|
'print_error',
|
||||||
|
'print_interrupt',
|
||||||
'run_agent_with_retry',
|
'run_agent_with_retry',
|
||||||
'__version__'
|
'__version__'
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ import sys
|
||||||
import uuid
|
import uuid
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from ra_aid.console.formatting import print_interrupt
|
|
||||||
from langgraph.checkpoint.memory import MemorySaver
|
from langgraph.checkpoint.memory import MemorySaver
|
||||||
from langgraph.prebuilt import create_react_agent
|
from langgraph.prebuilt import create_react_agent
|
||||||
from ra_aid.env import validate_environment
|
from ra_aid.env import validate_environment
|
||||||
from ra_aid.tools.memory import _global_memory, get_related_files, get_memory_value
|
from ra_aid.tools.memory import _global_memory, get_related_files, get_memory_value
|
||||||
from ra_aid.tools.human import ask_human
|
from ra_aid.tools.human import ask_human
|
||||||
from ra_aid import print_stage_header, print_error
|
from ra_aid import print_stage_header, print_error, print_interrupt
|
||||||
|
from ra_aid.tools.agent import CANCELLED_BY_USER_REASON
|
||||||
|
from ra_aid.tools.human import ask_human
|
||||||
from ra_aid.agent_utils import (
|
from ra_aid.agent_utils import (
|
||||||
run_agent_with_retry,
|
run_agent_with_retry,
|
||||||
run_research_agent,
|
run_research_agent,
|
||||||
|
|
@ -227,7 +228,7 @@ def main():
|
||||||
)
|
)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print_interrupt("Operation cancelled by user")
|
print_interrupt(f"Operation cancelled: {CANCELLED_BY_USER_REASON}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import time
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from langgraph.prebuilt import create_react_agent
|
from langgraph.prebuilt import create_react_agent
|
||||||
from ra_aid.console.formatting import print_stage_header, print_error, print_interrupt
|
from ra_aid.console.formatting import print_stage_header, print_error
|
||||||
from ra_aid.console.output import print_agent_output
|
from ra_aid.console.output import print_agent_output
|
||||||
from ra_aid.tool_configs import (
|
from ra_aid.tool_configs import (
|
||||||
get_implementation_tools,
|
get_implementation_tools,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from .formatting import print_stage_header, print_task_header, print_error, console
|
from .formatting import print_stage_header, print_task_header, print_error, print_interrupt, console
|
||||||
from .output import print_agent_output
|
from .output import print_agent_output
|
||||||
|
|
||||||
__all__ = ['print_stage_header', 'print_task_header', 'print_agent_output', 'console', 'print_error']
|
__all__ = ['print_stage_header', 'print_task_header', 'print_agent_output', 'console', 'print_error', 'print_interrupt']
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,11 @@ def print_error(message: str) -> None:
|
||||||
console.print(Panel(Markdown(message), title="Error", border_style="red bold"))
|
console.print(Panel(Markdown(message), title="Error", border_style="red bold"))
|
||||||
|
|
||||||
def print_interrupt(message: str) -> None:
|
def print_interrupt(message: str) -> None:
|
||||||
"""Print an interruption message in a yellow-bordered panel with appropriate emoji.
|
"""Print an interrupt message in a yellow-bordered panel with stop emoji.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The interruption message to display (supports Markdown formatting)
|
message: The interrupt message to display (supports Markdown formatting)
|
||||||
"""
|
"""
|
||||||
print() # Give space for "^C"
|
print() # Add spacing for ^C
|
||||||
console.print(Panel(Markdown(message), title="Interrupted", border_style="yellow bold"))
|
console.print(Panel(Markdown(message), title="⛔ Interrupt", border_style="yellow bold"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ from typing_extensions import TypeAlias
|
||||||
ResearchResult = Dict[str, Union[str, bool, Dict[int, Any], List[Any], None]]
|
ResearchResult = Dict[str, Union[str, bool, Dict[int, Any], List[Any], None]]
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from ra_aid.tools.memory import _global_memory
|
from ra_aid.tools.memory import _global_memory
|
||||||
from ra_aid.console.formatting import print_error, print_interrupt
|
from ra_aid.console.formatting import print_error
|
||||||
from .memory import get_memory_value, get_related_files, get_work_log, reset_work_log
|
from .memory import get_memory_value, get_related_files, get_work_log, reset_work_log
|
||||||
|
from .human import ask_human
|
||||||
from ..llm import initialize_llm
|
from ..llm import initialize_llm
|
||||||
from ..console import print_task_header
|
from ..console import print_task_header
|
||||||
|
|
||||||
|
|
@ -61,9 +62,14 @@ def request_research(query: str) -> ResearchResult:
|
||||||
console_message=query
|
console_message=query
|
||||||
)
|
)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print_interrupt("Research interrupted by user")
|
try:
|
||||||
success = False
|
print()
|
||||||
reason = CANCELLED_BY_USER_REASON
|
response = ask_human.invoke({"question": "Why did you interrupt me?"})
|
||||||
|
success = False
|
||||||
|
reason = response if response.strip() else CANCELLED_BY_USER_REASON
|
||||||
|
except Exception:
|
||||||
|
success = False
|
||||||
|
reason = CANCELLED_BY_USER_REASON
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_error(f"Error during research: {str(e)}")
|
print_error(f"Error during research: {str(e)}")
|
||||||
success = False
|
success = False
|
||||||
|
|
@ -118,9 +124,14 @@ def request_research_and_implementation(query: str) -> Dict[str, Any]:
|
||||||
success = True
|
success = True
|
||||||
reason = None
|
reason = None
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print_interrupt("Task interrupted by user")
|
try:
|
||||||
success = False
|
print()
|
||||||
reason = CANCELLED_BY_USER_REASON
|
response = ask_human.invoke({"question": "Why did you interrupt me?"})
|
||||||
|
success = False
|
||||||
|
reason = response if response.strip() else CANCELLED_BY_USER_REASON
|
||||||
|
except Exception:
|
||||||
|
success = False
|
||||||
|
reason = CANCELLED_BY_USER_REASON
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
console.print(f"\n[red]Error during research: {str(e)}[/red]")
|
console.print(f"\n[red]Error during research: {str(e)}[/red]")
|
||||||
success = False
|
success = False
|
||||||
|
|
@ -184,9 +195,14 @@ def request_task_implementation(task_spec: str) -> Dict[str, Any]:
|
||||||
success = True
|
success = True
|
||||||
reason = None
|
reason = None
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print_interrupt("Task implementation interrupted by user")
|
try:
|
||||||
success = False
|
print()
|
||||||
reason = CANCELLED_BY_USER_REASON
|
response = ask_human.invoke({"question": "Why did you interrupt me?"})
|
||||||
|
success = False
|
||||||
|
reason = response if response.strip() else CANCELLED_BY_USER_REASON
|
||||||
|
except Exception:
|
||||||
|
success = False
|
||||||
|
reason = CANCELLED_BY_USER_REASON
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_error(f"Error during task implementation: {str(e)}")
|
print_error(f"Error during task implementation: {str(e)}")
|
||||||
success = False
|
success = False
|
||||||
|
|
@ -240,9 +256,14 @@ def request_implementation(task_spec: str) -> Dict[str, Any]:
|
||||||
success = True
|
success = True
|
||||||
reason = None
|
reason = None
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print_interrupt("Planning interrupted by user")
|
try:
|
||||||
success = False
|
print()
|
||||||
reason = CANCELLED_BY_USER_REASON
|
response = ask_human.invoke({"question": "Why did you interrupt me?"})
|
||||||
|
success = False
|
||||||
|
reason = response if response.strip() else CANCELLED_BY_USER_REASON
|
||||||
|
except Exception:
|
||||||
|
success = False
|
||||||
|
reason = CANCELLED_BY_USER_REASON
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_error(f"Error during planning: {str(e)}")
|
print_error(f"Error during planning: {str(e)}")
|
||||||
success = False
|
success = False
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue