88 Message as LiteLLMMessage ,
99 ModelResponse ,
1010)
11- from pydantic import Field , ValidationError
11+ from pydantic import ValidationError
1212
1313from openhands .core .context import EnvContext , PromptManager
1414from openhands .core .conversation import ConversationCallbackType , ConversationState
1515from openhands .core .llm import LLM , Message , TextContent , get_llm_metadata
1616from openhands .core .logger import get_logger
17- from openhands .core .tool import ActionBase , ObservationBase , Tool , ToolAnnotations
17+ from openhands .core .tool import BUILT_IN_TOOLS , ActionBase , FinishTool , ObservationBase , Tool
1818
1919from ..base import AgentBase
2020
2121
2222logger = get_logger (__name__ )
2323
24- """Finish tool implementation."""
25-
26-
27- class FinishAction (ActionBase ):
28- message : str = Field (description = "Final message to send to the user." )
29-
30-
31- TOOL_DESCRIPTION = """Signals the completion of the current task or conversation.
32-
33- Use this tool when:
34- - You have successfully completed the user's requested task
35- - You cannot proceed further due to technical limitations or missing information
36-
37- The message should include:
38- - A clear summary of actions taken and their results
39- - Any next steps for the user
40- - Explanation if you're unable to complete the task
41- - Any follow-up questions if more information is needed
42- """
43-
44-
45- FINISH_TOOL = Tool (
46- name = "finish" ,
47- input_schema = FinishAction ,
48- description = TOOL_DESCRIPTION ,
49- annotations = ToolAnnotations (
50- title = "finish" ,
51- readOnlyHint = True ,
52- destructiveHint = False ,
53- idempotentHint = True ,
54- openWorldHint = False ,
55- ),
56- )
5724
5825
5926class CodeActAgent (AgentBase ):
@@ -65,8 +32,9 @@ def __init__(
6532 system_prompt_filename : str = "system_prompt.j2" ,
6633 cli_mode : bool = True ,
6734 ) -> None :
68- assert FINISH_TOOL not in tools , "Finish tool is automatically included and should not be provided."
69- super ().__init__ (llm = llm , tools = tools + [FINISH_TOOL ], env_context = env_context )
35+ for tool in BUILT_IN_TOOLS :
36+ assert tool not in tools , f"{ tool } is automatically included and should not be provided."
37+ super ().__init__ (llm = llm , tools = tools + BUILT_IN_TOOLS , env_context = env_context )
7038 self .prompt_manager = PromptManager (
7139 prompt_dir = os .path .join (os .path .dirname (__file__ ), "prompts" ),
7240 system_prompt_filename = system_prompt_filename ,
@@ -169,12 +137,6 @@ def _handle_tool_call(
169137 state .history .messages .append (Message (role = "tool" , name = tool .name , tool_call_id = tool_call .id , content = [TextContent (text = err )]))
170138 return state
171139
172- # Early return for finish action (no need for tool execution)
173- if isinstance (action , FinishAction ):
174- assert tool .name == FINISH_TOOL .name , "FinishAction must be used with the finish tool"
175- state .agent_finished = True
176- return state
177-
178140 # Execute actions!
179141 if tool .executor is None :
180142 raise RuntimeError (f"Tool '{ tool .name } ' has no executor" )
@@ -188,4 +150,8 @@ def _handle_tool_call(
188150 state .history .messages .append (tool_msg )
189151 if on_event :
190152 on_event (observation )
153+
154+ # Set conversation state
155+ if tool .name == FinishTool .name :
156+ state .agent_finished = True
191157 return state
0 commit comments