Skip to content

Commit 14c0c76

Browse files
committed
include handling of keyboardInterrupt
1 parent 1689cd2 commit 14c0c76

File tree

3 files changed

+89
-80
lines changed

3 files changed

+89
-80
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "windows-use"
3-
version = "0.6.6.5"
3+
version = "0.6.6.7"
44
description = "An AI Agent that interacts with Windows OS at GUI level."
55
authors = [
66
{ name = "Jeomon George", email = "jeogeoalukka@gmail.com" }

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

windows_use/agent/service.py

Lines changed: 87 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)