@@ -45,81 +45,86 @@ def __init__(self,instructions:list[str]=[],browser:Browser=Browser.EDGE, llm: B
4545 self .desktop = Desktop ()
4646 self .console = Console ()
4747
48- def print_response (self ,query : str ):
49- response = self .invoke (query )
50- self .console .print (Markdown (response .content or response .error ))
51-
52-
5348 def invoke (self ,query : str )-> AgentResult :
54- with (self .desktop .auto_minimize () if self .auto_minimize else nullcontext ()):
55- desktop_state = self .desktop .get_state (use_vision = self .use_vision )
56- language = self .desktop .get_default_language ()
57- tools_prompt = self .registry .get_tools_prompt ()
58- observation = "The desktop is ready to operate."
59- system_prompt = Prompt .system_prompt (desktop = self .desktop ,
60- browser = self .browser ,language = language ,instructions = self .instructions ,
61- tools_prompt = tools_prompt ,max_steps = self .max_steps
62- )
63- human_prompt = Prompt .observation_prompt (query = query ,steps = 0 ,max_steps = self .max_steps ,
64- tool_result = ToolResult (is_success = True , content = observation ), desktop_state = desktop_state
65- )
66- agent_log = []
67- messages = [
68- SystemMessage (content = system_prompt ),
69- ImageMessage (content = human_prompt ,image = desktop_state .screenshot )
70- if self .use_vision and desktop_state .screenshot else
71- HumanMessage (content = human_prompt )
72- ]
73- for steps in range (1 ,self .max_steps ):
74- for consecutive_failures in range (self .max_consecutive_failures ):
75- try :
76- llm_response = self .llm .invoke (messages )
77- agent_data = extract_agent_data (llm_response )
78- break
79- except Exception as e :
80- logger .error (f"[LLM]: { e } . Retrying attempt { consecutive_failures + 1 } ..." )
81- if consecutive_failures == self .max_consecutive_failures - 1 :
82- return AgentResult (is_done = False , error = str (e ))
83-
84- logger .info (f"[Agent]🎯 Step: { steps } " )
85- logger .info (f"[Agent]📝 Evaluate: { agent_data .evaluate } " )
86- logger .info (f"[Agent]💭 Thought: { agent_data .thought } " )
87-
88- messages .pop () #Remove previous Desktop State Human Message
89- human_prompt = Prompt .previous_observation_prompt (steps = steps - 1 ,max_steps = self .max_steps ,observation = observation )
90- human_message = HumanMessage (content = human_prompt )
91- messages .append (human_message )
92-
93- ai_prompt = Prompt .action_prompt (agent_data = agent_data )
94- ai_message = AIMessage (content = ai_prompt )
95- messages .append (ai_message )
96-
97- action = agent_data .action
98- action_name = action .name
99- params = action .params
100-
101- if action_name .startswith ('Done' ):
102- action_response = self .registry .execute (tool_name = action_name , desktop = None , ** params )
103- answer = action_response .content
104- logger .info (f"[Agent]📜 Final-Answer: { answer } \n " )
105- agent_data .observation = answer
106- agent_log .append (agent_data .model_dump_json ())
107- human_prompt = Prompt .answer_prompt (agent_data = agent_data ,tool_result = action_response )
108- break
109- else :
110- logger .info (f"[Tool]🔧 Action: { action_name } ({ ', ' .join (f'{ k } ={ v } ' for k , v in params .items ())} )" )
111- action_response = self .registry .execute (tool_name = action_name , desktop = self .desktop , ** params )
112- observation = action_response .content if action_response .is_success else action_response .error
113- logger .info (f"[Tool]📝 Observation: { observation } \n " )
114- agent_data .observation = observation
115- agent_log .append (agent_data .model_dump_json ())
116-
117- desktop_state = self .desktop .get_state (use_vision = self .use_vision )
118- human_prompt = Prompt .observation_prompt (query = query ,steps = steps ,max_steps = self .max_steps ,
119- tool_result = action_response ,desktop_state = desktop_state
120- )
121- human_message = ImageMessage (content = human_prompt ,image = desktop_state .screenshot ) if self .use_vision and desktop_state .screenshot else HumanMessage (content = human_prompt )
49+ try :
50+ with (self .desktop .auto_minimize () if self .auto_minimize else nullcontext ()):
51+ desktop_state = self .desktop .get_state (use_vision = self .use_vision )
52+ language = self .desktop .get_default_language ()
53+ tools_prompt = self .registry .get_tools_prompt ()
54+ observation = "The desktop is ready to operate."
55+ system_prompt = Prompt .system_prompt (desktop = self .desktop ,
56+ browser = self .browser ,language = language ,instructions = self .instructions ,
57+ tools_prompt = tools_prompt ,max_steps = self .max_steps
58+ )
59+ human_prompt = Prompt .observation_prompt (query = query ,steps = 0 ,max_steps = self .max_steps ,
60+ tool_result = ToolResult (is_success = True , content = observation ), desktop_state = desktop_state
61+ )
62+ agent_log = []
63+ messages = [
64+ SystemMessage (content = system_prompt ),
65+ ImageMessage (content = human_prompt ,image = desktop_state .screenshot )
66+ if self .use_vision and desktop_state .screenshot else
67+ HumanMessage (content = human_prompt )
68+ ]
69+ for steps in range (1 ,self .max_steps ):
70+ for consecutive_failures in range (self .max_consecutive_failures ):
71+ try :
72+ llm_response = self .llm .invoke (messages )
73+ agent_data = extract_agent_data (llm_response )
74+ break
75+ except Exception as e :
76+ logger .error (f"[LLM]: { e } . Retrying attempt { consecutive_failures + 1 } ..." )
77+ if consecutive_failures == self .max_consecutive_failures - 1 :
78+ self .telemetry .capture (AgentTelemetryEvent (
79+ query = query ,
80+ answer = '' ,
81+ error = str (e ),
82+ use_vision = self .use_vision ,
83+ model = self .llm .model_name ,
84+ provider = self .llm .provider ,
85+ agent_log = agent_log
86+ ))
87+ return AgentResult (is_done = False , error = str (e ))
88+
89+ logger .info (f"[Agent] 🎯 Step: { steps } " )
90+ logger .info (f"[Agent] 📝 Evaluate: { agent_data .evaluate } " )
91+ logger .info (f"[Agent] 💭 Thought: { agent_data .thought } " )
92+
93+ messages .pop () #Remove previous Desktop State Human Message
94+ human_prompt = Prompt .previous_observation_prompt (steps = steps - 1 ,max_steps = self .max_steps ,observation = observation )
95+ human_message = HumanMessage (content = human_prompt )
12296 messages .append (human_message )
97+
98+ ai_prompt = Prompt .action_prompt (agent_data = agent_data )
99+ ai_message = AIMessage (content = ai_prompt )
100+ messages .append (ai_message )
101+
102+ action = agent_data .action
103+ action_name = action .name
104+ params = action .params
105+
106+ if action_name .startswith ('Done' ):
107+ action_response = self .registry .execute (tool_name = action_name , desktop = None , ** params )
108+ answer = action_response .content
109+ logger .info (f"[Agent] 📜 Final-Answer: { answer } \n " )
110+ agent_data .observation = answer
111+ agent_log .append (agent_data .model_dump_json ())
112+ human_prompt = Prompt .answer_prompt (agent_data = agent_data ,tool_result = action_response )
113+ break
114+ else :
115+ logger .info (f"[Tool] 🔧 Action: { action_name } ({ ', ' .join (f'{ k } ={ v } ' for k , v in params .items ())} )" )
116+ action_response = self .registry .execute (tool_name = action_name , desktop = self .desktop , ** params )
117+ observation = action_response .content if action_response .is_success else action_response .error
118+ logger .info (f"[Tool] 📝 Observation: { observation } \n " )
119+ agent_data .observation = observation
120+ agent_log .append (agent_data .model_dump_json ())
121+
122+ desktop_state = self .desktop .get_state (use_vision = self .use_vision )
123+ human_prompt = Prompt .observation_prompt (query = query ,steps = steps ,max_steps = self .max_steps ,
124+ tool_result = action_response ,desktop_state = desktop_state
125+ )
126+ human_message = ImageMessage (content = human_prompt ,image = desktop_state .screenshot ) if self .use_vision and desktop_state .screenshot else HumanMessage (content = human_prompt )
127+ messages .append (human_message )
123128
124129 self .telemetry .capture (AgentTelemetryEvent (
125130 query = query ,
@@ -130,11 +135,15 @@ def invoke(self,query: str)->AgentResult:
130135 provider = self .llm .provider ,
131136 agent_log = agent_log
132137 ))
133-
134- return AgentResult (is_done = True ,content = answer )
135-
136-
137-
138+ return AgentResult (is_done = True ,content = answer )
139+ except KeyboardInterrupt :
140+ logger .warning ("[Agent] ⚠️ Interrupted by user (Ctrl+C). Flushing telemetry before exit..." )
141+ self .telemetry .flush ()
142+ return AgentResult (is_done = False , error = "Interrupted by user" )
143+
144+ def print_response (self ,query : str ):
145+ response = self .invoke (query )
146+ self .console .print (Markdown (response .content or response .error ))
138147
139148
140149
0 commit comments